1.4.2 Bug Fixes
1.4.1 Bug Fixes
New Focus Subsystem
Deprecated Focus Methods
ActionEvents (and Other Events) Need
Timestamps
Headless Support
Window Centering API Required for
Multiscreen Support
The New Fullscreen Exclusive Mode
API
Sync Out of Range Error From Video Driver
Under Windows NT Undecorated
Frames
Mouse Wheel Support
Programmatic Zooming of
Frame
s
Dynamic Layout During Resize
Access to Component Listener
Lists
Changes to Drag and Drop
64-Bit Compliance on Solaris
Inconsistent DLLs Warning
Removal of the
DrawingSurface
API
New InputEvent Key Modifiers
Change in Drop Down Behavior for Choice
Menus
Choice Component Now Obeys Layout Manager
Constraints
4648702: On Microsoft Windows 2000 and Windows XP, a
TextArea
will sometimes display only a vertical
scrollbar, even though the SCROLLBARS_BOTH
field is
set to true
.
4636311: Modal dialogs may hang when run from a
Runnable
on release 1.3.1 and 1.4.
4385243: Unable to input text in Microsoft Windows locales that don't have an ANSI code page (such as Hindi).
1.4.1 Bug Fixes4690831: Game applets fail to repaint properly with Internet Explorer.
4627627: Focus traversal keys moved from awt.properties to Preferences API.
4636548/ 4639735: Crash of release 1.4 when screensaver on Microsoft Windows 2000 is activated.
4379138: Problems on Linux with key events for some dead keys.
4627542: Swing applications don't support international keyboards under Linux.
4395157: Under Linux on 1.3, can't type "%" in applets.
4669873: A drag and drop bug, reported on hopper-beta under Microsoft Windows, caused an application to briefly freeze during DnD and is fixed in the final release of 1.4.1.
New Focus SubsystemThe bugtraq report that corresponds to this change is: 4290675.
A new focus subsystem replaces the previous focus architecture and addresses many focus-related bugs caused by platform inconsistencies, and incompatibilities between AWT and Swing components. See the new Focus Model Specification for further details.
See the javadoc here.
Headless SupportThe bugtraq report that corresponds to this change is: 4281163.
Many environments, such as mainframe machines and dedicated
servers, do not support a display, keyboard, or mouse. Headless
support is enabled by the new GraphicsEnvironment
methods isHeadless
and
isHeadlessInstance
. These methods indicate whether a
display, keyboard, and mouse can be supported in a graphics
environment.
The API changes for headless include:
java.awt.HeadlessException
,
is introduced. It is derived from
UnsupportedOperationException
, which derives from
RuntimeException
, so that existing implementations of
methods that throw the new exception will not require signature
changes.java.awt.GraphicsEnvironment
.
public static boolean isHeadless() public boolean isHeadlessInstance()
Applet
and all heavyweight
components (*) are changed to throw HeadlessException
if a display, keyboard, and mouse are not supported by the toolkit
implementation. All javadoc tags on all constructors are changed to
reflect this RuntimeException
.Robot
constructor throws an
AWTException
if a display, keyboard, and mouse are not
supported by the toolkit implementation.Toolkit
and
GraphicsEnvironment
, with the exception of fonts,
imaging, and printing, are changed to throw
HeadlessException
if a display, keyboard, and mouse
are not supported. All the javadoc tags on these methods are
changed to reflect this RuntimeException
.HeadlessException
.HeadlessException
is thrown if and only if
isHeadless
returns true, and that all javadoc comments
should specify this.(*)Applet
, Button
,
Checkbox
, Choice
,
FileDialog
, Label
, List
,
Menu
, MenuBar
,
MenuComponent
, MenuItem
,
PopupMenu
, Scrollbar
,
ScrollPane
, TextArea
,
TextComponent
, Frame
,
Window
, Dialog
, JApplet
,
JFrame
, JWindow
, JDialog
,
and TextField
. Canvas
and
Panel
do not need to throw this exception since these
can be given empty peers and treated as lightweights.
To run our environment with a headless implementation, the
follow property may be specified at the java
command
line:
-Djava.awt.headless=trueIf this property is not specified and a display, keyboard, and mouse are not supported, then headless implementation is used by default.
Source code should check for headless, so that the exception may
be caught gracefully. For example, see the following pre-headless
implementation of the class Foo
:
class Foo { static Choice c = new Choice(); // could throw HeadlessException }The new and improved implementation of
Foo
should be
placed in a static block:
class Foo { static Choice c; static { try { c = new Choice(); catch (HeadlessException e) { ... } } }
The New Fullscreen Exclusive Mode API
The bugtraq report that corresponds to this change is: 4189326.
The new full-screen exclusive mode API supports high performance
graphics by suspending the windowing system so that drawing can be
done directly to the screen. Full screen mode, which is entirely
different from simply taking an AWT Frame
,
Window
, or Dialog
and expanding it to fit
the screen, is a graphics mode whereby the application takes entire
control over the contents of video memory. The application tells
the graphics card what to draw, how to draw it, and when to draw
it. This mode is not always available. On some operating systems,
it may not be implemented at all. On other operating systems, it
may only be available if the capability is supported by the
graphics card. Nevertheless, this mode is critical for performance
and is necessary for enabling hardware page-flipping on
Windows.
For a tutorial explaining how to use the full screen exclusive API mode with several code examples, see here.
API Changes:
java.awt.DisplayMode
,
is introduced.java.awt.GraphicsDevice
:
public void setFullScreenWindow(Window w) public Window getFullScreenWindow() public boolean isDisplayChangeSupported() public void setDisplayMode(DisplayMode dm) public DisplayMode getDisplayMode() public DisplayMode[] getDisplayModes()
java.awt.image.BufferStrategy
.java.awt.BufferCapabilities
can be used when creating a buffer strategy. Likewise, a new class
java.awt.ImageCapabilities
is available to define the image capabilities of a specific
configuration.Canvas
or a Window
. There are two
buffer strategies that are supported as protected inner classes:
java.awt.Component.FlipBufferStrategy
and java.awt.Component.BltBufferStrategy
.
One of these two inner classes is used on the Canvas
or
Window
when the createBufferStrategy
method is called,
depending on the BufferCapabilities
object supplied
when creating the strategy (if any). To get the buffer strategy
used by a particular component, the getBufferStrategy
method is used.The bugtraq report that corresponds to this change is: 4452207.
If you have a Dell Optiplex GX110 using an Intel 810 Graphics Controller, under Windows NT, you may get a "sync out of range" message from the video driver if you change the display mode more than once and use a high display resolution. There is evidently a bug in the (DirectX) video driver that is causing this. There are several workarounds to this problem:
-Dsun.java2d.noddraw=true
at the command line.1152 X 864 8 85 1152 X 864 16 85 1152 X 864 24 85 1280 X 1024 8 70,72,75,85 1280 X 1024 16 70,72,75,85 1280 X 1024 24 70,75,85 Bad Color (Unsatisfactory appearance in terms of color) 1024 X 768 8 60,70,72,75,85
The bugtraq report that corresponds to this change is: 4038769.
For certain applications having no native frame decorations makes sense. For example, applications that will run across many platforms and that require that the look and feel is the same, or when the programmer does not want the end-user coming in contact with the native operating system.
This release allows a Java application to turn off the creation of frame decorations; no native titlebar, system menu, border, or other native operating system dependent screen components appear when this mode is enabled. AWT and Swing components work transparently.
Changes to java.awt.Frame
:
public void setUndecorated(boolean undecorated) public boolean isUndecorated()
Changes to java.awt.Dialog
:
public void setUndecorated(boolean undecorated) public boolean isUndecorated()
The bugtraq report that corresponds to this change is: 4289845.
The mouse wheel, with a scroll wheel in place of the middle
mouse button, is enabled with new built-in Java support for
scrolling via the mouse wheel. The java.awt.event.MouseWheelEvent
class enables seamless support for mouse wheel scrolling in Java
applications with no recompiling required. Also, a new java.awt.event.MouseWheelListener
interface allows customization of mouse wheel behavior.
Note, for those using the mouse wheel on Linux, see here.
Component
than can be displayed at once, such that the
scroll thumb does not occupy the entire scroll track.setWheelScrollEnabled(false)
.TextArea
, Choice
,
FileDialog
, and List
. Such components
will let their native peers handle wheel scrolling.Component
s which do not inherit any native mouse
wheel behavior will propagate mouse wheel events up the
Container
hierarchy until a Container
with MouseWheelEvent
s enabled is found. This is
typically a ScrollPane
. Mouse wheel events are
delivered to the Component
with
MouseWheelEvent
s enabled.MouseWheelListener
s to customize what happens when the
mouse wheel is moved while the mouse is over a
Component
. In the case of Component
s that
already have native handling of mouse wheel events, clients may
consume the mouse wheel event to avoid native handling.java.awt.ScrollPane
is modified to have
MouseWheelEvent
s enabled by default. When a
ScrollPane
receives a MouseWheelEvent
, it
will properly scroll its contained Component
. This
functionality may be disabled with the new
setWheelScrollingEnabled
method.Lightweight Support:
MouseWheelListener
.MouseWheelListener
s may be added to any
JComponent
for custom event handling.javax.swing.JScrollPane
is modified to properly
scroll its viewed component. Like java.awt.ScrollPane
,
this may be disabled using
setWheelScrollingEnabled
.In addition to the new class and new interface previously mentioned, there are some other changes to the API to support the mouse wheel.
java.awt.AWTEvent
:
public final static long MOUSE_WHEEL_EVENT_MASK;
java.awt.AWTEventMulticaster
:
public void mouseWheelMoved(MouseWheelEvent e) public static MouseWheelListener add(MouseWheelListener a, MouseWheelListener b) public static MouseWheelListener remove(MouseWheelListener l, MouseWheelListener oldl)
java.awt.Component
:
public synchronized void addMouseWheelListener(MouseWheelListener l) public synchronized void removeMouseWheelListener(MouseWheelListener l)
java.awt.ScrollPane
:
public void setWheelScrollingEnabled(boolean handleWheel) public boolean isWheelScrollingEnabled()
java.awt.Robot
:
public synchronized void mouseWheel(int wheelAmt)
For Linux to recognize your mouse wheel, two modifications to
the /etc/X11/XF86Config
file are required. Under the
"Pointer" section:
Add the line:
ZAxisMapping 4 5
Change the protocol to: "imps/2" (this will vary depending on your particular wheel mouse).
Programmatic Zooming of
Frame
s
The bugtraq report that corresponds to this change is: 4071554.
Previously there was no way to zoom (or maximize) a
Frame
programmatically. This feature has been added to
this release.
The new interface java.awt.event.WindowStateListener
is introduced.
Changes to java.awt.Frame
:
public static final int MAXIMIZED_HORIZ; public static final int MAXIMIZED_VERT; public static final int MAXIMIZED_BOTH; public synchronized void setMaximizedBounds(Rectangle bounds) public Rectangle getMaximizedBounds() public synchronized void setExtendedState(int state) public synchronized int getExtendedState()
Changes to java.awt.event.WindowEvent
:
public static final int WINDOW_STATE_CHANGED; public WindowEvent(Window source, int id, Window opposite, int oldState, int newState) public WindowEvent(Window source, int id, int oldState, int newState) public int getOldState() public int getNewState()
Changes to java.awt.AWTEvent
:
public final static long WINDOW_STATE_EVENT_MASK;
Changes to java.awt.Toolkit
:
public boolean isFrameStateSupported(int state) throws HeadlessException
Changes to java.awt.Window
:
public synchronized void addWindowStateListener(WindowStateListener l) public synchronized void removeWindowStateListener(WindowStateListener l) public synchronized WindowStateListener[] getWindowStateListeners() protected void processWindowStateEvent(WindowEvent e)
Change to java.awt.event.WindowAdapter
:
public void windowStateChanged(WindowEvent e)
Changes to java.awt.AWTEventMulticaster
:
public static WindowStateListener add(WindowStateListener a, WindowStateListener b) public static WindowStateListener remove(WindowStateListener l, WindowStateListener oldl)
The bugtraq report that corresponds to this change is: 4077991.
Previously, dynamic window resizing wasn't supported on all
platforms. For example, on Windows NT, with solid resize on,
resizing a window recalculated the layout only when the drag was
finished. This has been fixed in this release with the addition of
the new desktop property awt.dynamicLayoutSupported
.
When dynamic layout is enabled, a Container
continually lays out its components as it resizes. If disabled, the
layout will be validated after resizing has finished.
API changes to java.awt.Toolkit
.
public void setDynamicLayout(boolean dynamic) protected boolean isDynamicLayoutSet() public boolean isDynamicLayoutActive()
Access to Component Listener Lists
The bugtraq report that corresponds to this change is: 4290704.
Previously all of the state in an AWT component that could be
written could also be read. For example, there are no write-only
properties in the component API. Event listeners were a notable
exception. AWT event listeners are managed according to the
JavaBeansTM conventions with a
pair of methods: addXXXListener
and
removeXXXListener
for a listener that
implements the XXXEventListener
interface.
No access was provided to the listener lists themselves. The fields that contain the listener lists are package private and no method was provided that returns the contents of a listener list. This has caused some problems for Swing and other AWT clients.
To mitigate the problem in the Java 2 SDK, v1.3 release, we
added a getListeners
method to Component
and to the Swing classes that defined listener lists. The
getListeners
method uses a class to specify a
particular listener list. For example to get all of the listeners
added with addFocusListener
, one would write:
getListeners(FocusListener.class)
.
This particular approach to exposing listener lists was taken to
minimize the overall change to the AWT/Swing public API. It was not
intended to be a convention for all JavaBeans and it did not handle
PropertyChangeListener
s - which can be added to a
single property, as in
addPropertyChangeListener("myProperty", myListener)
.
For this release, we have designed a more complete solution to
accessing event listeners. The two conceptual changes are:
getFooListeners
method to the
add/remove convention in AWT and Swing classes.PropertyChangeListener
s and
VetoableChangeListener
s, including those which listen
to a single property, using the new java.util.EventListenerProxy
class.There is a new java.awt.event.AWTEventListenerProxy
class.
API Changes to java.awt.Toolkit
:
public PropertyChangeListener[] getPropertyChangeListeners() public synchronized PropertyChangeListener[] getPropertyChangeListeners(String propertyName) public AWTEventListener[] getAWTEventListeners() public AWTEventListener[] getAWTEventListeners(long eventMask)
The bugtraq reports that corresponds to this change are: 4407057 and 4426750.
In the Solaris and Linux releases of Java 2 Standard Edition,
SDK 1.3, several of the AWT heavyweight Component
s
exhibited default drag behavior via the middle mouse button, even
if the application did not identify these Components
as DragSource
s via the java.awt.dnd API
.
These Component
s were implemented using Motif peers,
and Motif provides middle button drag behavior for these peers by
default.
Because of the design of the AWT, and because of bugs in the Motif library, this default behavior has been the source of numerous stability problems. Rather than continue to risk the stability of AWT and Drag & Drop for a niche feature, we have chosen to disable this feature explicitly in our implementations.
Developers can still identify these Component
s as
DragSource
s in their applications using the
java.awt.dnd API
. This is both functional and
supported. This approach is superior to relying upon default Motif
behavior in any case, because it enables drag support for these
Component
s on all platforms, not just Solaris and
Linux.
64-Bit Compliance on Solaris Machines
The bugtraq report that corresponds to this change is: 4295833.
64-bit Solaris applications use 64 bits to address memory instead of 32. This allows larger applications by providing a much larger virtual memory space. For this release, AWT has been brought up to 64-bit compliance. For more information, see here.
Inconsistent DLLs WarningThe bugtraq report that corresponds to this change is: 4414004.
If you have installed English VC++ 6.0 onto a machine that also
has Asian Windows NT installed, you may encounter strange artifacts
when rendering Asian text in the TextArea
component.
You may also see this problem if you have installed Microsoft
Exchange or Microsoft Office 97 onto a machine running Asian
Windows NT 4.0. Although this problem was reported on the Japanese
version of Windows NT, it will probably occur on other non-Latin
versions of NT as well, such as Chinese or Korean.
The problem was caused when the installation of those programs replaced the Asian Riched32.dll with the English version. The problem can be corrected by replacing Riched32.dll with the Asian version.
Removal of the Drawing Surface APIThe bugtraq report that corresponds to this change is: 4293646.
The sun.awt.DrawingSurface
API has been removed. It
was never made public, but some developers have been using it. The
functionality has been replaced by the JAWT. For more information,
see the AWT Native
Interface description.
The bugtraq report that corresponds to this change is: 4463949.
Xinerama-aware applications running on multi-headed systems have caused problems which have resulted in a variety of bug reports. Some multi-headed environments use monitors with little or no borders, which can be butted up against one another such that the resulting effect is one mammoth display. In this case, a "properly" centered window may span multiple screens. Other multi-headed environments use regular CRT monitors, with several inches of packaging between the actual display areas. In this case, a window spanning multiple screens produces a disconcerting effect, especially if the window cannot be dragged onto one monitor or the other (the Solaris login screen, for example). In short there was no way to tell where to center a window in a Xinerama environment.
To address this problem, the X group has added API which allows Xinerama users to specify where they want "centered" windows to be centered, and allows developers of Xinerama-aware applications to code accordingly.
Prior to this release, the way to center a window has been to
center it within the bounds of the default
GraphicsDevice
, like this:
bounds = getDefaultScreenDevice().getDefaultConfiguration().getBounds(); frame.setLocation(bounds / 2 - size of window / 2);This code would center the windows "correctly" on Xinerama systems where windows should be centered to the entire Xinerama coordinate space.
As of this release, post 4356756-fix JDKs will center windows "correctly" on Xinerama systems where windows should be centered within the first display.
To accomplish this, the
getCenterPoint
method has been added to GraphicsEnvironment
.
This method works as follows on various platforms:
getCenterPoint
returns the coordinates
of the center of the primary display.getCenterPoint
returns the center point of the primary
display.getCenterPoint
reflects their
value. Otherwise, it returns the point at the center of the virtual
coordinate space. (In practice, this will almost always be set -
CDE sets it by default.)As of JDK 1.4, the correct code for centering is:
frame.setLocation(getCenterPoint() - size of window / 2);
The other method added to GraphicsEnvironment
is
getMaximumWindowBounds
. Both
getCenterPoint
and getMaximumWindowBounds
throw a HeadlessException
when in Headless mode.
The bugtraq reports that corresponds to this change are: 4387938 and 4421515.
Previously, the InputEvent
modifiers had the same values for keyboard and mouse buttons. In
certain situations there was no way to distinguish which one was
pressed or when more than one was held simultaneously. These
situations included cases when more than one mouse button was down
at the same time, or when a modifier key was used to modify a mouse
event.
To address this deficiency, the following constants were added
to InputEvent
:
SHIFT_DOWN_MASK
CTRL_DOWN_MASK
META_DOWN_MASK
ALT_DOWN_MASK
ALT_GRAPH_DOWN_MASK
BUTTON1_DOWN_MASK
BUTTON2_DOWN_MASK
BUTTON3_DOWN_MASK
The following methods were added to InputEvent
:
The class spec for MouseEvent
was updated. The following constants were also added to
MouseEvent
:
These methods in MouseEvent
were added:
MouseEvent(Component source, int id, long when, int
modifiers, int x, int y, int clickCount, boolean popupTrigger, int
button)
getButton
getMouseModifiersText
DragSourceDragEvent
has the new method
getGestureModifiersEx
.
The bugtraq report that corresponds to this change is: 4462677.
The Choice
drop down menu behavior has changed from
JDK 1.3.1 to 1.4. In 1.3.1, you could click anywhere on the choice
bar and the menu would drop down. In 1.4, you must click on the
arrow selector on the right hand side of the Choice
bar. Clicking anywhere else on the Choice
bar has no
effect. Also, the symbol on the Choice
bar has changed
from a bar to an arrow/bar combination. Finally, if the drop down
menu extends outside of the parent, when clicking on that area, the
application underneath is brought to the foreground. This happens
on Solaris, not Windows.
The bugtraq report that corresponds to this change is: 4288285.
In releases prior to 1.4, the AWT Choice
widget
sometimes ignored the size that the layout manager told it to be.
As of this release, it now obeys the layout manager
constraints.
The bugtraq report that corresponds to this change is: 4476300.
The new focus subsystem, introduced in this release, introduced a new architecture and a new terminology for handling keyboard focus in sophisticated AWT and Swing applications. Prior to this project, many of the focus-related APIs were inconsistent in usage and termonology, were improperly documented, and led to poorly designed UIs. Now that the new architecture is in place, the most egregious of these APIs has been deprecated.
The following constants and methods have been deprecated:
javax.swing.FocusManager.FOCUS_MANAGER_CLASS_PROPERTY
javax.swing.FocusManager.disableSwingFocusManager()
javax.swing.FocusManager.isFocusManagerEnabled()
javax.swing.JComponent.requestDefaultFocus()
javax.swing.JComponent.isManagingFocus()
javax.swing.JComponent.setNextFocusableComponent(Component)
javax.swing.JComponent.getNextFocusableComponent()
java.awt.Component.isFocusTraversable()
java.awt.Component.hasFocus()
javax.swing.SwingUtilities.findFocusOwner(Component)
The bugtraq report that corresponds to this change is: 4434193.
The new focus architecture includes a type-ahead mechanism that
ensures that subsequent KeyEvent
s that follow a
KeyEvent
that initiates a focus transfer are not
delivered until the transfer is completed. The design for this
feature is based on the UTC timestamps of the various events.
Events with timestamps later than that of the initiating event are
enqueued pending resolution of the transfer; events with earlier
timestamps are not.
To implement this feature, the focus code keeps track of the
timestamp of the event currently being handled. If a focus change
is initiated during this handling, the timestamp is available for
use. However, if the current event does not have a timestamp, then
the current system time is used. This time is usually too far ahead
of the time that the event actually occurred to be of any real use.
As a result, the type-ahead mechanism fails, and
KeyEvent
s are delivered before the focus transfer is
completed.
The most common case where we encountered this problem was with
ActionEvent
s. ActionEvent
s are
high-level, semantic events generated in response to underlying
InputEvent
s. While the InputEvent
s had
timestamps associated with them, the ActionEvent
s did
not. The ActionEvent
API has therefore been expanded
to accomodate a timestamp and the implementation has been updated
so that an ActionEvent
's timestamp is equal to that of
its underlying InputEvent
.
The following methods have been added to ActionEvent
:
The following ActionEvent
methods were
modified:
ActionEvent(Object source, int id, String
command)
ActionEvent(Object source, int id, String command, int
modifiers)
The getWhen
method was added to InvocationEvent
.
The InvocationEvent
constructors
InvocationEvent(Object, Runnable)
and
InvocationEvent(Object, Runnable, Object, boolean)
were modified.
A new constructor
InputMethodEvent(Component, int, long,
AttributedCharacterIterator, int, TextHitInfo,
TextHitInfo)
was added to InputMethodEvent
,
as well as the
getWhen
method.
The following InputMethodEvent
constructors have
been modified:
InputMethodEvent(Component, int, AttributedCharacterIterator,
int, TextHitInfo, TextHitInfo)
InputMethodEvent(Component, int, TextHitInfo,
TextHitInfo)
.Finally, the following methods were added to EventQueue
: