10 AWT
This chapter contains the following sections:
Debug Tips for AWT
Helpful tips to debug issues related to AWT.
To dump the AWT component hierarchy, press Control+Shift+F1.
If the application hangs, get a stack trace by pressing Control+Break on Windows (which sends the SIGBREAK signal) or Control+\ on the Oracle Solaris and Linux operating systems (which sends the SIGQUIT signal).
To trace X11 errors on the Oracle Solaris and Linux operating systems, set the sun.awt.noisyerrorhandler
system property to true
. In Java SE 6 and earlier releases, the NOISY_AWT
environment variable was used for this purpose.
Before Java SE 8, exceptions thrown in the AWT Event Dispatch Thread (EDT) could be caught by setting the system property sun.awt.exception.handler
to the name of the class that implements the public void handle(Throwable)
method. This mechanism was updated in Java SE 8 to use the standard Thread.UncaughtExceptionHandler
interface.
Loggers can produce helpful output when debugging AWT problems. See java.util.logging
package description.
The following loggers are available:
java.awt
java.awt.focus
java.awt.event
java.awt.mixing
sun.awt
sun.awt.windows
sun.awt.X11
Layout Manager Issues
This section describes possible problems with layout managers and provides workarounds when available.
Key Events
Issues related to handling key events that do not have a solution in the current release.
The following keyboard issues are currently unresolved:
-
On some non-English keyboards, certain accented keys are engraved on the key and therefore are primary layer characters. Nevertheless, they cannot be used for mnemonics because there is no corresponding Java keycode.
-
Changing the default locale at runtime does not change the text that is displayed for the menu accelerator keys.
-
On a standard 109-key Japanese keyboard, the yen key and the backslash key both generate a backslash, because they have the same character code for the
WM_CHAR
message. AWT should distinguish them.
The following keyboard issues concern the Oracle Solaris 10 and Linux x86 systems.
-
Keyboard input in these systems is usually based on the X keyboard extension (XKB) of the X Window System. Users can configure one keyboard layout (for instance, Danish:
dk
) or several layouts to switch between (for example,us
anddk
). -
With some keyboard layouts, for instance
sk
,hu
, andcz
, pressing the decimal separator on the numeric keypad not only enters a delimiter but also deletes the previous character. This is due to a native bug. A workaround is to use two layouts, for example,us
andsk
. In this case, the numeric keypad works correctly in both layouts. -
On UNIX systems that support dynamic keyboard changes, a running Java application does not recognize such a change. For instance, changing the keyboard from US to German does not change the keyboard mapping. Although the X server detects the change and sends out a
MappingNotify
event to interested clients AWT does not refresh its notion of the keycode-keysym mapping.
Modality Issues
Information about issues related to using modality.
With the Java SE 6 release, many problems were fixed and many improvements were implemented in the area of AWT modality. If you see a modality problem with Java SE 1.5 or an earlier release, first upgrade to the latest Java SE release to see if the problem was already fixed.
Some of the problems that were fixed in Java SE 6 are the following:
-
A modal dialog box goes behind a blocked frame.
-
Two modal dialog boxes with the same parent window opened at the same time.
The section addresses the following issues.
-
UNIX window managers:
Many of the modality improvements are unavailable in some Oracle Solaris or Linux environments, for example, when using Common Desktop Environment (CDE) window managers. With Java SE 6 and later releases, to see if a modality type or modal exclusion type is supported in a particular configuration, use the following methods:
-
Toolkit.isModalityTypeSupported()
-
Toolkit.isModalExclusionTypeSupported()
When a modal dialog box appears on the screen, the window manager might hide some of the Java top-level windows in the same application from the taskbar. This can confuse end users, but it does not affect their work much, because all the hidden windows are modal blocked and cannot be operated.
-
-
Other modality problems:
For more information about modality-related features and how to use them, see the AWT Modality specification.
One of the sections in that specification describes some AWT features that might be related to or affected by modal dialog boxes: always-on-top property, focus handling, window states, and so on. Application behavior in such cases is usually unspecified or depends on the platform; therefore, do not rely on any particular behavior.
Focus Events
The following sections discuss the troubleshooting issues related to focus events:
How to Trace Focus Events
You can trace focus events by adding a focus listener to the toolkit, as shown in the following example.
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener(
public void eventDispatched(AWTEvent e) {
System.err.println(e);
}
), FocusEvent.FOCUS_EVENT_MASK | WindowEvent.WINDOW_FOCUS_EVENT_MASK |
WindowEvent.WINDOW_EVENT_MASK);
The System.err
stream is used here because it does not buffer the output.
Remember:
The correct order of focus events is the following:-
FOCUS_LOST
on component losing focus -
WINDOW_LOST_FOCUS
on top-level losing focus -
WINDOW_DEACTIVATED
on top-level losing activation -
WINDOW_ACTIVATED
on top-level becoming active widow -
WINDOW_GAINED_FOCUS
on top-level becoming focused window -
FOCUS_GAINED
on component gaining focus
When focus is transferred between components inside the focused window, only FOCUS_LOST
and FOCUS_GAINED
events should be generated. When focus is transferred between owned windows of the same owner or between an owned window and its owner, then the following events should be generated:
-
FOCUS_LOST
-
WINDOW_LOST_FOCUS
-
WINDOW_GAINED_FOCUS
-
FOCUS_GAINED
Note:
The events losing focus or activation should come first.Native Focus System
Sometimes, a problem can be caused by the native platform. To check this, investigate the native events that are related to focus.
Ensure that the window you want to be focused gets activated and that the component you want to focus receives the native focus event.
On the Windows platform, the native focus events are the following:
-
WM_ACTIVATE
for a top-level.WPARAM
isWA_ACTIVE
when activating andWA_INACTIVE
when deactivating. -
WM_SETFOCUS
andWM_KILLFOCUS
for a component.
On the Windows platform, a concept of synthetic focus was implemented. It means that a focus owner component only emulates its focusable state, whereas real native focus is set to a focus proxy component. This component receives key and input method native messages and dispatches them to a focus owner. Before JDK7, a focus proxy component was a dedicated hidden child component inside a frame or dialog box. In the latest JDK releases a frame or dialog box serves as a focus proxy. Now, it proxies focus not only for components in an owned window but for all child components as well. A simple window never receives native focus and relies on the focus proxy of its owner. This mechanism is transparent for a user but should be taken into account when debugging.
On Oracle Solaris and Linux operating systems, XToolkit uses a focus model that allows AWT to manage focus itself. With this model the window manager does not directly set input focus on a top-level window, but instead it sends only the WM_TAKE_FOCUS
client message to indicate that focus should be set. AWT then explicitly sets focus on the top-level window if it is allowed.
Note:
The X server and some window managers may send focus events to a window. However, these events are discarded by AWT.AWT does not generate the hierarchical chains of focus events when a component inside a top-level gains focus. Moreover, the native window mapped to the component does not get a native focus event. On the Oracle Solaris and Linux platforms, as well as on the Windows platform, AWT uses the focus proxy mechanism. Therefore, focus on the component is set by synthesizing a focus event, whereas the invisible focus proxy has native focus.
A native window that is mapped to a Window
object (not a Frame
or Dialog
object) has the override-redirect
flag set. Thus, the window manager does not notify the window about the focus change. Focus is requested on the window only in response to a mouse click. This window will not receive native focus events at all. Therefore, you can trace only FocusIn
or FocusOut
events on a frame or dialog box. Because the major processing of focus occurs at the Java level, debugging focus with XToolkit is simpler than with WToolkit.
Focus Models Supported by X Window Managers
The following focus models are supported by X window managers:
-
Click-to-focus is a commonly used focus model. (For example, Microsoft Windows uses this model.)
-
Focus-follows-mouse is a focus model in which focus goes to the window that the mouse hovers over.
Data Transfer
The following sections discuss possible problems with data transfer features, which allow you to add drag-and-drop (DnD) and cut, copy, and paste (CCP) operations to the application.
Debug Drag-and-Drop Applications
It is difficult to use a debugger to troubleshoot DnD features, because during the drag-and-drop operation all input is grabbed. Therefore, if you place a breakpoint during DnD, you might need to restart your X server. Try to use remote debugging instead.
Two simple methods can be used to troubleshoot most issues with DnD:
Other Issues
The following subsections discuss troubleshooting tips for other issues:
Splash Screen Issues
Issues that can happen with splash screen AWT and solutions.
This section describes some issues that can happen with the splash screen in AWT:
Tray Icon Issues
If a SecurityManager
is installed, then the value of AWTPermission
must be set to accessSystemTray
in order to create a TrayIcon
object.
Pop-up Menu Issues
In the JPopupMenu.setInvoker() method, the invoker is the component in which the pop-up menu is to be displayed. If this property is set to null
, then the pop-up menu does not function correctly.
The solution is to set the pop-up menu's invoker to itself.
Background or Foreground Color Inheritance
To ensure the consistency of your application on every platform, use explicit color assignment (both foreground and background) for every component or container.
Many AWT components use their own defaults for background and foreground colors instead of using parent colors.
This behavior is platform-dependent; the same component can behave differently on different platforms. In addition, some components use the default value for one of the background or foreground colors, but take the value from the parent for another color.
AWT Panel Size Restriction
The AWT container has a size limitation. On most platforms, this limit is 32,767 pixels.
This means that, for example, if the canvas objects are 25 pixels high, then a Java AWT panel cannot display more than 1310 objects.
Unfortunately, there is no way to change this limit, neither with Java code nor with native code. The limit depends on what data type the operating system uses to store the widget size. For example, the Linux X windows system use the integer
type, and are therefore limited to the maximum size of an integer. Other operating systems might use different types, such as long
, and in this case, the limit could be higher.
See the documentation for your platform.
The following are examples of workarounds for this limit that might be helpful:
- Display components, page by page.
- Use tabs to display a few components at a time.
Hangs During Debugging of Pop-up Menus and Similar Components on X11
Set the -Dsun.awt.disablegrab=true
system property during the debugging of certain graphical user interface (GUI) components.
Certain graphical user interface (GUI) actions require grabbing all the input events in order to determine when the action should terminate (for example, navigating pop-up menus). While the grab is active, no other applications receive input events. If a Java application is being debugged, and a breakpoint is reached while the grab is active, then the operating system appears to hang. This happens because the Java application holding the grab is stopped by the debugger and cannot process any input events, and other applications do not receive the events due to the installed grab. In order to allow debugging such applications, the following system property should be set when running the application from the debugger:
-Dsun.awt.disablegrab=true
This property effectively turns off setting the grab, and does not hang the system. However, with this option set, in some cases, this can lead to the inability to terminate a GUI actions that would normally be terminated. For example, pop-up menus may not be dismissed when clicking a window's title bar.
Window.toFront()/toBack() Behavior on X11
Due to restrictions enforced by third-party software (in particular, by window managers such as the Metacity), the toFront()/toBack() methods may not work as expected and cause the window to not change its stacking order in relation to other top-level windows.
More details are available in the CR 6472274.
If an application wants to bring a window to the top, it can try to workaround the issue by calling Window.setAlwaysOnTop(true) to temporarily make the window always stay on top and then calling setAlwaysOnTop(false) to reset the "always on top" state.
Note:
This workaround is not guaranteed to work because window managers can enforce more restrictions. Also, setting a window to "always on top" is available to trusted applications only.
However, native applications experience similar issues, and this peculiarity makes Java applications behave similar to native applications.