zerone
zerone

Reputation: 125

JComponent.WHEN_IN_FOCUSED_WINDOW cannot work with JCombobox

I had screen below: enter image description here

public BillSummaryScreen() {
   ..........
   ShortcutKeyUtils.createShortcutKey(this, KeyEvent.VK_ENTER, "enterShortcut", new EnterAction());

}

public static void createShortcutKey(JComponent panel, int keyEventCode, String actionShortcutName, AbstractAction action){
        InputMap inputMap =  panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        inputMap.put(KeyStroke.getKeyStroke(keyEventCode, 0), actionShortcutName);
        ActionMap actionMap = panel.getActionMap();
        actionMap.put(actionShortcutName, action);
    }

private class EnterAction extends AbstractAction{

        @Override
        public void actionPerformed(ActionEvent arg0) {
            System.out.println("EnterAction");
        }

    }

I want to press "ENTER" key so the search button is clicked. But when i focus into one combobox(by mouse) and i pressed ENTER, the action did not work

Upvotes: 1

Views: 867

Answers (1)

kleopatra
kleopatra

Reputation: 51525

As long as you are only interested in the ENTER binding, you might consider defining the search button as the rootpane's default button: this will pass the enter on the comboBox automatically to the button's action.

JButton searchButton = new JButton(searchAction);
frame.getRootPane().setDefaultButton(searchButton);

While possible to pass-on arbitrary bindings, that's a bit difficult, both from the usibility perspective (do you really want both action to happen, that is the one bound to the component and the one in your window binding?) as from the technical perspective. For solving the latter, you basically need a custom component that tricks the binding mechanism into believing that it isn't interested in the keyStroke, f.i. as done in the MultiplexingTextField below.

Doing so for a JComboBox has its own stumbling blocks: you would have to implement a custom comboBoxEditor which uses such a custom textField. As the editor is controlled by the LAF (and looks different for nearly each one), you would need a custom editor per LAF (check the sources and c&p :-).

/**
 * A JTextField that allows you to specify an array of KeyStrokes that
 * will have their bindings processed regardless of whether or
 * not they are registered on the JTextField itself. 
 */
public static class MultiplexingTextField extends JTextField {
    private KeyStroke[] strokes;
    private List<KeyStroke> keys;
    MultiplexingTextField(int cols, KeyStroke... strokes) {
        super(cols);
        this.keys = Arrays.asList(strokes);
    }

   @Override
    protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
                                        int condition, boolean pressed) {
        boolean processed = super.processKeyBinding(ks, e, condition,
                                                    pressed);

        if (processed && condition != JComponent.WHEN_IN_FOCUSED_WINDOW
                && keys.contains(ks)) {
            // Returning false will allow further processing
            // of the bindings, eg our parent Containers will get a
            // crack at them.
            return false;
        }
        return processed;
    }

}

Upvotes: 1

Related Questions