use of CCDD.CcddConstants.ArrowFocusOption in project CCDD by nasa.
the class CcddKeyboardHandler method setKeyboardHandler.
/**
********************************************************************************************
* Adjust the handling of Enter and space key inputs in order to activate dialog controls, and
* keyboard focus changes in order to use the arrow keys like Tab keys
********************************************************************************************
*/
private void setKeyboardHandler() {
// Get the keyboard focus manager
focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
// Listen for key presses
focusManager.addKeyEventDispatcher(new KeyEventDispatcher() {
boolean isShowMacros = false;
Timer releaseTimer = null;
/**
************************************************************************************
* Alter the response to the Enter key to act like the Space key to activate button and
* check box controls, and the arrow keys so as to mimic the Tab and Shift+Tab keys,
* unless the key press originates within a table or combo box. For a tabbed pane the
* left/right arrows are left unchanged so that these are used for traversing the
* tabbed panes, but the down and up arrows act like Tab and Shift+Tab respectively
************************************************************************************
*/
@Override
public boolean dispatchKeyEvent(final KeyEvent ke) {
// Flag that indicates if the key event has been handled by this method (true) or
// that it still needs to be processed (false)
boolean handled = false;
// Get a reference to the component with the focus in order to shorten the
// subsequent calls
Component comp = ke.getComponent();
// pressed
if (ke.getID() == KeyEvent.KEY_PRESSED && !ke.isControlDown() && !ke.isShiftDown() && !ke.isAltDown()) {
// Check if the Enter key is pressed
if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
// Check if this is a button
if (comp instanceof JButton) {
// Activate the control (same as if Space key is pressed)
((AbstractButton) comp).doClick();
handled = true;
} else // Check if this is a table
if (comp instanceof CcddJTableHandler || (comp.getParent() instanceof CcddJTableHandler && !(comp instanceof JComboBox))) {
// Handle the Enter key in the table
handled = tableEditCellHandler(comp);
}
} else // Check if the space key is pressed
if (ke.getKeyCode() == KeyEvent.VK_SPACE) {
// Check if this is a table
if (comp instanceof CcddJTableHandler) {
// Handle the space key in the table
handled = tableEditCellHandler(comp);
} else // Check this is a combo box in a table
if (comp.getParent() instanceof CcddJTableHandler && comp instanceof JComboBox) {
// Ignore the key press
handled = true;
}
} else // produce a character and is not a modifier; this covers the arrow keys)
if (ke.isActionKey()) {
// Assume that the default handling will be used with an arrow key
ArrowFocusOption arrowResponse = USE_DEFAULT_HANDLER;
// Check if the focus is on a tabbed pane's tab or on a slider
if (comp instanceof JTabbedPane || comp instanceof JSlider) {
// The left and right arrows traverse the tabs, and the up and down
// arrows behave like (Shift+)Tab
arrowResponse = HANDLE_UP_AND_DOWN_ARROWS;
} else // Check if the focus is in a text field within a table
if ((comp instanceof JTextField || comp instanceof JTextArea) && comp.getParent() instanceof CcddJTableHandler) {
// The up and down arrows are ignored. This prevents accidently exiting
// edit mode on a table cell and losing any changes
arrowResponse = IGNORE_UP_AND_DOWN_ARROWS;
} else // button, or check box
if (comp instanceof JButton || comp instanceof JRadioButton || comp instanceof JCheckBox) {
// The up and left arrow keys behave as Shift+Tab, and the down and
// right arrow keys behave as Tab
arrowResponse = HANDLE_ALL_ARROWS;
} else // Check if the focus is within a table
if (comp instanceof CcddJTableHandler) {
// Get the reference to the table with the focus
CcddJTableHandler table = (CcddJTableHandler) comp;
// Get the row containing the cell with the focus in order to shorten
// the subsequent calls
int row = table.getSelectedRow();
// Check if the table has no rows
if (row == -1) {
// Treat the table as if it wasn't there; i.e., the left and right
// arrows behave like the (Shift+)Tab key
arrowResponse = HANDLE_ALL_ARROWS;
} else // Check if the table has only a single row
if (table.getRowCount() == 1) {
// The up and down arrows behave like the (Shift+)Tab key
arrowResponse = HANDLE_UP_AND_DOWN_ARROWS;
} else // Check if the top row is selected
if (row == 0) {
// The up arrow behaves like the Shift+Tab key
arrowResponse = HANDLE_UP_ARROW;
} else // Check if the bottom row is selected
if (row == table.getRowCount() - 1) {
// The down arrow behaves like the Tab key
arrowResponse = HANDLE_DOWN_ARROW;
}
}
// Check if the key pressed is an arrow key and if so adjust its behavior
switch(ke.getKeyCode()) {
case KeyEvent.VK_LEFT:
case KeyEvent.VK_KP_LEFT:
// Check if the left arrow key should be handled
if (arrowResponse == HANDLE_ALL_ARROWS) {
// Treat the left arrow as a Shift+Tab key and indicate that
// the key has been handled
focusManager.focusPreviousComponent();
handled = true;
}
break;
case KeyEvent.VK_UP:
case KeyEvent.VK_KP_UP:
// Check if the up arrow key should be handled
if (arrowResponse == HANDLE_ALL_ARROWS || arrowResponse == HANDLE_UP_ARROW || arrowResponse == HANDLE_UP_AND_DOWN_ARROWS) {
// Treat the up arrow as a Shift+Tab key and indicate that the
// key has been handled
focusManager.focusPreviousComponent();
handled = true;
} else // Check if the up arrow should be ignored
if (arrowResponse == IGNORE_UP_AND_DOWN_ARROWS) {
// Indicate that the key has been handled
handled = true;
}
break;
case KeyEvent.VK_RIGHT:
case KeyEvent.VK_KP_RIGHT:
// Check if the right arrow key should be handled
if (arrowResponse == HANDLE_ALL_ARROWS) {
// Treat the right arrow as a Tab key and indicate that the key
// has been handled
focusManager.focusNextComponent();
handled = true;
}
break;
case KeyEvent.VK_DOWN:
case KeyEvent.VK_KP_DOWN:
// Check if the down arrow key should be handled
if (arrowResponse == HANDLE_ALL_ARROWS || arrowResponse == HANDLE_DOWN_ARROW || arrowResponse == HANDLE_UP_AND_DOWN_ARROWS) {
// Treat the down arrow as a Tab key and indicate that the key
// has been handled
focusManager.focusNextComponent();
handled = true;
} else // Check if the down arrow should be ignored
if (arrowResponse == IGNORE_UP_AND_DOWN_ARROWS) {
// Indicate that the key has been handled
handled = true;
}
break;
}
}
} else // Check if the Ctrl key is pressed
if (ke.getID() == KeyEvent.KEY_PRESSED && ke.isControlDown() && !ke.isAltDown()) {
// Check if the Ctrl-Z key is pressed
if (ke.getKeyCode() == KeyEvent.VK_Z) {
// Get the currently active undo manager
final CcddUndoManager undoManager = getActiveUndoManager();
// Check if an active undo manager was found
if (undoManager != null) {
// Create a runnable object to be executed
SwingUtilities.invokeLater(new Runnable() {
/**
****************************************************************
* Execute after all pending Swing events are finished so that the
* events occur in the desired order
****************************************************************
*/
@Override
public void run() {
// Undo the previous edit action
undoManager.undo();
// associated with the component
if (editPnlHandler != null) {
// Update the data field background colors
editPnlHandler.setFieldBackgound();
}
// Force the component to repaint so that the change is visible
ke.getComponent().repaint();
}
});
// Set the flag to indicate this key press was handled
handled = true;
}
} else // Check if the Ctrl-Y key is pressed
if (ke.getKeyCode() == KeyEvent.VK_Y) {
// Get the currently active undo manager
final CcddUndoManager undoManager = getActiveUndoManager();
// Check if an active undo manager was found
if (undoManager != null) {
// Create a runnable object to be executed
SwingUtilities.invokeLater(new Runnable() {
/**
****************************************************************
* Execute after all pending Swing events are finished so that the
* events occur in the desired order
****************************************************************
*/
@Override
public void run() {
// Redo the previous undo action
undoManager.redo();
// associated with the component
if (editPnlHandler != null) {
// Update the data field background colors
editPnlHandler.setFieldBackgound();
}
// Force the component to repaint so that the change is visible
ke.getComponent().repaint();
}
});
// Set the flag to indicate this key press was handled
handled = true;
}
} else // focus
if (ke.getKeyCode() == KeyEvent.VK_F && ccddMain.getMainFrame().isFocused()) {
// Open the event log search dialog
ccddMain.showSearchDialog(SearchDialogType.LOG, null, ccddMain.getSessionEventLog(), ccddMain.getMainFrame());
// Set the flag to indicate this key press was handled
handled = true;
} else // insertion
if (ke.getKeyCode() == KeyEvent.VK_S) {
// Get the table editor dialog with the focus
CcddTableEditorDialog editorDialog = getFocusedTableEditorDialog();
// contain a combo box
if (editorDialog != null && !(comp instanceof JComboBox)) {
// Check if a cell in the table is being edited
if (editorDialog.getTableEditor().getTable().isEditing()) {
// Insert the structure name chosen by the user into the text field
// at the current text insertion point
dataTypeHandler.insertDataTypeName((JFrame) editorDialog, (JTextArea) comp, true, editorDialog.getTableEditor().getValidDataTypes().toArray(new String[0]));
}
} else // Check if the data type editor editing is active
if (SwingUtilities.getWindowAncestor(comp) instanceof CcddDataTypeEditorDialog && modalTable.isEditing()) {
// Get the row and column being edited in the table, and the contents
// of the edited row's base data type
int row = modalTable.getEditingRow();
int column = modalTable.convertColumnIndexToModel(modalTable.getEditingColumn());
String baseType = modalTable.getValueAt(row, DataTypeEditorColumnInfo.BASE_TYPE.ordinal()).toString();
// base data type is empty or a pointer
if ((column == DataTypeEditorColumnInfo.USER_NAME.ordinal() || column == DataTypeEditorColumnInfo.C_NAME.ordinal()) && (baseType.isEmpty() || baseType.equals(BaseDataTypeInfo.POINTER.getName()))) {
// Insert the structure name chosen by the user into the text field
// at the current text insertion point
dataTypeHandler.insertDataTypeName((JDialog) SwingUtilities.getWindowAncestor(comp), (JTextArea) comp, false, null);
}
} else // Check if the macro editor editing is active
if (SwingUtilities.getWindowAncestor(comp) instanceof CcddMacroEditorDialog && modalTable.isEditing()) {
// Insert the structure name chosen by the user into the text field at
// the current text insertion point
dataTypeHandler.insertDataTypeName((JDialog) SwingUtilities.getWindowAncestor(comp), (JTextArea) comp, true, null);
}
// Set the flag to indicate this key press was handled
handled = true;
} else // and expansion
if (ke.getKeyCode() == KeyEvent.VK_M) {
// Check if the shift key is also pressed (Ctrl-Shift-M)
if (ke.isShiftDown()) {
// Check if the macros aren't already expanded
if (!isShowMacros) {
// Get the table editor dialog with the focus
CcddTableEditorDialog editorDialog = getFocusedTableEditorDialog();
// Check if a table editor dialog has the focus
if (editorDialog != null) {
// Replace the macro names with their corresponding values in
// the currently selected table in this editor
editorDialog.getTableEditor().expandMacros(true, true);
isShowMacros = true;
} else // Check if this is the macro editor
if (SwingUtilities.getWindowAncestor(comp) instanceof CcddMacroEditorDialog) {
// Expand the macros in the macro value column
((CcddMacroEditorDialog) SwingUtilities.getWindowAncestor(comp)).expandMacros(true);
isShowMacros = true;
}
}
} else // The shift key isn't pressed (Ctrl-M only). Check if this is a table cell
if (comp.getParent() instanceof CcddJTableHandler) {
// Get the table editor dialog with the focus
CcddTableEditorDialog editorDialog = getFocusedTableEditorDialog();
// doesn't contain a combo box
if (editorDialog != null && !(comp instanceof JComboBox)) {
// Get references to shorten subsequent calls
CcddTableEditorHandler editor = editorDialog.getTableEditor();
CcddJTableHandler table = editor.getTable();
// Check if a cell in the table is being edited
if (table.isEditing()) {
// Get the index of the column being edited in model
// coordinates
int column = table.convertColumnIndexToModel(table.getEditingColumn());
// Get the input type for the column being edited
InputDataType inputType = editor.getTableTypeDefinition().getInputTypes()[column];
// Insert the macro name chosen by the user into the text
// component at the current text insertion point
macroHandler.insertMacroName(editorDialog, (JTextComponent) comp, inputType, editor.getValidDataTypes());
}
} else // column is being edited
if (SwingUtilities.getWindowAncestor(comp) instanceof CcddMacroEditorDialog && modalTable.isEditing() && modalTable.convertColumnIndexToModel(modalTable.getEditingColumn()) == MacroEditorColumnInfo.VALUE.ordinal()) {
// Insert the macro name chosen by the user into the text component
// at the current text insertion point
macroHandler.insertMacroName((JDialog) SwingUtilities.getWindowAncestor(comp), (JTextComponent) comp, InputDataType.TEXT, null);
}
}
// Set the flag to indicate this key press was handled
handled = true;
} else // Check if the Ctrl-E key is pressed while the focus is on a tree
if (ke.getKeyCode() == KeyEvent.VK_E && comp instanceof CcddCommonTreeHandler) {
// Expand/collapse the selected node(s)
((CcddCommonTreeHandler) comp).expandCollapseSelectedNodes();
}
} else // text
if (ke.getID() == KeyEvent.KEY_PRESSED && ke.isAltDown() && !ke.isControlDown() && ke.getKeyCode() == KeyEvent.VK_ENTER && comp.getParent() instanceof CcddJTableHandler && comp instanceof JTextArea) {
// Get the table editor dialog with the focus
CcddTableEditorDialog editorDialog = getFocusedTableEditorDialog();
// Check if a table editor dialog has the focus
if (editorDialog != null) {
// Check if a cell in the table is being edited
if (editorDialog.getTableEditor().getTable().isEditing()) {
JTextComponent textComp = (JTextComponent) comp;
// Get the cell's current value
String cellValue = textComp.getText();
// Get the starting position of the selected text
int caretPosn = textComp.getSelectionStart();
// Replace the currently selected text with a line feed
textComp.setText(cellValue.substring(0, caretPosn) + "\n" + cellValue.substring(textComp.getSelectionEnd()));
// Position the cursor after the newly inserted line feed
textComp.setCaretPosition(caretPosn + 1);
}
}
}
// key sequence is no longer active
if (isShowMacros && ke.getID() == KeyEvent.KEY_RELEASED && ke.getKeyCode() == KeyEvent.VK_M) {
// Check if the key release action timer doesn't exist
if (releaseTimer == null) {
// Create the key release action timer. In Linux if a key is held it
// generates continuous key release events. This timer is used to ignore
// the key release events that are close together time-wise
releaseTimer = new Timer(75, new ActionListener() {
/**
********************************************************************
* Handle the key release action
********************************************************************
*/
@Override
public void actionPerformed(ActionEvent ae) {
// Get the table editor dialog with the focus
CcddTableEditorDialog editorDialog = getFocusedTableEditorDialog();
// Check if a table editor dialog has the focus
if (editorDialog != null) {
// Restore the macro names in the currently selected table in
// this editor
editorDialog.getTableEditor().expandMacros(false, true);
isShowMacros = false;
} else // Check if this is the macro editor
if (SwingUtilities.getWindowAncestor(modalTable) instanceof CcddMacroEditorDialog) {
// Expand the macros in the macro value column
((CcddMacroEditorDialog) SwingUtilities.getWindowAncestor(modalTable)).expandMacros(false);
isShowMacros = false;
}
}
});
// Allow the timer to send only a single expiration event
releaseTimer.setRepeats(false);
}
// (Re)start the key release action timer
releaseTimer.restart();
// Set the flag to indicate this key press was handled
handled = true;
}
return handled;
}
});
}
Aggregations