DefaultKeyboardFocusManager.java [plain text]
package java.awt;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
public class DefaultKeyboardFocusManager extends KeyboardFocusManager
{
private class EventDelayRequest implements Comparable
{
private LinkedList enqueuedKeyEvents = new LinkedList ();
public long timestamp;
public Component focusedComp;
public EventDelayRequest (long timestamp, Component focusedComp)
{
this.timestamp = timestamp;
this.focusedComp = focusedComp;
}
public int compareTo (Object o)
{
if (!(o instanceof EventDelayRequest))
throw new ClassCastException ();
EventDelayRequest request = (EventDelayRequest) o;
if (request.timestamp < timestamp)
return -1;
else if (request.timestamp == timestamp)
return 0;
else
return 1;
}
public boolean equals (Object o)
{
if (!(o instanceof EventDelayRequest) || o == null)
return false;
EventDelayRequest request = (EventDelayRequest) o;
return (request.timestamp == timestamp
&& request.focusedComp == focusedComp);
}
public void enqueueEvent (KeyEvent e)
{
KeyEvent last = (KeyEvent) enqueuedKeyEvents.getLast ();
if (last != null && e.getWhen () < last.getWhen ())
throw new RuntimeException ("KeyEvents enqueued out-of-order");
if (e.getWhen () <= timestamp)
throw new RuntimeException ("KeyEvents enqueued before starting timestamp");
enqueuedKeyEvents.add (e);
}
public void dispatchEvents ()
{
int size = enqueuedKeyEvents.size ();
for (int i = 0; i < size; i++)
{
KeyEvent e = (KeyEvent) enqueuedKeyEvents.remove (0);
dispatchKeyEvent (e);
}
}
public void discardEvents ()
{
enqueuedKeyEvents.clear ();
}
}
private SortedSet delayRequests = new TreeSet ();
public DefaultKeyboardFocusManager ()
{
}
public boolean dispatchEvent (AWTEvent e)
{
if (e instanceof WindowEvent)
{
Window target = (Window) e.getSource ();
if (e.id == WindowEvent.WINDOW_ACTIVATED)
setGlobalActiveWindow (target);
else if (e.id == WindowEvent.WINDOW_GAINED_FOCUS)
setGlobalFocusedWindow (target);
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)
{
Component target = (Component) e.getSource ();
if (e.id == FocusEvent.FOCUS_GAINED)
{
if (! (target instanceof Window))
{
if (((FocusEvent) e).isTemporary ())
setGlobalFocusOwner (target);
else
setGlobalPermanentFocusOwner (target);
}
Container parent = target.getParent ();
while (parent != null
&& !(parent instanceof Window))
parent = parent.getParent ();
Window toplevel = parent == null ?
(Window) target : (Window) parent;
Component focusOwner = getFocusOwner ();
if (focusOwner != null
&& ! (focusOwner instanceof Window))
toplevel.setFocusOwner (focusOwner);
}
else if (e.id == FocusEvent.FOCUS_LOST)
{
if (((FocusEvent) e).isTemporary ())
setGlobalFocusOwner (null);
else
setGlobalPermanentFocusOwner (null);
}
redispatchEvent(target, e);
return true;
}
else if (e instanceof KeyEvent)
{
Iterator i = getKeyEventDispatchers().iterator();
while (i.hasNext ())
{
KeyEventDispatcher dispatcher = (KeyEventDispatcher) i.next ();
if (dispatcher.dispatchKeyEvent ((KeyEvent) e))
return true;
}
Component focusOwner = getGlobalPermanentFocusOwner ();
if (focusOwner != null)
processKeyEvent (focusOwner, (KeyEvent) e);
if (e.isConsumed ())
return true;
if (enqueueKeyEvent ((KeyEvent) e))
return true;
else
return dispatchKeyEvent ((KeyEvent) e);
}
return false;
}
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;
}
}
return oneEnqueued;
}
public boolean dispatchKeyEvent (KeyEvent e)
{
Component focusOwner = getGlobalPermanentFocusOwner ();
if (focusOwner != null)
redispatchEvent(focusOwner, e);
Iterator i = getKeyEventPostProcessors().iterator();
while (i.hasNext ())
{
KeyEventPostProcessor processor = (KeyEventPostProcessor) i.next ();
if (processor.postProcessKeyEvent ((KeyEvent) e))
return true;
}
if (postProcessKeyEvent (e))
return true;
return true;
}
public boolean postProcessKeyEvent (KeyEvent e)
{
int modifiers = e.getModifiersEx ();
if (e.getID() == KeyEvent.KEY_PRESSED
&& (modifiers & KeyEvent.CTRL_DOWN_MASK) != 0)
{
Window focusedWindow = getGlobalFocusedWindow ();
if (focusedWindow instanceof Frame)
{
MenuBar menubar = ((Frame) focusedWindow).getMenuBar ();
if (menubar != null)
{
int numMenus = menubar.getMenuCount ();
for (int i = 0; i < numMenus; i++)
{
Menu menu = menubar.getMenu (i);
int numItems = menu.getItemCount ();
for (int j = 0; j < numItems; j++)
{
MenuItem item = menu.getItem (j);
MenuShortcut shortcut = item.getShortcut ();
if (item.isEnabled() && shortcut != null)
{
if (shortcut.getKey () == e.getKeyCode ()
&& ((shortcut.usesShiftModifier ()
&& (modifiers & KeyEvent.SHIFT_DOWN_MASK) != 0)
|| (! shortcut.usesShiftModifier ()
&& (modifiers & KeyEvent.SHIFT_DOWN_MASK) == 0)))
{
item.dispatchEvent (new ActionEvent (item,
ActionEvent.ACTION_PERFORMED,
item.getActionCommand (),
modifiers));
return true;
}
}
}
}
}
}
}
return false;
}
public void processKeyEvent (Component comp, KeyEvent e)
{
AWTKeyStroke eventKeystroke = AWTKeyStroke.getAWTKeyStrokeForEvent (e);
AWTKeyStroke oppositeKeystroke = AWTKeyStroke.getAWTKeyStroke (e.getKeyCode (),
e.getModifiersEx (),
!(e.id == KeyEvent.KEY_RELEASED));
Set forwardKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
Set backwardKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
Set upKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
Set downKeystrokes = null;
if (comp instanceof Container)
downKeystrokes = comp.getFocusTraversalKeys (KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS);
if (forwardKeystrokes.contains (eventKeystroke))
{
focusNextComponent (comp);
e.consume ();
}
else if (backwardKeystrokes.contains (eventKeystroke))
{
focusPreviousComponent (comp);
e.consume ();
}
else if (upKeystrokes.contains (eventKeystroke))
{
upFocusCycle (comp);
e.consume ();
}
else if (comp instanceof Container
&& downKeystrokes.contains (eventKeystroke))
{
downFocusCycle ((Container) comp);
e.consume ();
}
else if (forwardKeystrokes.contains (oppositeKeystroke)
|| backwardKeystrokes.contains (oppositeKeystroke)
|| upKeystrokes.contains (oppositeKeystroke)
|| (comp instanceof Container &&
downKeystrokes.contains (oppositeKeystroke)))
e.consume ();
}
protected void enqueueKeyEvents (long after, Component untilFocused)
{
delayRequests.add (new EventDelayRequest (after, untilFocused));
}
protected void dequeueKeyEvents (long after, Component untilFocused)
{
if (after < 0)
{
int size = delayRequests.size ();
if (size > 0)
delayRequests.remove (delayRequests.first ());
}
else
{
EventDelayRequest template = new EventDelayRequest (after, untilFocused);
if (delayRequests.contains (template))
{
EventDelayRequest actual = (EventDelayRequest) delayRequests.tailSet (template).first ();
delayRequests.remove (actual);
actual.dispatchEvents ();
}
}
}
protected void discardKeyEvents (Component comp)
{
Iterator i = delayRequests.iterator ();
while (i.hasNext ())
{
EventDelayRequest request = (EventDelayRequest) i.next ();
if (request.focusedComp == comp
|| (comp instanceof Container
&& ((Container) comp).isAncestorOf (request.focusedComp)))
request.discardEvents ();
}
}
public void focusPreviousComponent (Component comp)
{
Component focusComp = (comp == null) ? getGlobalFocusOwner () : comp;
Container focusCycleRoot = focusComp.getFocusCycleRootAncestor ();
FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy ();
Component previous = policy.getComponentBefore (focusCycleRoot, focusComp);
if (previous != null)
previous.requestFocusInWindow ();
}
public void focusNextComponent (Component comp)
{
Component focusComp = (comp == null) ? getGlobalFocusOwner () : comp;
Container focusCycleRoot = focusComp.getFocusCycleRootAncestor ();
FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy ();
Component next = policy.getComponentAfter (focusCycleRoot, focusComp);
if (next != null)
next.requestFocusInWindow ();
}
public void upFocusCycle (Component comp)
{
Component focusComp = (comp == null) ? getGlobalFocusOwner () : comp;
Container focusCycleRoot = focusComp.getFocusCycleRootAncestor ();
if (focusCycleRoot instanceof Window)
{
FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy ();
Component defaultComponent = policy.getDefaultComponent (focusCycleRoot);
if (defaultComponent != null)
defaultComponent.requestFocusInWindow ();
}
else
{
Container parentFocusCycleRoot = focusCycleRoot.getFocusCycleRootAncestor ();
focusCycleRoot.requestFocusInWindow ();
setGlobalCurrentFocusCycleRoot (parentFocusCycleRoot);
}
}
public void downFocusCycle (Container cont)
{
if (cont == null)
return;
if (cont.isFocusCycleRoot (cont))
{
FocusTraversalPolicy policy = cont.getFocusTraversalPolicy ();
Component defaultComponent = policy.getDefaultComponent (cont);
if (defaultComponent != null)
defaultComponent.requestFocusInWindow ();
setGlobalCurrentFocusCycleRoot (cont);
}
}
}