This document presents the concepts related to the tutorial Developing Java Applications: A Tutorial .
If you are an Objective-C programmer who is familiar with the Yellow Box development environment and the Yellow Box APIs, you're probably interested only in the differences in the development procedure between Objective-C and Java:
Object myTextField;public void doThis(Object sender)
NSTextField myTextField;public void doThis(NSButton sender)
If you don't specify the correct class type, you must cast to that type in the code.
With the Yellow Box development environment, you can create applications written in Java but built both from objects in the Yellow Box frameworks and from pure Java objects. These applications run on any Mac OS X or Yellow Box for Windows system.
There are four major parts to Yellow Box's Java feature for this release:
The Yellow Box development environment includes project types and tools for wrapping Objective-C code in Java interfaces. For more on Apple's bridging technology, see The Java Bridge .
The Yellow Box also helps you build and lets you run 100% Pure Java applets and applications. See Developing 100% Pure Java Applications for details.
The Java bridge is an Apple technology that lets Objective-C objects and Java objects communicate freely. With it developers can transparently instantiate Objective-C objects in Java code and treat them as if they were Java objects; for example, it allows Objective-C protocols to appear in the guise of Java interfaces. Conversely, it can expose any Java class or interface as an Objective-C class or protocol.
The core Yellow Box frameworks--the Application Kit and Foundation--have been "bridged" to Java. This means that developers can write Yellow Box applications using nothing but Java code.
The Java bridge offers the following features:
The Yellow Box development environment provides a set of tools and specifications that enable you to bridge your own Objective-C classes and protocols, exposing them as Java classes and interfaces. (And, if you wish, you can expose Java classes and interfaces as Objective-C classes and protocols.) The essential tool, bridget , reads and processes a "jobs" file --a file with an extension of .jobs (the letters of which stand for Java to Objective-C Bridging Specification). The jobs file is a text file that contains specifications mapping Objective-C classes, interfaces, and method selectors to Java classes, interfaces, and methods.
Other tools in the development environment facilitate the process of bridging frameworks. The general procedure for bridging is as follows:
You can use the Yellow Box development environment to develop 100% Pure Java applications: that is, applications developed exclusively with JavaSoft's Java Development Kit (JDK). Mac OS X includes the latest version of the JDK in
/System/Library/Frameworks/JavaVM. framework
.
To create an 100% Pure Java application with the Yellow Box development environment:
Project Builder supports syntax coloring and indentation for Java code. You can use all other Project Builder features that do not depend on project indexing.
The build process automatically invokes javac with the correct arguments and does whatever else is requred to build the project, such as creating the archive (a .zip file, by default). If there are Java coding errors, Project Builder reports them in its Build panel; you can navigate to the code containing an error by clicking the reporting line in the panel.
When you're ready to create and install the .zip package containing your Java classes, do the following:
The .zip package is created and installed.
You can use the Java interpreter ( java ) and the applet previewer ( appletviewer ) to run Java applications and applets, respectively. These tools are in /usr/bin .
To compile and run Java applicatons, the CLASSPATH environment variable must be correctly set. This variable is usually set for you by the installation script and by Project Builder. But if CLASSPATH becomes faulty, you can reset it with the setenv and javaconfig commands on the command line:
Project Builder presents the elements of a project in a project window.
When you create or open a project, after some seconds you may notice triangular "branch" buttons appearing after source code files in the browser. Project Builder has indexed these files.During indexing, Project Builder stores all symbols of the project (classes, methods, globals, and such) in virtual memory. This allows Project Builder to access project-wide information quickly. Indexing is indispensable to such features as name completion and Project Find. Usually indexing happens automatically when you create or open a project. You can turn off this option if you wish. Choose Preferences from the Edit menu and then choose the Indexing display. Turn off the "Index when project is opened" checkbox.You can also index a project at any time by choosing Tools>Indexer>Index Project. If you want to do without indexing (maybe you have memory constraints), choose Tools>Indexer>Purge Indices.
Every application has at least one nib file. The main nib file contains the application menu and often a window and other objects. An application can have other nib files as well. Each nib file contains the following information:
Archived objects . Encoded information on Yellow Box objects, including their size, location, and position in the object hierarchy (for view objects, determined by superview/subview relationship). At the top of the hierarchy of archived objects is the File's Owner object, a proxy object that points to the actual object that owns the nib file.
Custom class information . Interface Builder can store the details of Yellow Box objects and objects that you palettize (static palettes), but it does not know how to archive instances of your custom classes since it doesn't have access to the code. For these classes, Interface Builder stores a proxy object to which it attaches class information.
Connection information . Information about how objects within the object hierarchy are interconnected. Connector objects special to Interface Builder store this information. When you save the document, connector objects are archived in the nib file along with the objects they connect.
Images and sounds . Image files and sound files that you drag and drop over the nib file window or over an object that can accept them (such as a button or image view).
In your code, you can load a nib file by sending the NSBundle class
loadNibNamed:owner:
or
loadNibFile:externalNameTable:withZone:
messages. When you do this, the runtime system does the following: It unarchives the objects from the object hierarchy, sending each object an
initWithCoder:
message after allocating memory for it.
awakeFromNib
to all objects that were derived from information in the nib file, signalling that the loading process is complete.When the Yellow Box establishes connections during the course of loading a nib file, it sets the values of the source object's outlets. It first tries to set an outlet through the "set" accessor method if the source object implements it. For example, if the source object has an outlet named "contraption," the system first sees if that object responds to "setContraption" and, if it does, it invokes the accessor method. If the source object doesn't implement the accessor method, the system sets the outlet directly.
Problems naturally ensue if a "set" accessor method does something other than directly set the outlet. One common example is an accessor method that sets the string value of an outlet referring to a text field (
setStringValue
). After loading, the value of the outlet is null because the "set" accessor method did not directly assign the value.
When you open a nib file, Interface Builder opens several windows: the nib file window, a menu bar panel, a palette window, and an empty window in which you can put elements of a graphical user interface. The nib file window gives access to the objects, class definitions, and resources of a nib file. The menu panel allows you to constuct your application menus. And the palette window holds various objects of the Application Kit and any custom objects that you or third parties palettize. To show a palette, click on the of the icons that runs across the top of the window.
Not shown in The Standard Windows of Interface Builder is Interface Builder's Inspector (Tools>Inspector), which lets you set attributes and the size of objects, specify objects to be connected, identify help files, and set many other variables.
Just inside each window's content area--the area enclosed by the title
bar and the other three sides of the frame--is the "content view." The content view is the root (or top) NSView in a window's view hierarchy. Conceptually like a tree, one or more NSViews may branch from the content view, one or more other NSViews may branch from these subordinate NSViews, and so on. Except for the content view, each NSView has one (and only one) NSView above it in the hierarchy. An NSView's subordinate views are called its subviews; its superior view is known as the superview.
On the screen, enclosure determines the relationship between superview and subview: a superview encloses its subviews. This relationship has several implications for drawing:
The view hierarchy also affects how events are handled, particularly through the first-responder mechanism.
A View Hierarchy shows how NSApplication, NSWindow, and NSView objects are connected through their instance variables.
Each NSWindow in an application keeps track of the object in its view hierarchy that has "first responder" status. The first responder is the NSView that currently is the focus of keyboard events in the window. By default, an NSWindow is its own first responder, but any NSView within the window can become first responder when the user clicks it with the mouse.
You can also set the first responder programmatically with the NSWindow's
makeFirstResponder
method. Moreover, the first-responder object can be a target of an action message sent by an NSControl, such as a button or a matrix. Programmatically, you do this by sending
setTarget
to the NSControl (or its cell) with an argument of
nil
. You can do the same thing in Interface Builder by making a target/action connection between the NSControl and the First Responder icon in the Instances display of the nib file window.
All NSViews of an application, as well as all NSWindows and the application object itself, inherit from NSResponder, which defines the default message-handling behavior: events are passed up the responder chain. Many Application Kit objects, of course, override this behavior, so events are passed up the chain until they reach an object that does respond.
The series of next responders in the responder chain is determined by the interrelationships between the application's NSView, NSWindow, and NSApplication objects). For an NSView, the next responder is usually its superview; the content view's next responder is the NSWindow. From there, the event is passed to the NSApplication object.
For action messages sent to the first responder, the trail back through possible respondents is even more detailed. The messages are first passed up the responder chain to the NSWindow and then to the NSWindow's delegate. Then, if the previous sequence occurred in the key window, the same path is followed for the main window. Then the NSApplication object tries to respond, and failing that, it goes to NSApp's delegate.
Interface Builder allows you to view and specify connections between a control object and its target in the Connections display of the control's inspector. The relation of target and action in this Inspector might not be apparent. First, target is an outlet of a cell object that identifies the recipient of an action message. So what is a cell object and what does it have to do with a button?
One or more cell objects are always associated with a control object (that is, an object inheriting from NSControl, such as a button). Control objects "drive" the invocation of action methods, but they get the target and action from a cell. This way one control object, such as an NSMatrix, can have different targets and actions for each of its cells, as well as its own target and action. NSActionCell defines the target and action outlets, and most kinds of cells in the Application Kit inherit these outlets.
When a user clicks a button, the button gets the target and action information from its cell. The action is a selector indicating the method to invoke in the target object. The button sends the approriate message to its target, which is typically an instance of a custom class.
The Actions column of the Connections display shows the action methods defined by the class of the target object and known by Interface Builder. Interface Builder identifies action methods because their declarations follow the syntax:
- (IBAction)doThis:(id)sender;
The return argument can also be
void
instead of
IBAction
, but the argument is always
sender
.
A common and useful paradigm for object-oriented applications, particularly business applications, is Model-View-Controller (MVC). Derived from Smalltalk-80, MVC proposes three types of objects in an application, separated by abstract boundaries and communicating with each other across those boundaries.
Model object . This type of object represents special knowledge and expertise. Model objects hold a company's data and define the logic that manipulates that data. For example, a Customer object, common in business applications, is a Model object. It holds data describing the salient facts of a customer and has access to algorithms that access and calculate new data from those facts. A more specialized Model class might be one in a meteorological system called Front; objects of this class would contain the data and intelligence to represent weather fronts. Model objects are not directly displayed. They often are reusable, distributed, persistent, and portable to a variety of platforms.
View object . A View object in the paradigm represents something visible on the user interface (a window, for example, or a button). A View object is "ignorant" of the data it displays. The Application Kit usually provides all the View objects you need: windows, text fields, scroll views, buttons, browsers, and so on. But you might want to create your own View objects to show or represent your data in a novel way (for example, a graph view). You can also group View objects within a window in novel ways specific to an application. View objects, especially those in kits, tend to be very reusable and so provide consistency between applications.
Controller object . Acting as a mediator between Model objects and View objects in an application is a Controller object. There is usually one per application or window. A Controller object communicates data back and forth between the Model objects and the View objects. It also performs all the application-specific chores, such as loading nib files and acting as window and application delegate. Since what a Controller does is very specific to an application, it is generally not reusable even though it often comprises much of an application's code. (This last statement does not mean, however, that Controller objects cannot be reused; with a good design, they can.)
Because of the Controller's central, mediating role, Model objects need not know about the state and events of the user interface, and View objects need not know about the programmatic interfaces of the Model objects. You can make your View and Model objects available to others from a palette in Interface Builder.
Hybrid models . MVC, strictly observed, is not advisable in all circumstances. Sometimes it's best to combine roles. For instance, in a graphics-intensive application, such as an arcade game, you might have several View objects that merge the roles of View and Model. In some applications, especially simple ones, you can combine the roles of Controller and Model; these objects join the special data structures and logic of Model objects with the Controller's hooks to the interface.
The Project Build panel has buttons that do the following:
It also shows the results of the build and takes you to the site of any error in the code when you click the line in the Project Build panel reporting the error.