Reputation: 19822
I am trying to find out how to detect if a JComboBox lost focus when user pressed tab or via a mouse-click outside the component's area.
Adding a FocusListener to the editor component of the JComboBox does not help me, as I can't find out if user used the mouse or moved the focus via the tab key. Any ideas would be greatly appreciated.
Edit 1: What I am trying to achieve is this:
Edit 2:
It seems that I have to use setFocusTraversalKeysEnabled(false)
to get notified when TAB is pressed, and when i capture that event, I should manually transfer focus... I do not like this solution, but that is so far the best I could come up with.
Solution:
Following piece of Java code is actually solving my problem. As I wrote in Edit 2 the easiest solution was to disable focus traversal. I shamelessly borrowed Kleopatra's code, and all works now. :)
if (!isTableCellEditor()) {
comboBoxEditor.setFocusTraversalKeysEnabled(false);
Action myAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
handleTabPress();
comboBoxEditor.transferFocus();
} // actionPerformed() method
};
comboBoxEditor.getActionMap().put("tab-action", myAction);
comboBoxEditor.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.put(KeyStroke.getKeyStroke("TAB"), "tab-action");
} // if
Thanks to all participants in the discussion!
Upvotes: 3
Views: 3861
Reputation: 51536
As I understand your question, there are two separate problems
if so, the answers are
In code:
final JComboBox simpleBox = new JComboBox(Locale.getAvailableLocales());
// this line configures the combo to only commit on ENTER
// or selecting an item from the list
simpleBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
//
// simpleBox.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
// Collections.EMPTY_SET);
// just noticed the OPs edit - following indeed is easier to disable _all_ traversal
// keys with one statement
simpleBox.setFocusTraversalKeysEnabled(false);
Action myAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
LOG.info("got it!");
simpleBox.transferFocus();
}
};
simpleBox.getActionMap().put("tab-action", myAction);
simpleBox.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.put(KeyStroke.getKeyStroke("TAB"), "tab-action");
Upvotes: 6
Reputation: 94118
It is assumed that you have pressed the mouse (or key) right before you loose focus. So listen to all the keyboard and mouse clicks, and the one used last right before loosing focus is the culprit.
When focuslost is fired, you would check a variable you set when a mouse or key is pressed, on any part of your window. This variable just logs the last mouse and/or key pressed. You would have to capture all the mouse and keypresses of course, since clicking on any widget would let you loose focus.
Upvotes: 3