4.5 Other AWT Improvements
In addition to the major change in the AWT event model, there have been quite a few other improvements to the AWT. These improvements are summarized in the sections below.
Printing in Java 1.1 is implemented through the new PrintJob class and PrintGraphics interface. The PrintJob class represents a print request. When a PrintJob object is created, the user is prompted with a platform-dependent print dialog, which allows her to specify options such as which printer to use.
The getGraphics() method of a PrintJob object returns a Graphics object that can be used for printing. This object is an instance of a subclass of Graphics that knows how to print in a platform-dependent way. The object also implements the PrintGraphics interface. To print a component, you simply pass this Graphics object to the component's print() method. If the component does not define this method, the default implementation simply invokes the paint() method, which usually does the right thing. When you want to print a component and all of its subcomponents, you can simply pass the Graphics object to the printAll() method of the component.
Printing multiple pages is more complex, of course. The application is responsible for pagination of the output, and in order to draw the output on the page the application may also need to query the PrintJob object to determine the page size (in pixels) and page resolution (in pixels per inch).
For security reasons, applets are not allowed to initiate print jobs; if they were, you could expect to see applets on the Net that automatically printed hardcopy advertisements to your printer! Note, however, that this does not mean that applets cannot print themselves when the browser or applet viewer initiates the print request object and invokes the printAll() method of the applet.
Chapter 8, New AWT Features contains an example that uses the printing capabilities of Java 1.1.
Data transfer via the cut-and-paste metaphor is supported in Java 1.1 by the classes and interfaces in the java.awt.datatransfer package. One half of this package provides generic data-transfer functionality, and the other half provides the classes and interfaces needed for clipboard-based cut-and-paste. In future versions of the JDK, we can expect to see support for the drag-and-drop data transfer metaphor added to this package.
For the purposes of data transfer, the DataFlavor class represents the notion of a data type or data format. A DataFlavor consists of a human-readable name for the flavor and one of two possible machine-readable format definitions. The first of the machine-readable descriptions is a String that specifies a MIME type for the transferred data. The second is a Class object that represents a Java class. When a DataFlavor is specified with a Class object, it is an instance of this class that is passed when data transfer actually occurs.
Any value that can be transferred through the Java 1.1 data transfer mechanism must be represented by a class that implements the Transferable interface. This interface defines methods to query the data flavors that the class supports, and it defines a method that the data transfer mechanism calls to convert the transferable value into the appropriate form for a given DataFlavor.
While the DataFlavor class and the Transferable interface define the fundamental data transfer mechanism, they, by themselves, are not enough to initiate or perform data transfer. For this purpose, java.awt.datatransfer also defines the Clipboard class and the ClipboardOwner interface. Together, they support a cut-and-paste metaphor for data transfer. Because strings are often transferred between applications, java.awt.datatransfer provides the StringSelection class. This class implements both the Transferable and the ClipboardOwner interfaces and makes it very easy to transfer textual data through cut-and-paste.
Inter-application data transfer is performed through the system clipboard. It is also possible to perform intra-application transfers through a private clipboard that an application creates for itself. Note that untrusted applets are not allowed to access the system clipboard--there could be sensitive information contained on it that untrusted code should not have access to. This means that applets cannot participate in inter-application cut-and-paste. Chapter 8, New AWT Features provides an example that demonstrates intra-application cut-and-paste data transfer.
Popup Menus and Menu Shortcuts
Java 1.1 adds support for popup menus to the AWT. The PopupMenu class is a subclass of Menu; menu items are added to it just as they are added to regular pulldown menus. A popup menu can be attached to an arbitrary AWT component, using the new add() method of the Component class. And, finally, a popup menu can be "popped up" by calling its show() method. (The menu pops itself down automatically.)
An application typically displays a popup menu when the user clicks a certain mouse button over the component that the menu is attached to. However, different platforms traditionally use different mouse buttons to display popup menus. You can use the new isPopupTrigger() method of MouseEvent to determine whether a given mouse click has the appropriate modifiers set to trigger the popup menu for the current platform.
Java 1.1 also adds support for menu shortcut keys. The new MenuShortcut class represents a menu shortcut key. An instance of this class may optionally be specified whenever you create a MenuItem object. Again, different platforms use different modifier keys to invoke menu shortcuts, so when you create a MenuShortcut object, you specify only the key in question (plus, optionally, the Shift key). The system translates this into a platform-dependent shortcut using Ctrl, Alt, or some other modifier key.
The example in Chapter 8, New AWT Features demonstrates both a popup menu and menu shortcuts.
Keyboard Focus Traversal
The ability to operate a GUI without using the mouse is an important feature of any windowing toolkit. The addition of menu shortcuts in Java 1.1 is an important step in this direction. Java 1.1 also adds rudimentary facilities for keyboard focus traversal (i.e., moving keyboard focus among the individual components in a window) using the Tab and Shift-Tab keys.
Under the new focus traversal scheme, components within a container are traversed in the order in which they were added to the container. (Note, however, that it is possible to override this order by specifying an explicit position within the container's component list for a new component as it is added to the container with the add() method.) Beyond adding components to their container in the order desired for traversal, nothing else is required of the programmer in order to make keyboard focus traversal work.
If you are creating a custom component that can accept keyboard focus, you should override the isFocusTraversable() method to return true. The component should call the requestFocus() method it inherits from Component when the user clicks on it or otherwise activates it. Finally, when a component receives focus, (i.e., when its processFocusEvent() method is invoked), it should provide some sort of visual indication, such as a highlighted border, that it has the focus.
The SystemColor class represents a color used by the desktop system. On some platforms, these colors may be dynamically updated while the system is running. The SystemColor class also implements quite a few constants that represent system colors for various GUI components. Thus, if you want your GUIs to match the desktop color scheme, you might create them using colors such as SystemColor.menu (the background color for menus) and SystemColor.menuText (foreground color for menus), for example.
The treatment of fonts has been changed and improved somewhat in Java 1.1. The use of the font names "TimesRoman," "Helvetica," and "Courier" is now discouraged. Instead, you should use "serif," "sansserif," and "monospaced"--these names convey the essential style of the font face, without specifying the exact font to be used. The font names "Dialog" and "DialogInput" are still supported in Java 1.1. An important reason for switching to generic font names is that Java can now display any Unicode character for which there is an appropriate font installed on the host system. The names "serif" and "sansserif" have meaning even when applied to non-Latin character sets, such as Japanese Kanji characters; the names "timesroman" and "helvetica" clearly do not. Another result of this fuller Unicode support is that the use of the "ZapfDingbats" font is also discouraged. Instead, regardless of what font you are using, you can simply encode these graphical symbols using Unicode characters between \u2700 and \u27ff. (See Chapter 11, Internationalization for an example.) This improved support for Unicode makes it much easier to write internationalized programs in Java.
In Java 1.0, mouse cursors could only be specified for a Frame. In Java 1.1, every component can have a its own cursor, represented by the new Cursor object. There are new methods of Component for setting and querying the cursor. This change does not add any new predefined cursor images, nor does it add the ability to create custom cursors; it merely allows you to specify a cursor for any arbitrary component, and to do so in a more logical fashion.
The ScrollPane class is new in Java 1.1. It is a Container that makes it very easy to scroll a large component or GUI within a smaller visible area. Doing this in Java 1.0 required a custom container, and suffered from some serious performance problems. Chapter 8, New AWT Features shows the use of a ScrollPane object.
Another new feature is the ability to create "lightweight components." These are components and containers that do not have a native window of their own. In Java 1.0, custom components and containers had to be subclassed from Canvas or Panel. In Java 1.1, however, you can subclass Component and Container directly. Doing so creates a simpler component or container, without the overhead of a native window. It also allows you to create partially transparent components that appear non-rectangular.
Java 1.1 also includes several miscellaneous changes to clipping and image manipulation: