The Java TM Tutorial

| Start of Tutorial > Start of Trail > Start of Lesson | Search

Trail: To 1.1 -- And Beyond!
Lesson: Migrating to 1.1

## Incompatible Changes in the 1.1 AWT API

> As a rule, code written for the 1.0, 1.0.1, and 1.0.2 releases can be compiled without change in the 1.1 release (although you might see some warnings about "deprecated" API). Also, code compiled under those earlier releases generally works (without recompilation) at least as well in a 1.1 runtime system as it did before. This document lists the AWT exceptions to these rules -- the changes that might cause incompatible compilation or runtime behavior.

> Here are the incompatible AWT changes:

> 1. On Windows 95/NT systems, menus no longer allow keyboard alternatives, known as mnemonics. Due to an implementation flaw, you used to be able to specify mnemonics in Windows 95/NT by putting an ampersand ("&") in the menu label. For example, a menu item with the label "Save &As..." defined "a" as the mnemonic and would result in "A" being underlined in the displayed menu item -- but only on Windows 95/NT. Now, menus with "&" in the label simply display the "&" on Windows 95/NT, as they always have on other platforms. The reason the "&" hack no longer works is that it depended on the AWT using the native menu system, which it no longer does due to the need to support modifiable fonts and the display of non-Latin1 text. We plan to add support for menu mnemonics in a future release.

> 2. On Windows 95/NT systems, canvases and panels might seem unable to get keyboard events. The reason is that they no longer automatically get the focus, which is required for receiving keyboard events. To give a canvas or panel the focus, use the `requestFocus` method. For example, your implementation of the `mouseClicked` method in the `MouseListener` for a custom component should invoke the `requestFocus` method on the component.

> 3. The following four 1.0.2 methods in the `java.awt.peer` package have been removed in 1.1:
>    - `java.awt.peer.ComponentPeer:
>      public abstract boolean handleEvent(java.awt.Event);
>      public abstract void nextFocus();`
>    - `java.awt.peer.ScrollbarPeer:
>      public abstract void setValue(int);`
>    - `java.awt.peer.FramePeer:
>      public abstract void setCursor(int);`
>    Note: API in the `java.awt.peer` package is always subject to change because the peer classes aren't intended to be called directly by developers.

> 4. Trying to add a window to a container now results in an `IllegalArgumentException`.

> 5. The `Graphics` `drawPolygon` method used to draw unclosed polygons if the end point wasn't the same as the start point. In 1.1, `drawPolygon` automatically closes the polygon. If you want to draw an unclosed polygon, you can use the new `drawPolyline` method instead.

> 6. Constructors for the `Color` class now check the range of the parameters passed in, and throw an `IllegalArgumentException` if out-of-range values are encountered.

> 7. Passing a null frame to a `Dialog` constructor now results in an `IllegalArgumentException`.

> 8. The public abstract method `nextFocus` has been removed from the `java.awt.peer.ComponentPeer` interface. This does not affect applications or applets, since the peer interfaces are private interfaces between the AWT and its implementations.

> 9. Bug fixes in Win32 event handling might mean that your components get more events than they used to. Details are in the Improvements in Win32 Event Handling section below.

> 10. The synchronization model of the AWT has been revised to reduce the potential of deadlock. This might result in different behavior of existing programs. Details are in the Details of the New Synchronization Model section below.

### Improvements in Win32 Event Handling

Many bugs were fixed in the event handling of the win32 implementation of the AWT. In particular, focus events were previously not delivered to certain components (buttons, etc.) in 1.0.2, but are now properly delivered on win32 in 1.1. If you have a `handleEvent` method which is not coded properly to handle these new events, you may see changes in the way your program runs. For example, if you had the following fragment in the `handleEvent` method of a `Frame`:

>     if (event.id == Event.GOT_FOCUS) {
>         // do something...
>     }

This block will now be called when components within the `Frame` (such as buttons) get the focus. If the block isn't designed to handle this case, then your program may not run as it did in 1.0.2.

### Details of the New Synchronization Model

The synchronization model of the AWT has been revised to significantly reduce (but not eliminate) the potential of deadlock that existed in the 1.0.2 JDK. This is not, strictly speaking, an incompatibility with previous releases, but it does have the potential to change the behavior of existing programs. The AWT never was, and still isn't, guaranteed to be free of race conditions or deadlocks, given all the ways it can be invoked from and subclassed by client code.

In the new synchronization model, the structure and layout of components inside containers is guarded by a single AWT-wide lock, using an object called `Component.LOCK`, declared as follows in the `Component` class:

>     public static final Object LOCK = new Object();

For example, `Container.validate`, `Container.add`, and `Container.remove` all contain synchronized blocks that use `Component.LOCK`.

Setter methods for individual component state, such as `Component.setEnabled` or `Button.setLabel`, are synchronized on the instance itself. Getter methods are generally not synchronized, but they are semi-guarded by the copy-to-stack strategy: a thread-local copy of shared data is made and then used in the method.

Code that uses the AWT should be carefully scrutinized for uniform locking order if it acquires locks of its own while overriding an AWT method invoked in a synchronized context. For example, if you acquire your own locks in your layout code, you have to be aware that this code is being called with the `Component.LOCK` lock already held. If your code in another thread holds your lock and then tries to invoke `validate`, your program can deadlock. When you identify cases like this, you should rewrite your code wherever possible to ensure a uniform locking order. This order is usually client lock first, then `Component.LOCK`.

| Start of Tutorial > Start of Trail > Start of Lesson | Search