0

I've found several pages and SO answers about the enter-as-tab problem in Java, but all propose either overriding methods of JTextField or adding a key listener to every component.

But isn't there any other way? Can't I override something of the LookAndFeel or install some global policy?

Daniel Rikowski
  • 71,375
  • 57
  • 251
  • 329

3 Answers3

2

After some documentation crawling I found a solution: It is possible to set the focus traversal keys on KeyboardFocusManager instead of a JComponent instance.

// 1. Get default keys
Set<AWTKeyStroke> ftk = new HashSet<AWTKeyStroke>(
        KeyboardFocusManager.getCurrentKeyboardFocusManager()
        .getDefaultFocusTraversalKeys(
        KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));

// 2. Add our key
ftk.add(KeyStroke.getKeyStroke("ENTER"));

// 3. Set new keys
KeyboardFocusManager.getCurrentKeyboardFocusManager()
        .setDefaultFocusTraversalKeys(
        KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, ftk);

This adds the enter key to the list of keys which are used for forward traversal. (Backward traversal similar)

Daniel Rikowski
  • 71,375
  • 57
  • 251
  • 329
1

you can probably use http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html

to change the keyBinding for the enter key

or you can add focustravesal keys

setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, your keys here);
Peter
  • 5,728
  • 20
  • 23
1

The hammer - of setting the enter as focus traversal key for all component except those which register their own - is just fine if it's really required. The obvious drawback is that default bindings to the enter stop working, in particular

  • action/Listeners on textFields
  • default buttons
  • any other component type with a custom binding to enter

If those side-effects are problematic, there's the less intrusive alternative of tweaking the binding in the shared ancestor actionMap of the textFields.

// "early" in the app instantiate a textField
JTextField text = new JTextField();
ActionMap map = text.getActionMap();
// get a reference to the default binding
final Action notify = map.get(JTextField.notifyAction);
while (map.getParent() != null) {
    // walk up the parent chain to reach the top-most shared ancestor
    map = map.getParent();
}
// custom notify action
TextAction tab = new TextAction(JTextField.notifyAction) {

    @Override
    public void actionPerformed(ActionEvent e) {
        // delegate to default if enabled
        if (notify.isEnabled()) {
            notify.actionPerformed(e);
        }
        // trigger a focus transfer
        getTextComponent(e).transferFocus();
    }

};
// replace default with augmented custom action
map.put(JTextField.notifyAction, tab);

After replacing the default, all textFields will use the custom action. The one beware is that the replacement has to be repeated whenever the LAF is changed.

kleopatra
  • 51,061
  • 28
  • 99
  • 211
  • [and interesting answer for my question](http://stackoverflow.com/questions/10075147/how-to-use-textaction) – mKorbel Nov 19 '12 at 14:24