Some more fixes for the focus system (the more I dig, the more problems
I find. It must have worked before by pure accident only). Here's a
summary of the changes:
- Lightweight components are not automatically focus-requested when a
mouse click on them is dispatched. Swing components that wish to have
such behaviour must implement it on their own. Fixes for some obvious
components (AbstractButton, JTextField) follow soon.
- The EventDispatchThread shouldn't dispatch the event to the keyboard
focus manager and then to dispatchEventImpl() too, because
dispatchEventImpl() also (rightly) dispatches the events to the keyboard
focus manager. I ripped this out of the event dispatch thread and fixed
it in Component.dispatchEventImpl.
- The peers only send focus gained events for heavyweight components,
even if the ComponentPeer.requestFocus() has a lightweight component
argument. The mapping to the correct lightweight happens right before
dispatching the event to the keyboard focus manager in
Component.dispatchEventImpl().
Note that this work is by far not yet complete. There's so much ugliness
left in the focus system. But the basics should work again. I've tested
it against the Swing Demo (needs some patches that follow immediately)
and the AWT demo and both seem to work wrt focus.
2006-07-26 Roman Kennke <[EMAIL PROTECTED]>
* gnu/java/awt/peer/gtk/GtkComponentPeer.java
(focusRequest): Removed field.
(postFocusEvent(int,boolean,Component)): Removed.
(postFocusEvent(int,boolean)): Reverted to post event using
the heavyweight component.
(requestFocus): Post focus event using the heavyweight
component.
* gnu/java/awt/peer/gtk/GtkWindowPeer.java
(requestFocus): Post focus event using the heavyweight
component.
* java/awt/AWTEvent.java
(isFocusManagerEvent): New field, indicating if this is
an event that is redispatched by the KeyboardFocusManager.
* java/awt/Component.java
(requestFocusImpl): Register component for
heavyweight->lightweight mapping.
(dispatchEventImpl): Retarget focus events before dispatching
to the KeyboardFocusManager. Use new AWTEvent flag instead
of locking hack. Dispatch all events through the
KeyboardFocusManager. Don't request focus on lightweight
components.
* java/awt/DefaultKeyboardFocusManager.java
(dispatchEvent): Pulled out handling of FOCUS_GAINED and
FOCUS_LOST.
(handleFocusGained): Fixed handling of temporary vs permanent
focus changes. Added some checks.
(handleFocusLost): Fixed handling of temporary vs permanent
focus changes. Added some checks.
* java/awt/EventDispatchThread.java
(run): Don't dispatch to KeyboardFocusManager here. This
is done in Component.dispatchEventImpl().
* java/awt/KeyboardFocusManager.java
(redispatchEvent): Use new AWTEvent flag instead of locking hack.
(focusRequests): New field.
(retargetFocusEvent): New method. Retargets focus events
that come from heavyweights to the correct lightweight component.
(addLightweightFocusRequest): New method. Stores a mapping
for later retargetting of heavyweight focus events.
* java/awt/Window.java
(addFocusListener): Removed bogus method. If at all, this
should be performed in the KeyboardFocusManager.
(Window): Don't install a focus listener on the Window.
/Roman
Index: gnu/java/awt/peer/gtk/GtkComponentPeer.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java,v
retrieving revision 1.118
diff -u -1 -2 -r1.118 GtkComponentPeer.java
--- gnu/java/awt/peer/gtk/GtkComponentPeer.java 25 Jul 2006 22:41:46 -0000 1.118
+++ gnu/java/awt/peer/gtk/GtkComponentPeer.java 26 Jul 2006 19:08:41 -0000
@@ -81,31 +81,24 @@
import java.util.TimerTask;
public class GtkComponentPeer extends GtkGenericPeer
implements ComponentPeer
{
VolatileImage backBuffer;
BufferCapabilities caps;
Component awtComponent;
Insets insets;
- /**
- * Stores the actually requested focus component. This is used in
- * [EMAIL PROTECTED] #postFocusEvent(int, boolean)} to determine the actual component
- * which received focus.
- */
- private Component focusRequest;
-
/* this isEnabled differs from Component.isEnabled, in that it
knows if a parent is disabled. In that case Component.isEnabled
may return true, but our isEnabled will always return false */
native boolean isEnabled ();
static native boolean modalHasGrab();
native int[] gtkWidgetGetForeground ();
native int[] gtkWidgetGetBackground ();
native void gtkWidgetGetDimensions (int[] dim);
native void gtkWidgetGetPreferredDimensions (int[] dim);
native void gtkWindowGetLocationOnScreen (int[] point);
native void gtkWidgetGetLocationOnScreen (int[] point);
@@ -631,38 +624,33 @@
{
q.postEvent(keyEvent);
keyEvent = new KeyEvent(awtComponent, KeyEvent.KEY_TYPED, when,
mods, KeyEvent.VK_UNDEFINED, keyChar,
keyLocation);
q.postEvent(keyEvent);
}
}
else
q.postEvent(keyEvent);
}
- protected void postFocusEvent (int id, boolean temporary, Component target)
- {
- q().postEvent (new FocusEvent (target, id, temporary));
- }
-
/**
* Referenced from native code.
*
* @param id
* @param temporary
*/
protected void postFocusEvent (int id, boolean temporary)
{
- postFocusEvent(id, temporary, focusRequest);
+ q().postEvent (new FocusEvent (awtComponent, id, temporary));
}
protected void postItemEvent (Object item, int stateChange)
{
q().postEvent (new ItemEvent ((ItemSelectable)awtComponent,
ItemEvent.ITEM_STATE_CHANGED,
item, stateChange));
}
protected void postTextEvent ()
{
q().postEvent (new TextEvent (awtComponent, TextEvent.TEXT_VALUE_CHANGED));
@@ -696,42 +684,41 @@
KeyboardFocusManager kfm =
KeyboardFocusManager.getCurrentKeyboardFocusManager();
Component currentFocus = kfm.getFocusOwner();
if (currentFocus == request)
// Nothing to do in this trivial case.
retval = true;
else
{
// Requested component is a lightweight descendant of this one
// or the actual heavyweight.
// Since this (native) component is already focused, we simply
// change the actual focus and be done.
- postFocusEvent(FocusEvent.FOCUS_GAINED, temporary, request);
+ postFocusEvent(FocusEvent.FOCUS_GAINED, temporary);
retval = true;
}
}
else
{
if (gtkWidgetCanFocus())
{
if (allowWindowFocus)
{
Window window = getWindowFor(request);
GtkWindowPeer wPeer = (GtkWindowPeer) window.getPeer();
if (! wPeer.gtkWindowHasFocus())
wPeer.requestWindowFocus();
}
// Store requested focus component so that the corresponding
// event is dispatched correctly.
- focusRequest = request;
gtkWidgetRequestFocus();
retval = true;
}
}
return retval;
}
private Window getWindowFor(Component c)
{
Component comp = c;
while (! (comp instanceof Window))
comp = comp.getParent();
Index: gnu/java/awt/peer/gtk/GtkWindowPeer.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java,v
retrieving revision 1.51
diff -u -1 -2 -r1.51 GtkWindowPeer.java
--- gnu/java/awt/peer/gtk/GtkWindowPeer.java 25 Jul 2006 22:41:46 -0000 1.51
+++ gnu/java/awt/peer/gtk/GtkWindowPeer.java 26 Jul 2006 19:08:42 -0000
@@ -315,25 +315,25 @@
KeyboardFocusManager kfm =
KeyboardFocusManager.getCurrentKeyboardFocusManager();
Component currentFocus = kfm.getFocusOwner();
if (currentFocus == request)
// Nothing to do in this trivial case.
retval = true;
else
{
// Requested component is a lightweight descendant of this one
// or the actual heavyweight.
// Since this (native) component is already focused, we simply
// change the actual focus and be done.
- postFocusEvent(FocusEvent.FOCUS_GAINED, temporary, request);
+ postFocusEvent(FocusEvent.FOCUS_GAINED, temporary);
retval = true;
}
}
else
{
if (allowWindowFocus)
{
retval = requestWindowFocus();
}
}
return retval;
}
Index: java/awt/AWTEvent.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/AWTEvent.java,v
retrieving revision 1.17
diff -u -1 -2 -r1.17 AWTEvent.java
--- java/awt/AWTEvent.java 23 Feb 2006 23:43:51 -0000 1.17
+++ java/awt/AWTEvent.java 26 Jul 2006 19:08:42 -0000
@@ -94,24 +94,29 @@
* @see #isConsumed()
* @serial whether the event has been consumed
*/
protected boolean consumed;
/**
* Who knows? It's in the serial version.
*
* @serial No idea what this is for.
*/
byte[] bdata;
+ /**
+ * Indicates if this event is dispatched by the KeyboardFocusManager.
+ */
+ boolean isFocusManagerEvent = false;
+
/** Mask for selecting component events. */
public static final long COMPONENT_EVENT_MASK = 0x00001;
/** Mask for selecting container events. */
public static final long CONTAINER_EVENT_MASK = 0x00002;
/** Mask for selecting component focus events. */
public static final long FOCUS_EVENT_MASK = 0x00004;
/** Mask for selecting keyboard events. */
public static final long KEY_EVENT_MASK = 0x00008;
Index: java/awt/Component.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/Component.java,v
retrieving revision 1.137
diff -u -1 -2 -r1.137 Component.java
--- java/awt/Component.java 25 Jul 2006 22:41:46 -0000 1.137
+++ java/awt/Component.java 26 Jul 2006 19:08:44 -0000
@@ -4348,24 +4348,32 @@
Component heavyweightParent = this;
while (heavyweightParent.peer instanceof LightweightPeer)
heavyweightParent = heavyweightParent.parent;
// Don't allow focus on lightweight components without
// visible heavyweight ancestor
if (heavyweightParent != null && heavyweightParent.isVisible())
{
// Don't allow focus when heavyweightParent has no peer.
myPeer = heavyweightParent.peer;
if (myPeer != null)
{
+ // Register lightweight focus request.
+ if (heavyweightParent != this)
+ {
+ KeyboardFocusManager
+ .addLightweightFocusRequest(heavyweightParent,
+ this);
+ }
+
// Try to focus the component.
long time = EventQueue.getMostRecentEventTime();
boolean success = myPeer.requestFocus(this, temporary,
focusWindow,
time);
if (! success)
{
// Dequeue key events if focus request failed.
KeyboardFocusManager kfm =
KeyboardFocusManager.getCurrentKeyboardFocusManager();
kfm.dequeueKeyEvents(time, this);
}
@@ -5358,70 +5366,44 @@
* Implementation of dispatchEvent. Allows trusted package classes
* to dispatch additional events first. This implementation first
* translates <code>e</code> to an AWT 1.0 event and sends the
* result to [EMAIL PROTECTED] #postEvent}. If the AWT 1.0 event is not
* handled, and events of type <code>e</code> are enabled for this
* component, e is passed on to [EMAIL PROTECTED] #processEvent}.
*
* @param e the event to dispatch
*/
void dispatchEventImpl(AWTEvent e)
{
- // This boolean tells us not to process focus events when the focus
- // opposite component is the same as the focus component.
- boolean ignoreFocus =
- (e instanceof FocusEvent &&
- ((FocusEvent)e).getComponent() == ((FocusEvent)e).getOppositeComponent());
-
- if (eventTypeEnabled (e.id))
+ // Retarget focus events before dispatching it to the KeyboardFocusManager
+ // in order to handle lightweight components properly.
+ boolean dispatched = false;
+ if (! e.isFocusManagerEvent)
{
- if (e.id != PaintEvent.PAINT && e.id != PaintEvent.UPDATE
- && !ignoreFocus)
- processEvent(e);
-
- // the trick we use to communicate between dispatch and redispatch
- // is to have KeyboardFocusManager.redispatch synchronize on the
- // object itself. we then do not redispatch to KeyboardFocusManager
- // if we are already holding the lock.
- if (! Thread.holdsLock(e))
+ e = KeyboardFocusManager.retargetFocusEvent(e);
+ dispatched = KeyboardFocusManager.getCurrentKeyboardFocusManager()
+ .dispatchEvent(e);
+ }
+
+ if (! dispatched)
+ {
+ if (eventTypeEnabled (e.id))
{
- switch (e.id)
- {
- case WindowEvent.WINDOW_GAINED_FOCUS:
- case WindowEvent.WINDOW_LOST_FOCUS:
- case KeyEvent.KEY_PRESSED:
- case KeyEvent.KEY_RELEASED:
- case KeyEvent.KEY_TYPED:
- case FocusEvent.FOCUS_GAINED:
- case FocusEvent.FOCUS_LOST:
- if (KeyboardFocusManager
- .getCurrentKeyboardFocusManager()
- .dispatchEvent(e))
- return;
- case MouseEvent.MOUSE_PRESSED:
- // A mouse click on an enabled lightweight component
- // which has not yet been marked as consumed by any
- // other mouse listener results in a focus traversal
- // to that component.
- if (isLightweight()
- && isEnabled() && !e.isConsumed())
- requestFocus();
- break;
- }
+ if (e.id != PaintEvent.PAINT && e.id != PaintEvent.UPDATE)
+ processEvent(e);
}
+ if (peer != null)
+ peer.handleEvent(e);
}
-
- if (peer != null)
- peer.handleEvent(e);
}
/**
* Tells whether or not an event type is enabled.
*/
boolean eventTypeEnabled (int type)
{
if (type > AWTEvent.RESERVED_ID_MAX)
return true;
switch (type)
{
Index: java/awt/DefaultKeyboardFocusManager.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/DefaultKeyboardFocusManager.java,v
retrieving revision 1.21
diff -u -1 -2 -r1.21 DefaultKeyboardFocusManager.java
--- java/awt/DefaultKeyboardFocusManager.java 26 Jul 2006 11:14:47 -0000 1.21
+++ java/awt/DefaultKeyboardFocusManager.java 26 Jul 2006 19:08:45 -0000
@@ -173,77 +173,33 @@
else if (e.id != WindowEvent.WINDOW_LOST_FOCUS
&& e.id != WindowEvent.WINDOW_DEACTIVATED)
return false;
redispatchEvent(target, e);
return true;
}
else if (e instanceof FocusEvent)
{
FocusEvent fe = (FocusEvent) e;
Component target = fe.getComponent ();
+ boolean retval = false;
if (e.id == FocusEvent.FOCUS_GAINED)
{
- // If old focus owner != new focus owner, notify old focus
- // owner that it has lost focus.
- Component oldFocusOwner = getGlobalFocusOwner();
- if (oldFocusOwner != null && oldFocusOwner != target)
- {
- FocusEvent lost = new FocusEvent(oldFocusOwner,
- FocusEvent.FOCUS_LOST,
- fe.isTemporary(), target);
- oldFocusOwner.dispatchEvent(lost);
- }
- if (! (target instanceof Window))
- {
- if (((FocusEvent) e).isTemporary ())
- setGlobalFocusOwner (target);
- else
- setGlobalPermanentFocusOwner (target);
- }
-
- // Keep track of this window's focus owner.
-
- // Find the target Component's top-level ancestor. target
- // may be a window.
- Container parent = target.getParent ();
-
- while (parent != null
- && !(parent instanceof Window))
- parent = parent.getParent ();
-
- // If the parent is null and target is not a window, then target is an
- // unanchored component and so we don't want to set the focus owner.
- if (! (parent == null && ! (target instanceof Window)))
- {
- Window toplevel = parent == null ?
- (Window) target : (Window) parent;
-
- Component focusOwner = getFocusOwner ();
- if (focusOwner != null
- && ! (focusOwner instanceof Window))
- toplevel.setFocusOwner (focusOwner);
- }
+ retval = handleFocusGained(fe);
}
else if (e.id == FocusEvent.FOCUS_LOST)
{
- if (((FocusEvent) e).isTemporary ())
- setGlobalFocusOwner (null);
- else
- setGlobalPermanentFocusOwner (null);
+ retval = handleFocusLost(fe);
}
-
- redispatchEvent(target, e);
-
return true;
}
else if (e instanceof KeyEvent)
{
// Loop through all registered KeyEventDispatchers, giving
// each a chance to handle this event.
Iterator i = getKeyEventDispatchers().iterator();
while (i.hasNext ())
{
KeyEventDispatcher dispatcher = (KeyEventDispatcher) i.next ();
if (dispatcher.dispatchKeyEvent ((KeyEvent) e))
@@ -264,24 +220,113 @@
// This event was enqueued for dispatch at a later time.
return true;
else
// This event wasn't handled by any of the registered
// KeyEventDispatchers, and wasn't enqueued for dispatch
// later, so send it to the default dispatcher.
return dispatchKeyEvent ((KeyEvent) e);
}
return false;
}
+ /**
+ * Handles FOCUS_GAINED events in [EMAIL PROTECTED] #dispatchEvent(AWTEvent)}.
+ *
+ * @param fe the focus event
+ */
+ private boolean handleFocusGained(FocusEvent fe)
+ {
+ Component target = fe.getComponent ();
+
+ // If old focus owner != new focus owner, notify old focus
+ // owner that it has lost focus.
+ Component oldFocusOwner = getGlobalFocusOwner();
+ if (oldFocusOwner != null && oldFocusOwner != target)
+ {
+ FocusEvent lost = new FocusEvent(oldFocusOwner,
+ FocusEvent.FOCUS_LOST,
+ fe.isTemporary(), target);
+ oldFocusOwner.dispatchEvent(lost);
+ }
+
+ setGlobalFocusOwner (target);
+ if (target != getGlobalFocusOwner())
+ {
+ // Focus transfer was rejected, like when the target is not
+ // focusable.
+ dequeueKeyEvents(-1, target);
+ // FIXME: Restore focus somehow.
+ }
+ else
+ {
+ if (! fe.isTemporary())
+ {
+ setGlobalPermanentFocusOwner (target);
+ if (target != getGlobalPermanentFocusOwner())
+ {
+ // Focus transfer was rejected, like when the target is not
+ // focusable.
+ dequeueKeyEvents(-1, target);
+ // FIXME: Restore focus somehow.
+ }
+ else
+ {
+ redispatchEvent(target, fe);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Handles FOCUS_LOST events for [EMAIL PROTECTED] #dispatchEvent(AWTEvent)}.
+ *
+ * @param fe the focus event
+ *
+ * @return if the event has been handled
+ */
+ private boolean handleFocusLost(FocusEvent fe)
+ {
+ Component currentFocus = getGlobalFocusOwner();
+ if (currentFocus != fe.getOppositeComponent())
+ {
+ setGlobalFocusOwner(null);
+ if (getGlobalFocusOwner() != null)
+ {
+ // TODO: Is this possible? If so, then we should try to restore
+ // the focus.
+ }
+ else
+ {
+ if (! fe.isTemporary())
+ {
+ setGlobalPermanentFocusOwner(null);
+ if (getGlobalPermanentFocusOwner() != null)
+ {
+ // TODO: Is this possible? If so, then we should try to
+ // restore the focus.
+ }
+ else
+ {
+ fe.setSource(currentFocus);
+ redispatchEvent(currentFocus, fe);
+ }
+ }
+ }
+ }
+ return true;
+ }
+
private boolean enqueueKeyEvent (KeyEvent e)
{
Iterator i = delayRequests.iterator ();
boolean oneEnqueued = false;
while (i.hasNext ())
{
EventDelayRequest request = (EventDelayRequest) i.next ();
if (e.getWhen () > request.timestamp)
{
request.enqueueEvent (e);
oneEnqueued = true;
}
Index: java/awt/EventDispatchThread.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/EventDispatchThread.java,v
retrieving revision 1.10
diff -u -1 -2 -r1.10 EventDispatchThread.java
--- java/awt/EventDispatchThread.java 10 May 2006 10:15:43 -0000 1.10
+++ java/awt/EventDispatchThread.java 26 Jul 2006 19:08:45 -0000
@@ -73,35 +73,25 @@
// Ignore and use default.
}
setPriority(priority);
}
public void run()
{
while (true)
{
try
{
AWTEvent evt = queue.getNextEvent();
-
- KeyboardFocusManager manager;
- manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
-
- // Try to dispatch this event to the current keyboard focus
- // manager. It will dispatch all FocusEvents, all
- // WindowEvents related to focus, and all KeyEvents,
- // returning true. Otherwise, it returns false and we
- // dispatch the event normally.
- if (!manager.dispatchEvent (evt))
- queue.dispatchEvent(evt);
+ queue.dispatchEvent(evt);
}
catch (ThreadDeath death)
{
// If someone wants to kill us, let them.
return;
}
catch (InterruptedException ie)
{
// We are interrupted when we should finish executing
return;
}
catch (Throwable x)
Index: java/awt/KeyboardFocusManager.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/KeyboardFocusManager.java,v
retrieving revision 1.17
diff -u -1 -2 -r1.17 KeyboardFocusManager.java
--- java/awt/KeyboardFocusManager.java 28 Oct 2005 16:41:16 -0000 1.17
+++ java/awt/KeyboardFocusManager.java 26 Jul 2006 19:08:46 -0000
@@ -1096,29 +1096,27 @@
* <br />
* <strong>
* This method is not intended for general consumption, and is
* only for the use of the aforementioned classes.
* </strong>
*
* @param target the target component to which the event is
* dispatched.
* @param e the event to dispatch.
*/
public final void redispatchEvent (Component target, AWTEvent e)
{
- synchronized (e)
- {
- e.setSource (target);
- target.dispatchEvent (e);
- }
+ e.isFocusManagerEvent = true;
+ target.dispatchEvent (e);
+ e.isFocusManagerEvent = false;
}
/**
* Attempts to dispatch key events for which no key event dispatcher
* has so far succeeded. This method is usually called by
* <code>dispatchEvent()</code> following the sending of the key
* event to any registered key event dispatchers. If the key
* event reaches this stage, none of the dispatchers returned
* true. This is, of course, always the case if there are no
* registered dispatchers.
* <br />
* <br />
@@ -1427,13 +1425,57 @@
firePropertyChange (property, oldObject, newObject);
try
{
fireVetoableChange (property, oldObject, newObject);
// Set new object.
globalMap.put (currentGroup, newObject);
}
catch (PropertyVetoException e)
{
}
}
}
+
+
+ /**
+ * Maps focus requests from heavyweight to lightweight components.
+ */
+ private static HashMap focusRequests = new HashMap();
+
+ /**
+ * Retargets focus events that come from the peer (which only know about
+ * heavyweight components) to go to the correct lightweight component
+ * if appropriate.
+ *
+ * @param ev the event to check
+ *
+ * @return the retargetted event
+ */
+ static AWTEvent retargetFocusEvent(AWTEvent ev)
+ {
+ if (ev instanceof FocusEvent)
+ {
+ FocusEvent fe = (FocusEvent) ev;
+ Component target = fe.getComponent();
+ if (focusRequests.containsKey(target))
+ {
+ Component lightweight = (Component) focusRequests.get(target);
+ ev = new FocusEvent(lightweight, fe.id, fe.isTemporary());
+ focusRequests.remove(target);
+ }
+ }
+ return ev;
+ }
+
+ /**
+ * Adds a lightweight focus request for a heavyweight component.
+ *
+ * @param heavyweight the heavyweight from which we will receive a focus
+ * event soon
+ * @param lightweight the lightweight that ultimately receives the request
+ */
+ static void addLightweightFocusRequest(Component heavyweight,
+ Component lightweight)
+ {
+ focusRequests.put(heavyweight, lightweight);
+ }
}
Index: java/awt/Window.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/Window.java,v
retrieving revision 1.73
diff -u -1 -2 -r1.73 Window.java
--- java/awt/Window.java 15 Jul 2006 08:02:23 -0000 1.73
+++ java/awt/Window.java 26 Jul 2006 19:08:46 -0000
@@ -30,26 +30,24 @@
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.awt;
import java.awt.event.ComponentEvent;
-import java.awt.event.FocusEvent;
-import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.awt.image.BufferStrategy;
import java.awt.peer.WindowPeer;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.EventListener;
import java.util.Iterator;
import java.util.Locale;
import java.util.ResourceBundle;
@@ -123,97 +121,35 @@
* This (package access) constructor is used by subclasses that want
* to build windows that do not have parents. Eg. toplevel
* application frames. Subclasses cannot call super(null), since
* null is an illegal argument.
*/
Window()
{
visible = false;
// Windows are the only Containers that default to being focus
// cycle roots.
focusCycleRoot = true;
setLayout(new BorderLayout());
- addWindowFocusListener();
GraphicsEnvironment g = GraphicsEnvironment.getLocalGraphicsEnvironment();
graphicsConfiguration = g.getDefaultScreenDevice().getDefaultConfiguration();
}
Window(GraphicsConfiguration gc)
{
this();
graphicsConfiguration = gc;
}
- private void addWindowFocusListener()
- {
- addWindowFocusListener(new WindowAdapter()
- {
- public void windowGainedFocus(WindowEvent event)
- {
- EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
- if (windowFocusOwner != null)
- {
- synchronized (eq)
- {
- KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
- Component currentFocusOwner = manager.getGlobalPermanentFocusOwner();
- if (currentFocusOwner != null)
- {
- eq.postEvent(new FocusEvent(currentFocusOwner,
- FocusEvent.FOCUS_LOST, false,
- windowFocusOwner));
- eq.postEvent(new FocusEvent(windowFocusOwner,
- FocusEvent.FOCUS_GAINED, false,
- currentFocusOwner));
- }
- else
- eq.postEvent(new FocusEvent(windowFocusOwner,
- FocusEvent.FOCUS_GAINED, false));
- }
- }
- else
- eq.postEvent(new FocusEvent(Window.this, FocusEvent.FOCUS_GAINED,
- false));
- }
-
- public void windowLostFocus(WindowEvent event)
- {
- EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
- if (windowFocusOwner != null)
- {
- synchronized (eq)
- {
- KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
- Component currentFocusOwner = manager.getGlobalPermanentFocusOwner();
- if (currentFocusOwner != null)
- {
- eq.postEvent(new FocusEvent(currentFocusOwner,
- FocusEvent.FOCUS_GAINED, false,
- windowFocusOwner));
- eq.postEvent(new FocusEvent(windowFocusOwner,
- FocusEvent.FOCUS_LOST, false,
- currentFocusOwner));
- }
- else
- eq.postEvent(new FocusEvent(windowFocusOwner,
- FocusEvent.FOCUS_LOST, false));
- }
- }
- else
- eq.postEvent(new FocusEvent(Window.this, FocusEvent.FOCUS_LOST, false));
- }
- });
- }
-
/**
* Initializes a new instance of <code>Window</code> with the specified
* parent. The window will initially be invisible.
*
* @param owner The owning <code>Frame</code> of this window.
*
* @exception IllegalArgumentException If the owner's GraphicsConfiguration
* is not from a screen device, or if owner is null; this exception is always
* thrown when GraphicsEnvironment.isHeadless returns true.
*/
public Window(Frame owner)
{