Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
Why should you update a 1.0 program to the 1.1 AWT API? Here are five possible reasons:
- The 1.1 version of AWT has some new features you want to use. See AWT Enhancements for a summary of new features.
- The new AWT architecture enables faster, more robust implementations of the AWT, which means that the updated program might work better.
- You plan to use the Swing components, which rely on the new event architecture. See Using Swing Components for information on the Swing components.
- The program is one of the rare ones that is affected by incompatible AWT changes. You can find a list of possibly incompatible bug fixes in the document Incompatible Changes in the 1.1 AWT API.
- You want the 1.1 Java compiler to compile the program without deprecation warnings.
Converting a 1.0 program to the 1.1 AWT API usually requires two steps:
The following two sections describe each step in detail, and then give an example.
- Replace deprecated methods with their 1.1 equivalents.
- Convert the program's event-handling code to use the new AWT event system.
Because so many methods were deprecated JavaSoft provides a script to help you convert 1.0 programs to the 1.1 versions. This script, calledupdateAWT
, uses on a UNIX utility calledsed
to change the names of many deprecated 1.0 AWT methods into their 1.1 equivalents. If you're developing on a PC, you might be able to run the script using a product such as MKS Toolkit, which provides PC versions of UNIX tools. For instructions, see Platform-specific Details: Using theupdateAWT
Script.You'll probably have to make some changes by hand, whether or not you use the
updateAWT
script. As described in How to Convert Your Program, you can get a list of the deprecated methods in the program by compiling its files with the-deprecation
flag.Once you know which deprecated methods the program uses, look up each method in the section Alternatives to Deprecated Methods in the AWT. Then replace each deprecated method with its 1.1 alternative. Most of the changes you need to make are straightforward, except those to event-handling code, which are described in the next section.
In 1.0, theComponent handleEvent
method (along with the methods it called, such asaction
) was the center of event handling. OnlyComponent
objects could handle events, and the component that handled an event had to be either the component in which the event occurred or a component above it in the component containment hierarchy.In 1.1, event handling is no longer restricted to objects in the component containment hierarchy, and the
handleEvent
method is no longer the center of event handling. Instead, objects of any type can register as event listeners. Event listeners receive notification only about the types of events they've registered their interest in. Never again will you have to create aComponent
subclass just to handle events.When upgrading to the 1.1 release, the simplest way to convert event-handling code is to leave it in the same class, making that class a listener for that type of event. That's the scheme that this section illustrates.
Another possibility is to centralize event-handling code in one or more non-
Component
listeners. This approach lets you separate the GUI of your program from implementation details. It requires that you modify your existing code so that the listeners can get whatever state information they require from the components. This approach can be worth your while if you're trying to keep your program's architecture clean.We recommend that you do not mix the 1.0 event model with the 1.1 event model in the same program. The results would be unpredictable and might be difficult to debug.
For more information about event handling, see Event Handling.
Making a
The process of making aComponent
a ListenerComponent
a listener can be straightforward, once you figure out which events a program handles and which components generate the events. If you're using a Java compiler from JDK 1.1.1 or later, then compiling with the-deprecation
flag generates a list that includes all old-style event handling methods. (Before 1.1.1, the compiler didn't generate a complete list, so you had to search for "Event" in a source file.) While you're looking at the code, you should note whether any classes exist solely for the purpose of handling events; you might be able to eliminate such classes.Here are the steps to follow when converting a 1.0 component into a listener:
- Figure out which components generate each event type. The Event-Conversion Table can help you know what to look for. For example, if you're converting event code that's in an
action
method, the table tells you to look forButton
,List
,MenuItem
,TextField
,Checkbox
, andChoice
objects.
- By looking up each event type in the Event-Conversion Table, note which listener interfaces the listener should implement, and which methods within each interface should contain event-handling code. For example, if you're trying to handle an action event generated by a
Button
, the table tells you to implement theActionListener
interface, putting the event-handling code in theactionPerformed
method
- Change the class declaration so that the class imports the necessary types and implements the appropriate listener interfaces:
Alternative: Instead of implementing an interface, you can declare an inner class that extends an event adapter class. Inner classes are useful when you need to implement only one method of an interface, but the interface contains many other methods. See Using Adapters and Inner Classes to Handle AWT Events for more information.import java.awt.event.*; ... public class MyClass extends SomeComponent implements ActionListener {
- Create empty implementations of all the methods in the listener interfaces your class must implement. Copy the event-handling code into the appropriate methods. For example,
ActionListener
has just one method,actionPerformed
. So as a shortcut way of creating the new method and copying the event-handling code to it, you can simply change the signature of anaction
method from this:to this:public boolean action(Event event, Object arg) {Alternative: If you use an adapter subclass to handle the events, you don't need to create empty implementations of methods. See Using Adapters and Inner Classes to Handle AWT Events for more information.public void actionPerformed(ActionEvent event) {
- Modify the event-handling code in these ways:
- Delete all
return
statements.- Change references to
event.target
to beevent.getSource()
.- Delete any code that unnecessarily tests for which component the event came from. Now that events are forwarded only if the generating component has a listener, you don't have to worry about receiving events from an unwanted component.
- Perform any other modifications required to make the program compile cleanly and execute correctly.
- Determine where the components that generate the events are created. Just after the code that creates each one, register
this
as the appropriate type of listener. For example:Alternative: If you use an inner class to handle the events, register an instance of that inner class instead. See Using Adapters and Inner Classes to Handle AWT Events for more information.newComponentObject.addActionListener(this);
- Compile and test your program. If your program is ignoring some events, make sure you added the correct event-listener object as a listener to the correct event-generating object.
AppletButton
.
The DialogWindow program is
featured in the section
How
to Use Dialogs.
% mkdir 1.0example % mv DialogWindow.class 1.0example % cp DialogWindow.java 1.0example
% updateAWT DialogWindow.java > tmp.java % diff DialogWindow.java tmp.java 33c33 < dialog.show(); --- > dialog.setVisible(true); 38c38 < textArea.appendText(text + "\n"); --- > textArea.append(text + "\n"); 47c47 < window.show(); --- > window.setVisible(true); 87c87 < hide(); --- > setVisible(false); % mv tmp.java DialogWindow.java
% which javac /usr/local/java/jdk1.1.1/solaris/bin/javac % javac DialogWindow.java Note: DialogWindow.java uses a deprecated API. Recompile with "-deprecation" for details. 1 warning %
As you can see, the example compiles successfully. However, a few calls or overrides of deprecated methods remain. The% javac -deprecation DialogWindow.java DialogWindow.java:18: Note: The method boolean handleEvent( java.awt.Event) in class java.awt.Component has been deprecated, and class DialogWindow overrides it. public boolean handleEvent(Event event) { ^ DialogWindow.java:26: Note: The method boolean handleEvent( java.awt.Event) in class java.awt.Component has been deprecated. return super.handleEvent(event); ^ DialogWindow.java:29: Note: The method boolean action( java.awt.Event, java.lang.Object) in class java.awt.Component has been deprecated, and class DialogWindow overrides it. public boolean action(Event event, Object arg) { ^ DialogWindow.java:81: Note: The method boolean action( java.awt.Event, java.lang.Object) in class java.awt.Component has been deprecated, and class SimpleDialog overrides it. public boolean action(Event event, Object arg) { ^ Note: DialogWindow.java uses a deprecated API. Please consult the documentation for a better alternative. 5 warnings %
Event
arguments to these methods
are a tell-tale sign that the methods contain event-handling code.
To convert DialogWindow, follow the sequence described previously in Making a Component a Listener.
-deprecation
flag
tells us that DialogWindow has three 1.0-style event-handling methods:
DialogWindow.handleEvent
DialogWindow.action
SimpleDialog.action
Studying DialogWindow's code tells us these things about its event handling architecture:
DialogWindow
handles window destroy events
for itself.
DialogWindow
handles action events
for the components it contains.
Upon closer inspection,
we can see that it contains only one component
that can generate action events: a Button
.
SimpleDialog
handles action events
for the components it contains.
Upon closer inspection,
we can see that it contains three components
that can generate action events:
two Button
s (Cancel and Set)
and a TextField
.
DialogWindow
and SimpleDialog
contain non-event-handling code,
so you can't eliminate them
by moving their event-handling code elsewhere.
windowClosing
method
of WindowListener
,
and that action events generated by buttons and text fields
are handled by the actionPerformed
method
of ActionListener
.
Instead of implementing theimport java.awt.event.*; public class DialogWindow extends Frame implements WindowListener, ActionListener { ... public DialogWindow() { ... Button button = new Button("Click to bring up dialog"); button.addActionListener(this); ... addWindowListener(this); } public void windowClosed(WindowEvent event) { } public void windowDeiconified(WindowEvent event) { } public void windowIconified(WindowEvent event) { } public void windowActivated(WindowEvent event) { } public void windowDeactivated(WindowEvent event) { } public void windowOpened(WindowEvent event) { } public void windowClosing(WindowEvent event) { if (inAnApplet) { dispose(); } else { System.exit(0); } } public void actionPerformed(ActionEvent event) { if (dialog == null) { dialog = new SimpleDialog(this, "A Simple Dialog"); } dialog.setVisible(); } ... } class SimpleDialog extends Dialog implements ActionListener { ... SimpleDialog(Frame dw, String title) { ... field = new TextField(40); field.addActionListener(this); ... Button b = new Button("Cancel"); b.addActionListener(this); setButton = new Button("Set"); setButton.addActionListener(this); ... } public void actionPerformed(ActionEvent event) { Object source = event.getSource(); if ( (source == setButton) | (source == field)) { parent.setText(field.getText()); } field.selectAll(); setVisible(false); } }
WindowListener
interface,
DialogWindow
could simply contain an inner class
that extends WindowAdapter.
This change makes the empty method bodies unnecessary.
The following are the highlights of
a DialogWindow
class
that uses an inner class to handle window events.
Significant changes from the 1.1 window listener version
are in bold.
public class DialogWindow extends Frame implements ActionListener { ... public DialogWindow() { ... Button button = new Button("Click to bring up dialog"); button.addActionListener(this); ... addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent event) { if (inAnApplet) { dispose(); } else { System.exit(0); } } }); } ...//No empty windowXXX method implementations!... ... }
Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
Copyright 1995-2004 Sun Microsystems, Inc. All rights reserved.