|
Last modified: 4 November 1996. |
Article complete: approx 3000 words
Referenced pages: sidebars/figures in article.
Text in <CODE> tags are class names, while those in <TT> tags are methods.
Netscape's Internet Foundation Classes (IFC) aim to provide a base Java API, improving Sun's core Java Development Kit (JDK) classes. In particular most people have found the JDK Advanced Window Toolkit (AWT) insufficient for their needs. Netscape bill their current offering as GUI IFC, with other IFCs to come, some Netscape specific. So this IFC mainly improves the window classes. However it has several other rivals, including Sun's own Java Workshop Visual classes.
This review covers the "Barium" release of October 15 1996. This made substantial changes from the previous "Cesium" release. However Netscape claim that there should be no major alterations before the final release (by the end of the year, and definitely with Navigator 4.0). In addition to class changes, the Barium release has better documentation and a few examples.
Netscape is in a good position to ensure that its own classes, including IFC, become de facto standards as they will be included with its browsers. IFC is written completely in Java and is therefore browser-independent. However, the big question is whether other browsers will include these classes as standard. The complete classes are over 500kB; no one will want to download these on-line. Somewhat limply, Netscape suggest that users will be able to get the IFC classes on a floppy from a friend. If you cannot guarantee that Microsoft's Internet Explorer, for example, has bundled these classes then it may be difficult to justify basing a project on this technology. Perhaps Netscape et al can agree to having each other's classes in their browsers. Obviously for intranet applications, you can ensure that IFC is available locally.
Naming ConventionsThe IFC naming convention seems intent on confusing us. Breaking with tradition, the paint() routine is now replaced with draw() and drawView(), gotFocus() becomes resumeFocus(), etc. Even an applet getParameter() becomes parameterNamed(). In some cases IFC does follow previous naming conventions, eg it has its own
One method called stringWithoutCarriageReturns() in fact replaces CR+LF with just CR! While resisting the temptation to name the classes eponymously, ie NFC, having "Internet" in the title does not quite seem appropriate either. IFC is described by Netscape as providing a series of frameworks. I think that 'function areas' or similar would be a more appropriate term. |
You can get the full 900kB IFC development kit on-line at http://developer.netscape.com/library/ifc/. This is now public, so you do not need to be a member of Netscape's DevEdge program.
Download the appropriate file and expand it to get the barium directory structure. You will need to set your CLASSPATH environment variable, eg add "d:\barium\classes" or similar. I needed to reboot NT to get this recognised. You will probably want to set up bookmark links to the developer guide and the class reference.
There are five examples to try out, the cutest being the aquarium, see figure 1. You can drag the aquarium supplies into the tank: then the fish swim, the bubbles bubble and the foliage waves.
As well as installation instructions and release notes, the IFC development toolkit comes with two sets of web page documentation: a developers guide and the class reference. Further resources are available on-line, including a quiescent newsgroup and a few more examples.
The developers guide is reasonably comprehensive and comprehensible, an improvement over the Cesium release. However you have to firtle around the classes to discover all IFC's capabilities.
The supplied toolkit comes with the familiar class reference. However it is generated by (Netscape's?) netdoc, not the usual javadoc. There are the usual "Index of all Fields and Methods", "Class Hierarchy" and package pages. The individual class pages start with the actual Java code for the class's public definition, rather than a pretty listing, but continue more or less as normal.
There are numerous links in the class reference pages which do not connect.
Most of these refer to the JDK, with a few IFC inconsistencies which are
probably classes used internally, eg HTMLParser
must be used by
TextView
. This gives the appearance of being slightly sloppy.
This table gives an overview of the areas of functionality provided by IFC
Framework | Description |
---|---|
Drawing/event framework | The basic framework for directing events to interface objects and allowing those objects to draw to the screen. |
Fundamental application controls | Basic GUI application controls, such as buttons, sliders, and text fields. |
Composite controls | More complex interface controls, such as the ColorChooser and FontChooser. |
Multi-font text object | An object that can display multi-font text as well as embedded images. |
Windowing framework | Support for a traditional windowing environment within a Java application, as well as placing IFC components within "native" windows. |
Animation framework | Support for animation, including buffered drawing and transparency. |
Drag-and-drop framework | Support for dragging and dropping items within an application. |
Timers framework | Support for concurrent behaviour without the need to spawn threads. |
Object persistence framework | Support for enabling objects to save their essential state, allowing them to be reconstituted at a later time. |
Localization framework | Support for multiple localized versions of application resources. |
There are two main packages: netscape_beta.util
and netscape_beta.application
.
I presume that these names will lose their "_beta" in the fullness of
time.
IFC can be used in both web applets and stand alone applications.
Most of IFC is in the application
package which in effect
extends java.applet
and java.awt
. The View
class is the basis of much of the package. These user interface components are
supplied: Button
, CheckBox
, ColorWell
,
ContainerView
, ListView
, PopUp
,
RadioButton
, ScrollBar
, Slider
,
TextField
, TextView
and two types of window. The
three composite components are ColorChooser
, FontChooser
and FileChooser
.
The display and event objects are based on the abstract View
class. I must say straight away that IFC does not have a document/view
architecture, although I am sure that you could build a companion document class
should you wish. No, a view represents a rectangular area on the screen which
can receive events.
A Window
is in fact just an interface, which is implemented by
the two possible window types, InternalWindow
or ExternalWindow
,
both of which are derived from View
.
An InternalWindow
lives within the Java program area. It is
rectangular but may be transparent. There are several window styles, eg no
adornment through to title bars, resize handles, etc.
IFC maintains a view hierarchy (z-order) of views and sub-views, all
originating from the RootView
, eg the area that your applet is
given. So, a display order of internal windows is maintained. In addition, you
can specify which "layer number" a window is in, either DEFAULT_LAYER,
PALETTE_LAYER, POPUP_LAYER and DRAG_LAYER. So, a floating palette would have a
higher layer number than document windows so that it always appears on top of
them.
ExternalWindow
s are outside the Java application (but
controlled by it) and look like windows created by the native operating system.
External windows can contain views by creating their own RootView
.
An applet with one external window contains two root views and, therefore, two
view hierarchies.
Views support resizing nicely. You can decide whether the view's width
should stay the same when resized, or - if fixed - which margin should move. It
is easy to make any components or group of components scrollable using
ScrollGroup
.
A set of standard basic and composite components are available.
A view's drawView() paints the view. Normally you call draw() which calls drawView() and then paints any sub-views.
IFC sticks with just having an image model based on pixels. There are none of the other image modes that Win32 has, for example.
Unlike some AWT programming, you have to set up your Graphics
context each time you use it, eg set the font in drawView().
You can override the methods used to draw standard components. Eg, you
could override Button
drawViewTitleInRect() just to
alter how the button text is displayed. You could have a oval button by making
the view transparent and only drawing the oval in drawViewInterior().
You can ensure that painting is flicker free by asking the view to use its
built-in support for drawing via an off-screen buffer.
The abstract Border
class is used by other components to draw
their surrounds. Five borders are provided as standard, though you may roll
your own by implementing or overriding the five primitive border methods.
Every IFC application has a main thread that receives mouse and keyboard AWT events. Events are directed to the appropriate object in the view hierarchy.
There are some nice touches here. If your mouseDown() returns false then you do not receive the mouseDragged() or mouseUp() events. By default, mouse tracking events are coalesced so only the latest MOUSE_DRAGGED or MOUSE_MOVED event is sent, allowing a view to keep up with the user's actions.
Note carefully that - like AWT - there is no apparent paint event, although the underlying operating system will generate these. The core Java classes ensure that draw() is called appropriately.
If you want, you can ask for auto-scrolling events, eg where the user has dragged the mouse out of a component's window.
The Target
interface is implemented by IFC objects that wish
to receive commands. So, a button is assigned a target. When the button is
pressed it calls its target's
performCommand(). Unfortunately, the command passed is a string, ie
the button's name. Using strings as commands is not great, methinks. In the
interest of efficiency, an integer identifier would be better.
Netscape say that this interface will change to use class reflection, once JDK 1.1 is widely available. Reflection allows you to determine the (public) fields, methods and constructors of other classes. I presume this means that a command "Cut" will automatically invoke method OnCut().
Note that commands are not normally passed as events. However there is
CommandEvent
which will do just this.
For commands that might apply generally, eg Cut, the framework can identify
the current object, or the first one in the reverse view hierarchy, which can
handle it. Such objects must implement the ExtendedTarget
interface. There are 14 standard commands which you might want to implement, eg
ExtendedTarget.CUT. My brief attempt failed to get this to work with
TextField which is supposed to support CUT and PASTE.
So there is implicitly a clipboard available, but there is no documentation for it.
IFC makes it easier to have just one thread in your program if it only needs
to perform simple action regularly. You can use a Timer
which
calls the Target
performCommand() at your defined rate.
You can call an application's eventLoop() to get its EventLoop
class instance. Use this to add events to the event queue. Exceptions in your
code are caught in the event loop, and event processing continues.
For the TextField
class only, you can set the tab and back tab
order, ie the next or previous text field. Buttons, etc. may not be part of a
tab sequence.
So, the tab order is cumbersome to set up, and quite limited in its behaviour. It is important to give people the option of using the keyboard to select radio buttons, etc. The Return key was supposed to be equivalent to pressing Tab, but I found that this was not so.
I am afraid that the components, such as buttons, still look subtly naff. In the text components, Shift+left cursor, for example, does not select the previous character, and the Home and End do not work, which is poor. You can select character ranges with the mouse.
The TextView class can display images and text in various fonts and colours.
If you keep typing text into a text view, you would at least expect it to
scroll the latest text into view, and preferably sprout a vertical scroll bar.
But it does neither. Not all the view is cleared to the background colour if
you do a deletion. It was easy to get weird characters in the field, eg on
pressing the delete key in some circumstances. A text view can read HTML from a
URL, but its display is disastrous, so its implementation is obviously not
complete. HTML links are then supposed to be recognised, and their selection
notified to the
TextViewOwner
.
Implementing a text field (and especially a multi-font text area) is no easy job - I know, I have done something similar - but Netscape must do their stuff.
A TextField or a TextView can set a text filter to pre-process key events.
Drag and drop is supported within a Java application. Drag source
classes must implement the DragSource
interface and destinations
DragDestination
. The source's mouseDragged() method
should create an instance of DragSession
to show the moving image.
One of the examples had a resizable internal window. This did not show a resize cursor when positioned on the edge of the window.
There is no support for the likes of toolbars and tooltips.
IFC provides two layout managers, GridLayout
and PackLayout
.
There is still no support for printing.
The abstract DrawingSequence
class is used by views to display
animations. Its drawInRect() method is called with a frame number,
every frame rate seconds. The derived class ImageSequence
displays a list of images that you have given it, with different sequences if
the mouse is within its area or if it has been clicked. The aquarium example
uses a drawing sequence to make its fish swim, etc. The DrawSequenceOwner
interface can be used to notify when an image frame has changed.
Only a few IFC classes have Clone() methods.
Netscape IFC engineers use their own Constructor GUI tool internally as a testbed. They may not release it, although IDE vendors will probably produce something similar.
The documentation hints at a resource format, but there is no evidence of either yet. There was no evidence of the claimed localisation framework for application resources.
The util
package includes the Archiver
, improved
versions of Vector
and HashTable
as well as other
new utility classes such as Sort
.
The Archiver
can store object graphs, ie a root object and all
the other objects that it relies upon. To be archived an object must support
the Codable
interface, and must have a constructor with no
arguments. The version of classes is stored. An archive does not have to be
read serially, so it could be viewed as a simple database. The ClassInfo
and ClassTable
classes are used internally by the archiver to
store objects on any output stream.
Most IFC classes seem to be archivable. I am not sure if Netscape intend to use their archive as a resource format for laying out windows.
Note that JDK 1.1 supports "lightweight" object persistence. By
default, this saves all non-transient and non-static fields in a class to an
ObjectOutputStream
. You can override this process by providing
your own writeObject() and readObject() methods. For some
programs this automatic object persistence mechanism may be simpler to use than
IFC.
Figure 2 is screen shot of the PushMe IFC example. The slider has just been moved half way along, making the GrayView box half way between black and white.
The main entry point for an IFC applet must be this code in
NetscapeApplet.class. This allows IFC to start up first and then call your main
class, as specified by the ApplicationClass applet
parameter. NetscapeApplet
is there to provide the classForName()
method; if IFC is installed as system classes then having this function inside
FoundationApplet
would mean that the user classes would not be
found.
import netscape_beta.application.*; import netscape_beta.util.*; public class NetscapeApplet extends FoundationApplet { public Class classForName(String className) throws ClassNotFoundException { return Class.forName(className); } }
The HTML to call the applet should be
<APPLET CODE="NetscapeApplet" WIDTH=320 HEIGHT=200> <PARAM NAME="ApplicationClass" VALUE="PushMe"> </APPLET>
The rest of the example is in the code files GrayView.java and PushMe.java.
The main PushMe
class has to extend Application
,
and, as usual, implements Target
so that it can perform commands.
As with most Java programs there is no message loop to get right.
PushMe.init() initialises the application by setting up the view
hierarchy, ie the root view has a write-only status text field, a button, a
slider, an editable text field and a custom GrayView
. Each
component has its target set to be PushMe
so PushMe.performCommand()
is called to dispatch any commands. As I mentioned before, performCommand()
has to compare each command string laboriously. If commands were integers, then
a nice familiar switch statement could be used.
PushMe.main() is there to allow PushMe to run as a stand alone
application as well as an applet. In this case, it creates a new instance of
PushMe
and a new ExternalWindow
. The root view is
made, sized and shown. Finally IFC's Application.run() is called.
GrayView
straightforwardly fills its rectangle with a gray
colour. It does not generate commands.
While IFC definitely has improvements over the raw JDK, it does not quite go far enough. The supplied user interface components need work. I would like to see a window manager defined to give a standard look and feel to a Java application. Yes, make it so that you can change the window manager. A internationalisable resource format might be in order. A document/view architecture that allowed file storage on a server would be nice.
Although not the perfect solution, if I knew for certain that a tidied-up IFC would be available on most browsers, then I would use these classes as a base to build on. Will Netscape be able to pick up support for IFC from the development tool suppliers? Apparently Symantec has already opted to bundle IFC.
I had hoped that IFC would have been good enough to become de rigueur. Although I am not totally convinced, perhaps Netscape has the clout to ensure that it becomes de facto, especially if all my moans here are tidied up for the final release.
© 1996 Chris Cant, PHD Computer Consultants Ltd
Chris Cant runs PHD Computer Consultants Ltd at http://www.phdcc.com/ where various Java applets are on show.