PHD Computer Consultants Ltd
... Netscape IFC article
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

Introduction

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 Conventions

The 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 Graphics class, netscape_beta.application.Graphics. So you have to remember that you are using IFC graphics, not java.awt.Graphics.

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.

Getting started

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.

Aquarium screen shot

Documentation

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.

Overview

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.

View Hierarchy

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.

ExternalWindows 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.

Drawing

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.

Events and Targets

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.

Look and Feel

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.

Other points

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.

Utilities

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.

Sample Application

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.

PushMe screenshot

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.

Conclusion

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.

Author

© 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.


PHD Home page.