Disclaimer and Legal Information
| Version | Version Information | Date | 
| Initial version | Nadya Morozova, Pavel Dolgov: document created. | May 10, 2006 | 
Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
Licensed under the Apache License, Version 2.0 (the License); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
This document introduces the AWT (Abstract Window Toolkit) framework delivered as part of the DRL (Dynamic Run-time Layer) initiative. This document focuses on the characteristics of the current AWT implementation.
The target audience for the document includes a wide community of engineers interested in further work with AWT to contribute to its development. The document assumes that readers are familiar with AWT and the Java* programming language.
This document uses the unified conventions for the DRL documentation kit.
As indicated in the specification [1], the Abstract Window Toolkit (AWT) is a part of the Java* Foundation Classes (JFC). AWT provides basic facilities to develop graphical user interfaces (GUI) and to draw simple graphics for platform-independent applets and applications.
In AWT, GUI consists of components, such as buttons, menus, and top-level windows. One of the main AWT features is that all its built-in components are heavy-weight, that is, every Java* component has a native GUI object behind it. The Swing library [2] is built on the basis of AWT and uses light-weight components, which do not have the 1:1 mapping with native resources.
         This document describes major design features and internal
         specifics of the DRL AWT implementation. Further in this
         document, AWT denotes the DRL implementation for
         convenience.
          To summarize, DRL AWT has the following key features:
      
AWT helps applications react to user's actions and traces the system state and the AWT internal state by means of events. Subsequent sections describe the AWT event handling implementation in DRL with focus on the interaction between AWT and the native system, specifically, the GUI subsystem of OS. For information on application events handling, consult the AWT specification [1].
The DRL AWT framework deals with the following types of events:
AWTEvent class and are stored in the AWT
            event queue represented by the�EventQueue
            class.
         
         AWT has the event dispatch thread (EDT) at its basis,
         represented by the
         class�java.awt.EventDispatchThread. This thread
         handles all generated types of events by going over the loop
         shown in Figure 1. EDT starts on AWT Toolkit creation and
         stops on application termination.
      
         
      
Figure 1: Native and AWT Events Handling
In more detail, EDT performs the following event loop:
java.awt.Dispatcher class.
         java.awt.EventQueue class.
         java.awt.Component.processXYZEvent()
            methods.
         EventListener interface.
            Applications should implement appropriate listeners'
            interfaces to react to specific events.
         awake() of
            the�NativeEventQueue interface is called.
			This method produces a native auxiliary event so that  EDT becomes ready to handle AWT events. EDT 
			treats this auxiliary event as invisible.
         This section defines native events types and the way AWT handles these events based on their type.
Figure 3 below demonstrates how native events can be classified by their role in the AWT framework.
         
      
Figure 3: Native Events Classification
Abstracting the Native Platform
         Native events handling goes in two stages: the first stage
         depends on the native platform, and the second stage is the
         same on all supported platforms. Platform-dependent
         functionality comprises the Window Toolkit, WTK, in
         the�org.apache.harmony.awt.wtk package. The
         platform-dependent and platform-independent levels cooperate
         via three main interfaces of this
         package:�NativeEventListener,�NativeEvent,
         and�NativeEventQueue, as shown in Figure 2.
         Classes implementing the�NativeEvent
         and�NativeEventQueue interfaces are
         platform-specific. For example, the�NativeEvent
         interface is implemented by the
         classes�LinuxEvent and�WinEvent
         for the Linux* and Windows* systems respectively.
      
         
      
Figure 2: Interfaces for Abstracting the Native Platform
�
         Classes of the�NativeEvent interface convert
         information about native events to a platform-independent
         format. The�NativeEventQueue interface fetches
         native events, and the�NativeEventListener
         interface of the Java* EDT thread handles
         native events. In the DRL AWT implementation, native and AWT
         events are handled by the single EDT thread. See the Multi-threading Support
         section for more information.
      
         The method�onEvent() in the
         platform-dependent�NativeEventListener
         interface processes native events. Platform-dependent
         classes implementing�NativeEventQueue call this
         method to handle a relevant native event, see Figure 4.
      
AWT handles relevant native events by following these steps:
NativeEvent interface translates the
            event to a unified format described by the
            interface�NativeEvent.
         NativeEventQueue calls the EDT
            method�onEvent() and passes the decoded
            event as a parameter.
         java.awt.Dispatcher
            class identifying the type of event.
         java.awt.MouseDispatcher works
            with mouse
            events,�java.awt.Dispatcher.KeyDispatcher
            processes keyboard events.
         The result of native event dispatching depends on the event type: state event, signal or invisible. Signal native events are translated to AWT events explicitly (Figure 4, second column). For state and invisible events, the AWT framework updates the state of the AWT object corresponding to the native object that sent the event. For state events, this implicitly generates an AWT event signaling an AWT object state change (Figure 4, third column). For invisible events, the AWT object state gets updated silently (Figure 4, fourth column).
         
      
Figure 4: Native Events Handling by Type
Native events often result in new AWT events that need to be handled. This section describes when and how AWT event handlers are called for this purpose.
         The Windows* OS generates synchronous and
         asynchronous native events, so that AWT must be ready to
         handle nested calls to the event handler. In this case, AWT
         makes an additional effort to handle AWT events one by one.
         DRL AWT uses the�WindowProc event handler
         inside WTK for interaction with Windows*.
         The OS calls this handler for handling any native event in
         AWT.
      
The Linux* event handling mechanism is different with its own method for handling native events. In this OS, all native events are asynchronous and no nesting happens.
Handling a single event
Figure 5 is an example of mouse click event handling in AWT. In the given case, the AWT listener does not co-operate with the underlying native system, and, consequently, no other native events are produced during the listener's operation. The example demonstrates handling an event on Windows*.
         
      
Figure 5: Mouse Click Event Handling
Numbers in the figure above correspond to the following steps in the event handling flow:
WindowProc to handle the native
            event. The type of event is determined, information about
            this event is gathered and passed to
            the�onEvent() method
            of�NativeEventListener.
         java.awt.Dispatcher class finds the
            appropriate target for this event and posts an AWT event
            to the AWT event queue. In this example, it
            is�MouseEvent.
         onEventNestingEnd() is called to
            handle all accumulated AWT
            events.�MouseEvent is fetched from the event
            queue and finally dispatched. Listeners of the event's
            target are called at this point.
         WindowProc returns.
         Handling nested events
Figure 6 is an example of mouse click event handling with the event listener requests keyboard focus on the clicked component.
         
      
Figure 6: Mouse Click Event Handling with a Nested Event
Numbers in the figure above correspond to the following steps in the event handling flow:
WindowProc, the native event is
            transformed into an AWT event and stored in the event
            queue.
         requestFocus(),
            which indirectly results in a native API call.
         WindowProc to report the focus
            change event. Because the previous call
            to�WindowProc is not complete yet, the new
            call is recognized as nested.
         FocusEvent, to the event queue.
         WindowProc returns without handling AWT
            events because it is a nested native event handler.
         onEventNestingEnd() is still
            working in the first-level�WindowProc
            handler. This method fetches and dispatches
            the�FocusEvent added at step 4.
         WindowProc returns.
         This technique guarantees that AWT event handlers are called sequentially. The nested native event handler does not attempt to handle pending AWT events. Instead, these events are collected in the event queue to be handled later. The first-level native event handler dispatches all the AWT events waiting in the queue.
The AWT focus subsystem is a set of classes for managing keyboard input focus responsible for:
Win32 or�X11, by way of
            handling native focus events and making native focus
            requests
         In the DRL implementation, the focus subsystem functionality is distributed among several internal layers:
The interaction between user code and these levels of the focus subsystem is shown on Figure 7 below.
         
      
Figure 7. Focus Event Data Flow
The following code entities perform the major focus subsystem tasks:
java.awt.FocusDispatcher class handles
            focus events received from the window toolkit level.
         KeyboardFocusManager class manage focus
            on the higher AWT level.
         Subsequent sections describe the levels of focus management in more detail and give specifics of the DRL implementation compared to the focus specification [3].
The focus dispatcher responds to native focus events and, for those relevant to AWT, sends an internal focus change event to the higher AWT level. The dispatcher skips redundant native events and handles event proxying supported on certain native platforms. The focus dispatcher in DRL is characterized by the features listed below.
               
            
Figure 8. Focus Proxy
If the active window is the focused window, no proxying occurs. In this case, the nearest heavyweight ancestor of the focus owner or the focus owner native window itself (if focus owner is a heavy-weight component) has native focus.
The higher level of the focus subsystem generates and posts all necessary AWT events to the event queue. This level keeps track of the following focus states:
         The AWT level of the focus subsystem handles focus requests
         synchronously on every successful focus change request. When
         the method�requestFocus() is called, the
         keyboard focus manager posts all necessary AWT events in the
         required order irrespective of the success or failure of the
         native focus request. In other words, the AWT subsystem does
         not wait until the native focus request gets confirmed and
         the corresponding native events are received.
      
After receiving a notification from the native system, WTK requests the AWT level to update the focus state via an internal request. For example, if the native system reports an unsuccessful focus change, a component might lose focus.
Note
Only certain native focus-related events cause a Java* focus state update. For example:
Window
            component itself, in case no child elements are
            available.
         setFocus(false)
            method on the focus owner to clear the focus owner value.
         Below, the specific features of DRL implementation are listed compared to the focus specification grouped by their function.
WINDOW_GAINED_FOCUS
            event, private methods in the keyboard focus manager set
            focus on the appropriate child component of the window.
         This document describes the mechanism of drawing standard AWT components with platform-independent Java* means or platform-specific native API or using both approaches.
         You can paint standard components in many ways, including
         drawing the component parts (text, background, shadows and
         all other elements) by the means of
         class�java.awt.Graphics. Note that the
         framework must not paint standard components by the
         method�java.awt.Component.paint() because it
         could be overridden. Instead, when processing a painting
         event, the framework calls the package-private
         method�java.awt.Component.prepaint() just
         before calling the method�paint().
         The�prepaint() method does the actual painting
         for all standard components by delegating the painting task
         to the theme. This approach might not seem optimal, but it
         works on all supported platforms without any changes.
      
         The�org.apache.harmony.awt.Theme class
         implements the default theme. Methods of this class do the
         following:
      
drawButton().
         calculateButton().
         The default theme class is platform-independent, non-abstract and fully functional, and it usually works when the native theme is disabled or not available, or when the native theme re-uses functionality of the standard theme.
         You can create a custom theme that inherits from the default
         theme and contains specific features. The current
         implementation contains the�WinTheme class that
         extends the default theme as shown in Figure 9.
      
         To use the native API in your theme, extend the default
         theme overriding its painting methods. In the derived theme,
         you can use the additional features of specific
         implementation of the�Graphics class, and
         explicitly call native API functions via wrappers,
         see�org.apache.harmony.misc package for
         details. Figure 9 below demonstrates theme-related classes
         hierarchy with methods related to the�Button
         component as an example. A block of code for extending
         the�drawButton() method is shown in Example 1 below.
      
         
      
Figure 9: Hierarchy of Theme Classes
�
         After creating a derived theme, turn it on by using the
         property�awt.theme. This property contains the
         name of a subclass of default theme class used as the theme
         by all components. If the property points to a non-existent
         class or if the required native library is missing, or any
         other error occurs, the default theme is used. If the
         property is not set, the native theme of the current OS is
         used if it exists. If no OS theme exists, the default theme
         is used.
      
         To force the default theme, set the command-line
         option�-Dawt.theme=0. As long as zero is an
         invalid class name, this does the job.
      
         Painting standard components requires access to their
         internal state, such as the pressed state, the focused
         state, the background color, and the contained text. Because
         not all these attributes are visible through the public API,
         the DRL AWT module provides a set of interfaces to allow the
         theme to access private and public data. The
         package�org.apache.harmony.awt.state contains
         these interfaces, such
         as,�TextState,�CheckboxState,
         and�ButtonState. Each standard component class
         has an inner class that implements the appropriate interface
         and has the state field of that class declared.
         The�java.awt.Component class stores all
         functionality common for all types of standard components.
         Specifically, the�java.awt.Component class has
         an inner class�ComponentState that implements
         the�org.apache.harmony.awt.state.State
         interface. This inner class enables implementing the state
         of a specific component by overriding only a few methods.
      
Standard components delegate the painting and size calculation to the currently active theme and pass their state field value as a parameter to every method of the theme.
         Platform-specific and component-specific code is
         concentrated in separate helper classes, such
         as�DefaultButton, the helper to the default
         theme, and�WinCheckbox, the helper to the
         Windows* theme. The theme class contains
         only simple methods.
      
         This is an example with the�Button component.
      
public void drawButton(Graphics g, ButtonState s) { 
    drawButtonBackground(g, s); 
    drawButtonText(g, s); 
} 
protected void drawButtonBackground(Graphics g, ButtonState s) { 
    DefaultButton.drawBackground(g, s); 
} 
protected void drawButtonText(Graphics g, ButtonState s) { 
    DefaultButton.drawText(g, s); 
}
      When designing a custom theme, you may need to override some of these protected methods.
         Figure 10 shows an example of component classes relation,
         inner states and the inheritance hierarchy of component
         state interfaces.
The figure contains short names for convenience, for example, 
 Component actually means  java.awt.Component. 
         
      
Figure 10: Inheritance and Composition for Components' State
         This section illustrates how the state interfaces are used
         in the�Button component. In DRL AWT, all
         standard components follow the same model.
      
         This is a part of the�java.awt.Button code that
         illustrates how to use visual themes in standard components.
      
class State extends Component.ComponentState implements ButtonState { … } 
final transient State state = new State(); 
    
void prepaint(Graphics g) { 
    toolkit.theme.drawButton(g, state); 
}
      
         The framework calls the�prepaint() method,
         which paints standard components. The painting itself is
         done by the theme class, and all the information it requires
         is contained in the state variable.
      
         In DRL, the Windows* theme is implemented
         by the
         class�org.apache.harmony.awt.theme.windows.WinTheme,
         which inherits from the
         class�org.apache.harmony.awt.Theme.
      
         The�WinTheme class paints components using the
         Windows* API
         function�DrawFrameControl() in the classic mode
         and�DrawThemeBackground() in the XP mode, and
         basic Windows* API painting functions.
      
The implementation also includes several helper classes:
org.apache.harmony.awt.gl.WinThemeGraphics
            has a set of native methods that call the Windows* API. This class is tightly coupled
            with�org.apache.harmony.awt.gl.WinGDIPGraphics2D,
            which is an implementation
            of�java.awt.Graphics.
            The�WinThemeGraphics class
            queries�WinGDIPGraphics2D for the current
            clip, translation and device context.
         org.apache.harmony.awt.wtk.windows.WinEventQueue.ThemeMap
            that handles theme-related native events and opens and
            closes handles of native theme data when needed.
         org.apache.harmony.awt.wtk.theme.windows
            responsible for specific types of components, for
            example,�org.apache.harmony.awt.wtk.theme.windows.WinButton.
         Note
If the Windows* theme does not support the combination of components attributes, it delegates painting to the default theme by calling the super class. For example, the default theme can be used when the background color of a push button differs from the theme setting.
Complying to the specification [1], DRL AWT can work within multi-threaded applications. This implementation ensures consistency of AWT framework data when accessed by multiple threads. For that, AWT synchronizes its key classes.
The main purpose of synchronization is keeping the component hierarchy consistent when component properties are queried and/or modified, so that it potentially affects other components. This includes the parent-child relationships, the child component order, inherited properties, such as the font and the background color, the size and position related properties, as well as visibility, focusable state and other conditions relevant for message handling. Concurrent modifications of these properties can make the AWT framework state inconsistent.
         For example, if a thread adds a component to a list of child
         components for a container without updating this
         component’s field�parent, another thread
         working with the same component gets the wrong value of
         the�parent field. Moreover, the second thread
         may remove this component from the container children list,
         which makes the behavior of the first thread unpredictable.
         Synchronization helps avoid such problems.
      
         When a method or a block of code deals with the data that
         must not be modified concurrently, a synchronized section is
         used. The DRL implementation uses a special monitor AWT
         lock more powerful than built-in Java*
         synchronized blocks and methods. The AWT lock is similar to
         the synchronization tools provided by
         the�java.util.concurrent package. The
         synchronized section using the AWT lock has its own
         specifics, as demonstrated by the example below.
      
Example 2
         This example provides an excerpt of code from
         the�Component class demonstrating a typical
         synchronized section in the AWT code. The
         methods�lockAWT() and�unlockAWT()
         are the boundaries of the critical section. The code between
         them is synchronized by the AWT lock.
      
final transient Toolkit toolkit = Toolkit.getDefaultToolkit();
…
public Color getBackground() {
    toolkit.lockAWT();
    try {
        if ((backColor == null) && (parent != null)) {
            return parent.getBackground();
        }
        return backColor;
    } finally {
        toolkit.unlockAWT();
    }
}
      
         From the syntactical standpoint, this is a try-finally
         structure, which guarantees that
         the�unlockAWT() method is always called after
         doing the useful work in the body of try block. Logically,
         it is used as an ordinary synchronized block, except when
         using AWT lock extended functionality.
      
AWT synchronization covers the following classes:
Component,�Button,
            and�Frame
         FlowLayout
            and�GridBagLayout
         Toolkit
            and�KeyboardFocusManager
         The total number of synchronized classes nears 40.
         Simple data structures, for example,�Rectangle
         or�Point, are not protected from concurrent
         modifications for performance reasons.
      
General rules on how to use synchronized sections
java.awt.Toolkit class.
         addNotify() in
            the�Component and�Container
            classes.
         org.apache.harmony.awt.wtk package must
            not use the AWT lock explicitly.
         Note
         In platform-specific event handling code, the event listener
         uses this lock by calling
         methods�onEventBegin()
         and�onEventEnd(). These methods
         call�lockAWT() and�unlockAWT()
         respectively. This is done to ensure that the dispatcher can
         find the event target and that the data is not modified by
         another thread.
      
         The�org.apache.harmony.awt.wtk.Synchronizer
         class implements the AWT lock. The�Toolkit
         class holds the reference to the synchronizer instance. In a
         standalone application,�Toolkit
         and�Synchronizer are singleton classes. In the
         multi-context mode, AWT provides
         independent�Toolkit
         and�Synchronizer instances per each context.
      
Figure 11 shows the inheritance relationship of synchronizer classes. The Linux* and Windows* operating systems have their own classes.
         
      
Figure 11: Synchronizer Classes
         The base class�Synchronizer represents a mutex
         with a high-priority event
         dispatch thread. All user threads are served in the FIFO
         (first in first out) order, whereas EDT has higher priority
         and is served in the LIFO (last in first out) order.
      
Synchronizer for Linux*
         AWT uses the Xlib library to access native window resources
         on Linux*. The Xlib library is thread-safe
         and all user and EDT threads can freely access the native
         system through the AWT interface, as shown in Figure 12. As
         a result, the
         class�org.apache.harmony.awt.wtk.linux.LinuxSynchronizer
         contains no extensions
         to�java.awt.Synchronizer.
      
         
      
Figure 12: Access to the Native System on Linux*
Synchronizer for Windows*
Synchronization on Windows* is different due to Windows* libraries specifics. Firstly, changing the state of a native window usually produces a synchronous event that reports this change. Secondly, only the thread that created a window receives native events related to that window.
In DRL AWT, the event dispatch thread handles all native events and, consequently, is the only thread that can create windows. EDT also changes the window’s state to simplify the native events handling scheme. Non-EDT threads can create and manipulate native windows by giving tasks to EDT. User and EDT threads cooperation is shown in Figure 13.
         
      
Figure 13: Access to the Native System on Windows* with EDT
         The�org.apache.harmony.awt.wtk.windows.WinSynchronizer
         class, the extension of�Synchronizer,
         implements the interface�NativeServer, which
         enables user threads to query EDT for access to native
         resources.
      
         However, delegating access to native resources to EDT
         requires a more complicated synchronization mechanism. Using
         the�Synchronizer logic as is results in a
         potential deadlock while handling native Windows* events. Figure 14 shows the scenario of the
         deadlock.
      
         
      
Figure 14: Deadlock with the user thread and EDT
t1: The user thread starts.
t2: EDT starts.
t3: The user thread obtains the AWT lock.
t4: EDT tries to obtain the AWT lock and gets blocked.
         t5: The user thread requests a service from EDT via
         the�NativeServer interface and gets blocked
         forever because EDT is blocked too.
      
         The�WinSynchronizer class resolves the deadlock
         issue by combining the synchronizer’s protocol and the
         native server protocol. For that, EDT switches between handling events and providing access to native resources for other running threads, as shown in Figure 15.
      
         
      
Figure 15. EDT Operation
         This algorithm  enables detecting a
         potential deadlock and resolving it. When EDT is requested
         to provide access to native resources while it is waiting to obtain the AWT
         lock, EDT awakes, serves the request and resumes waiting.
         Serving the native resource request is transparent for the
         event-handling side of EDT because this operation is
         performed while EDT is inside of�lockAWT()
         method. The deadlock is resolved, as shown in Figure 16.
      
         
      
Figure 16: Deadlock Resolution by WinSynchronizer
t1: The user thread starts.
t2: EDT starts.
t3: The user thread obtains the AWT lock.
t4: EDT tries to obtain the AWT lock and gets blocked.
t5: The user thread requests EDT service and also gets blocked. EDT starts processing the request.
t6: EDT finishes processing request. The user thread resumes.
t7: The user thread releases the AWT lock, EDT obtains it.
t8: The user thread may continue its work or exit.
t9: EDT releases the AWT lock.
t10: EDT continues operation.
[1] AWT spec, http://java.sun.com/j2se/1.5.0/docs/guide/awt/index.html
[2] Swing Library Description, http://java.sun.com/j2se/1.5.0/docs/guide/swing/index.html
[3] AWT Focus Subsystem specification, http://java.sun.com/j2se/1.5.0/docs/api/java/awt/doc-files/FocusSpec.html
�
* Other brands and names are the property of their respective owners.