How to turn off a key listener in NetBeans wizard panels?

余生颓废 提交于 2019-11-28 13:51:54
dic19

Everything is okay until user choose a some value from list and than press key ENTER then my panel goes to next Step 3. I attach a key listener to list something like [...]

If you want Enter key in your list has precedence over the default Next -> button then you have to use Key binding to attach an action to your list when it's focused:

KeyStroke enterKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
Action updateTextfieldAction = new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        JList list = (JList)evt.getSource();
        Object selectedPackage = list.getSelectedValue();
        typePackageField.setText((String)selectedPackage );
    }
};

list = new JList(new PackagesListModel());
list.getInputMap().put(enterKeyStroke, "enter");
list.getActionMap().put("enter", updateTextfieldAction);

Note that getInputMap() is a shortcut for getInputMap(JComponent.WHEN_FOCUSED). This means that if your list has focus and Enter key is pressed, then the action attached to this key stroke will be performed.

By this way your action will always have precedence over the next button's action, either if this button is the default button or it has attached an action using key bindings using WHEN_IN_FOCUSED_WINDOW like this:

JButton button = new JButton(nextStepAction);
button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(enterKeyStroke, "enter");
button.getActionMap().put("enter", nextStepAction);

Where nextStepAction would be the action to go to wizard's next step.

See also Key bindings vs. key listeners in Java


Example

Please cosider the example below. Note if you focus another component but list the the default action is performed. I've set the button as frame's root pane default button and I've attached an action using WHEN_IN_FOCUSED_WINDOW just to prove that WHEN_FOCUSED action has precedence over those.

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class Demo {

    private JList list;
    private JTextField textField;

    private void createAndShowGUI() {

        KeyStroke enterKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);

        Action nextStepAction = new AbstractAction("Next") {
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(null, "Going to step 3!", "Message", JOptionPane.INFORMATION_MESSAGE);
            }
        };

        Action updateTextfieldAction = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textField.setText((String)list.getSelectedValue());
            }
        };

        list = new JList(new String[]{"Item 1", "Item 2", "Item 3"});
        list.setPrototypeCellValue("This is a list's prototype cell value.");
        list.getInputMap().put(enterKeyStroke, "enter");
        list.getActionMap().put("enter", updateTextfieldAction);

        textField = new JTextField(15);

        JPanel listPanel = new JPanel();
        listPanel.add(new JScrollPane(list));
        listPanel.add(textField);

        JButton button = new JButton(nextStepAction);
        button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(enterKeyStroke, "enter");
        button.getActionMap().put("enter", nextStepAction);

        JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
        buttonsPanel.add(button);

        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(listPanel);
        frame.add(buttonsPanel, BorderLayout.PAGE_END);
        frame.getRootPane().setDefaultButton(button);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Demo().createAndShowGUI();
            }
        });
    }
}

Other comments

Please note that if you want avoid all this matter, you could attach a ListSelectionListener to your list and update the text field on selection change with no need to press Enter key at all. In fact if you have access to the next step action you could enable/disable it based on list selection. By doing this you'll be sure that wizard can't continue if no item is selected in your list. IMHO that would be a more elegant way to handle this situation. See Selecting Items in a List for further details.

I'm not sure but if you know which JComponent causes this behaviour, try this:

suspectedComponent.getInputMap().put(KeyStroke.getKeyStrokeForEvent(KeyEvent.VK_ENTER),"none");

To check which keystrokes are bound on a JComponent:

suspectedComponent.getInputMap().keys()

Or in the parent InputMap:

suspectedComponent.getInputMap().getParent().keys()

See the docs for InputMap for details.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!