Merge remote-tracking branch 'origin/GT-0-dragonmacher-test-fixes'

This commit is contained in:
Ryan Kurtz 2019-11-26 09:32:46 -05:00
commit 76bd653deb
15 changed files with 212 additions and 30 deletions

View file

@ -176,8 +176,14 @@ public class KeyBindingUtils {
/**
* Changes the given key event to the new source component and then dispatches that event.
* This method is intended for clients that wish to effectively take a key event given to
* one component and give it to another component. This is seldom-used code; if you don't
* know when to use this code, then don't.
* one component and give it to another component.
*
* <p>This method exists to deal with the complicated nature of key event processing and
* how our (not Java's) framework processes key event bindings to trigger actions. If not
* for our special processing of action key bindings, then this method would not be
* necessary.
*
* <p><b>This is seldom-used code; if you don't know when to use this code, then don't.</b>
*
* @param newSource the new target of the event
* @param e the existing event
@ -190,9 +196,44 @@ public class KeyBindingUtils {
KeyEvent newEvent = new KeyEvent(newSource, e.getID(), e.getWhen(), e.getModifiersEx(),
e.getKeyCode(), e.getKeyChar(), e.getKeyLocation());
e.consume();
/*
Unusual Code Alert!
The KeyboardFocusManager is a complicated beast. Here we use knowledge of one such
complication to correctly route key events. If the client of this method passes
a component whose 'isShowing()' returns false, then the manager will not send the
event to that component. Almost all clients will pass fully attached/realized
components to the manager. We, however, will sometimes pass components that are not
attached; for example, when we are using said components with a renderer to perform
our own painting. In the case of non-attached components, we must call the
redispatchEvent() method ourselves.
Why don't we just always call redispatchEvent()? Well, that
method will not pass the new cloned event we just created back through the full
key event pipeline. This means that tool-level (our Tool API, not Java)
actions will not work, as tool-level actions are handled at the beginning of the
key event pipeline, not by the components themselves.
Also, we have here guilty knowledge that the aforementioned tool-level key processing
will check to see if the event was consumed. If consumed, then no further processing
will happen; if not consumed, then the framework will continue to process the event
passed into this method. Thus, after we send the new event, we will update the
original event to match the consumed state of our new event. This means that the
component passed to this method must, somewhere in its processing, consume the key
event we dispatch here, if they do not wish for any further processing to take place.
*/
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
kfm.dispatchEvent(newEvent);
if (newSource.isShowing()) {
kfm.dispatchEvent(newEvent);
}
else {
kfm.redispatchEvent(newSource, newEvent);
}
if (newEvent.isConsumed()) {
e.consume();
}
}
/**

View file

@ -84,7 +84,7 @@ public class GTable extends JTable {
private int userDefinedRowHeight;
private boolean isInitialized;
private boolean allowActions;
private boolean enableActionKeyBindings;
private KeyListener autoLookupListener;
private long lastLookupTime;
private String lookupString;
@ -386,6 +386,11 @@ public class GTable extends JTable {
/**
* Sets the column in which auto-lookup will be enabled.
*
* <p>Note: calling this method with a valid column index will disable key binding support
* of actions. See {@link #setActionsEnabled(boolean)}. Passing an invalid column index
* will disable the auto-lookup feature.
*
* @param lookupColumn the column in which auto-lookup will be enabled
*/
public void setAutoLookupColumn(int lookupColumn) {
@ -395,7 +400,8 @@ public class GTable extends JTable {
autoLookupListener = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (!allowActions) {
if (enableActionKeyBindings) {
// actions will consume key bindings, so don't process them
return;
}
@ -428,6 +434,7 @@ public class GTable extends JTable {
if (lookupColumn >= 0 && lookupColumn < getModel().getColumnCount()) {
addKeyListener(autoLookupListener);
enableActionKeyBindings = false;
}
else {
removeKeyListener(autoLookupListener);
@ -471,7 +478,22 @@ public class GTable extends JTable {
* @param b true allows keyboard actions to pass up the component hierarchy.
*/
public void setActionsEnabled(boolean b) {
allowActions = b;
enableActionKeyBindings = b;
}
/**
* Returns true if key strokes are used to trigger actions.
*
* <p>This method has a relationship with {@link #setAutoLookupColumn(int)}. If this method
* returns <code>true</code>, then the auto-lookup feature is disabled. If this method
* returns <code>false</code>, then the auto-lookup may or may not be enabled.
*
* @return true if key strokes are used to trigger actions
* @see #setActionsEnabled(boolean)
* @see #setAutoLookupColumn(int)
*/
public boolean areActionsEnabled() {
return enableActionKeyBindings;
}
/**