Updated key event processing to let client code have the event before

the docking action system
This commit is contained in:
dragonmacher 2025-04-21 16:09:15 -04:00
parent 5a2957ff2a
commit f57c6f64ac

View file

@ -139,6 +139,14 @@ public class KeyBindingOverrideKeyEventDispatcher implements KeyEventDispatcher
return false; return false;
} }
// Let client programming have the first chance to process the event. Any key listeners and
// actions registered on the focused component are allowed to process the event before our
// action system. This allows clients to perform custom event processing without the action
// system interfering.
if (processComponentKeyListeners(event) || processInputAndActionMaps(event)) {
return true;
}
if (!executableAction.isValid()) { if (!executableAction.isValid()) {
// The action is not currently valid for the given focus owner. Let all key strokes go // The action is not currently valid for the given focus owner. Let all key strokes go
// to Java when we have no valid context. This allows keys like Escape to work on Java // to Java when we have no valid context. This allows keys like Escape to work on Java
@ -147,10 +155,10 @@ public class KeyBindingOverrideKeyEventDispatcher implements KeyEventDispatcher
} }
if (!executableAction.isEnabled()) { if (!executableAction.isEnabled()) {
// The action is valid, but is not enabled. In this case, we do not want Java to get // The action is valid, but is not enabled. At this point we know that the focused
// the event. Instead, let the user know that they cannot perform the requested action. // component has no key listeners interested in this event and that the focused
// We keep the action from Java in this case to keep the event processing consistent // component has not action bindings either. Stop all further processing for this
// whether or not the action is enabled. // event to maintain predictable behavior.
executableAction.reportNotEnabled(focusOwner); executableAction.reportNotEnabled(focusOwner);
return true; return true;
} }
@ -160,8 +168,8 @@ public class KeyBindingOverrideKeyEventDispatcher implements KeyEventDispatcher
// Finally, if the exception statement is reached, then someone has added a new level // Finally, if the exception statement is reached, then someone has added a new level
// of precedence that this algorithm has not taken into account! // of precedence that this algorithm has not taken into account!
// @formatter:off // @formatter:off
return processKeyListenerPrecedence(executableAction, event) || return processActionAtPrecedence(KeyListenerLevel, executableAction, event) ||
processComponentActionMapPrecedence(executableAction, event) || processActionAtPrecedence(ActionMapLevel, executableAction, event) ||
processActionAtPrecedence(DefaultLevel, executableAction, event) || processActionAtPrecedence(DefaultLevel, executableAction, event) ||
throwAssertException(); throwAssertException();
// @formatter:on // @formatter:on
@ -324,34 +332,6 @@ public class KeyBindingOverrideKeyEventDispatcher implements KeyEventDispatcher
return true; return true;
} }
private boolean processKeyListenerPrecedence(ExecutableAction action, KeyEvent e) {
if (processActionAtPrecedence(KeyBindingPrecedence.KeyListenerLevel,
action, e)) {
return true;
}
// O.K., there is an action for the KeyStroke, but before we process it, we have to
// check the proper ordering of key events (see method JavaDoc)
if (processComponentKeyListeners(e)) {
return true;
}
return false;
}
private boolean processComponentActionMapPrecedence(ExecutableAction action, KeyEvent event) {
if (processActionAtPrecedence(ActionMapLevel, action, event)) {
return true;
}
KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(event);
if (processInputAndActionMaps(event, keyStroke)) {
return true;
}
return false;
}
private boolean processActionAtPrecedence(KeyBindingPrecedence keyBindingPrecedence, private boolean processActionAtPrecedence(KeyBindingPrecedence keyBindingPrecedence,
ExecutableAction action, KeyEvent event) { ExecutableAction action, KeyEvent event) {
@ -398,9 +378,11 @@ public class KeyBindingOverrideKeyEventDispatcher implements KeyEventDispatcher
// note: this code is taken from the JComponent method: // note: this code is taken from the JComponent method:
// protected boolean processKeyBinding(KeyStroke, KeyEvent, int, boolean ) // protected boolean processKeyBinding(KeyStroke, KeyEvent, int, boolean )
// //
// returns true if there is a focused component that has an action for the given keystroke // returns true if there is a focused component that has an action for the given event
// and it processes that action. // and it processes that action.
private boolean processInputAndActionMaps(KeyEvent keyEvent, KeyStroke keyStroke) { private boolean processInputAndActionMaps(KeyEvent event) {
KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(event);
Component focusOwner = focusProvider.getFocusOwner(); Component focusOwner = focusProvider.getFocusOwner();
if (focusOwner == null || !focusOwner.isEnabled() || !(focusOwner instanceof JComponent)) { if (focusOwner == null || !focusOwner.isEnabled() || !(focusOwner instanceof JComponent)) {
return false; return false;
@ -409,15 +391,15 @@ public class KeyBindingOverrideKeyEventDispatcher implements KeyEventDispatcher
JComponent jComponent = (JComponent) focusOwner; JComponent jComponent = (JComponent) focusOwner;
Action action = getJavaActionForComponent(jComponent, keyStroke); Action action = getJavaActionForComponent(jComponent, keyStroke);
if (action != null) { if (action != null) {
return SwingUtilities.notifyAction(action, keyStroke, keyEvent, keyEvent.getSource(), Object source = event.getSource();
keyEvent.getModifiersEx()); int modifiers = event.getModifiersEx();
return SwingUtilities.notifyAction(action, keyStroke, event, source, modifiers);
} }
return false; return false;
} }
private Action getJavaActionForComponent(JComponent jComponent, KeyStroke keyStroke) { private Action getJavaActionForComponent(JComponent jComponent, KeyStroke keyStroke) {
// first see if there is a Java key binding for when the component is in the focused // first see if there is a Java key binding for when the component is focused...
// window...
Action action = KeyBindingUtils.getAction(jComponent, keyStroke, JComponent.WHEN_FOCUSED); Action action = KeyBindingUtils.getAction(jComponent, keyStroke, JComponent.WHEN_FOCUSED);
if (action != null) { if (action != null) {
return action; return action;