Xingji Chen
Xingji Chen

Reputation: 48

Java. Ignore/disable key function but still capture the keyEvent

I have a JTextField and I want to record keyEvent when I focus on it. This is not hard and I can already print out all key names (such as "F1", "ESCAPE", "A", "M") except "TAB".

The problem is, the focus would change when I press "TAB" and a character is deleted when I press "BACKSPACE". I want to avoid this but keep the keyEvent. So I wonder if it's possible to ignore the key function when I press it. Any ideas?

Upvotes: 1

Views: 1594

Answers (1)

DevilsHnd - 退した
DevilsHnd - 退した

Reputation: 9192

To eliminate the Tab-Away feature from a JTextField you will need to set its setFocusTraversalKeysEnabled property to false. Once this is done focus can not be lost from the JTextField by hitting the TAB (or SHIFT-TAB) key and the fact that the TAB key was pressed can be detected within the JTextField's KeyPressed event.

The easiest way to remove the the Backspace/Delete feature from a JTextField is with a custom DocumentFilter. By overriding the filter's remove() method with a empty method effectively eliminates Backspace or Delete key capabilities.

This can all be accomplished with the use of a single method which I have provided below. The method allows you to disable or enable Tab and Backspace capabilities from the supplied JTextField:

/**
 * Disables (and can again Enable) the TAB (or SHIFT-TAB), BACKSPACE, and DELETE keys when 
 * used within the supplied JTextField.<br><br>
 * 
 * When the Tab key or Backspace key is hit then it can be detected within the 
 * JTextField's KeyPressed Event by way of:<pre>
 * 
 *      if (event.getKeyCode() == KeyEvent.VK_TAB) {
 *          System.out.println("TAB Key Pressed!");
 *      } 
 *      else if (event.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
 *          System.out.println("BACKSPACE Key Pressed!");
 *      }</pre>
 * 
 * @param jtextfield (JTextField) The desired JTextField variable name to 
 * control.<br>
 * 
 * @param ON_OFF (Optional - Boolean - Default is true) If true (default) then 
 * Tab and Backspace is not allowed within the supplied JTextField. If false is 
 * supplied then Tab and Backspace is allowed within the supplied JTextField.
 */
public void noTABorBACKSPACE(JTextField jtextfield, boolean... ON_OFF) {
    boolean on = true;  // Default ON - No Tab Away and No Backspace allowed.
    if (ON_OFF.length > 0) {
        on = ON_OFF[0];
    }
    if (on) {
        // Remove the TAB Away feature from the JTextField.
        jtextfield.setFocusTraversalKeysEnabled(!on);

        // Disable the Backspace feature from the JTextField.
        // This is done with a custom Document Filter.
        ((AbstractDocument) jtextfield.getDocument()).setDocumentFilter(
            new DocumentFilter(){
                @Override
                // By overriding the remove() method with an empty remove() 
                // method we effectively eliminate Backspace capabilities.
                public void remove(DocumentFilter.FilterBypass fb, int i, int i1) 
                    throws BadLocationException {  }
            }
        );
    }
    else {
        // Re-enable the TAB Away feature for the JTextField.
        jtextfield.setFocusTraversalKeysEnabled(!on);

        // Re-enable the Backspace feature for the JTextField.
        // This is done by removing our custom Document Filter.
        ((AbstractDocument) jtextfield.getDocument()).setDocumentFilter(null);
    }
}

How to use this method:

// To disable TAB and BACKSPACE
noTABorBACKSPACE(jTextField1);
//         OR
// noTABorBACKSPACE(jTextField1, true);   

// To re-enable TAB and BACKSPACE
noTABorBACKSPACE(jTextField1, false);

While the TAB and BACKSPACE features are disabled within the supplied JTextField you can determine if those specific keys were pressed by way of the JTextField's KeyPressed event, for example:

private void jTextField1KeyPressed(java.awt.event.KeyEvent evt) {                                       
    if (evt.getKeyCode() == KeyEvent.VK_TAB) {
        System.out.println("TAB Key Hit!");
    }
    else if (evt.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
        System.out.println("BACKSPACE Key Hit!");
    }
}  

You will notice that when the JTextField's setFocusTraversalKeysEnabled property is set to boolean true you will not be able to detect when the TAB key is hit and this is because the TAB key is always consumed by the KeyboardFocusManager. This is not so when the setFocusTraversalKeysEnabled property is set to boolean false.

So far the code provided gives means to remove Tab-Away and Backspace/Delete capabilities but perhaps you want to keep the Delete key active and just remove capabilities for the TAB and BACKSPACE key. If this is the case then you can do this from within the JTextField's KeyPressed event by consuming the BACKSPACE key press:

private void jTextField1KeyPressed(java.awt.event.KeyEvent evt) {                                       
    if (evt.getKeyCode() == KeyEvent.VK_TAB) {
        System.out.println("TAB Key Hit!");
    }
    else if (evt.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
        System.out.println("BACKSPACE Key Hit!");
        evt.consume(); // Consume the BACKSPACE Key Press.
    }
}  

To stop the TAB key from moving focus you will still need to set the setFocusTraversalKeysEnabled property to false.

Upvotes: 2

Related Questions