可编辑的JComboBox:在下拉选择中忽略输入时确定是否按下了输入?

时间:2016-04-01 00:35:53

标签: java swing

我有一个面板,其中包含几个文本字段和一个用于执行搜索的可编辑JComboBox。我希望所有这些都像我按下回车键时按下下面的搜索按钮一样。这适用于JTextField ActionListener的{​​{1}}。但是,我只希望JComboBox在按下输入时开始搜索,并且没有显示下拉列表。即如果用户按下Enter键以在下拉列表中选择一个选项,则不会发生任何事情。

我将如何实现此行为?

我尝试检查getActionCommand(),并在事件触发时显示"comboBoxEdited""comboBoxChanged"。选择选项后按Enter键时以及在可编辑字段中按Enter键时会触发"comboBoxEdited"。在选项之间移动时,以及在编辑文本后按下输入时"comboBoxChanged"之前,"comboBoxEdited"会被触发。

我尝试了一个丑陋的黑客,我存储了之前的ActionCommand,但它并不完美,因为用户在手动输入文本后必须按两次输入。

public void actionPerformed(ActionEvent e) {
    if (e.getActionCommand().equals("comboBoxEdited") &&
        !combohack.equals("comboBoxChanged")) {

        combohack="";
        //PERFORM SEARCH!
    }
    combohack=e.getActionCommand();
}

我进一步尝试通过添加KeyListener来重置字符串,以便在按下实际字母时重置字符串,但我没有帮助。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

好的,这有点沉重,但这样做会将KeyEvent.VK_ENTER Action替换为我们自己的Action

基本上,当用户按下 Enter 键时,会通知Action,但组合框不通知(因此JComboBox不会触发{ {1}}对于它 - 但将用于选择更改)

ActionEvent
  

感谢您的努力!它并不像我想要的那样真正起作用。当按下[Enter]以选择突出显示的项目时,它仍会使用“comboBoxEdited”触发事件,而不是仅关闭下拉列表,而在编辑器中保留所选文本。它只应在下拉菜单关闭并且用户按下[Enter]时触发事件。所以[Enter]选择一个项目,再次按[Enter]激活该动作。

所以,我终于在Windows机器上运行代码了,基本上,在import java.awt.Component; import java.awt.EventQueue; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import javax.swing.AbstractAction; import javax.swing.ActionMap; import javax.swing.ComboBoxEditor; import javax.swing.InputMap; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class Test { public static void main(String[] args) { new Test(); } public Test() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { public TestPane() { setLayout(new GridBagLayout()); final JComboBox<String> cb = new JComboBox<>(new String[]{"Apples", "Bananas", "Pears"}); cb.setEditable(true); SimpleComboBoxEditor editor = new SimpleComboBoxEditor(); InputMap im = editor.getInputMap(); ActionMap am = editor.getActionMap(); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enter"); am.put("enter", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { if (!cb.isPopupVisible()) { System.out.println("Editor did action"); } cb.hidePopup(); } }); cb.setEditor(editor); cb.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("Combobox did action"); } }); add(cb); } public class SimpleComboBoxEditor extends JTextField implements ComboBoxEditor { @Override public Component getEditorComponent() { return this; } @Override public void setItem(Object anObject) { if (anObject != null) { setText(anObject.toString()); } else { setText(null); } } @Override public Object getItem() { return getText(); } } } } 的密钥绑定中,我检查了Action,当它不是时,它会打印出来“编辑做了动作”事件,否则它什么都不做

答案 1 :(得分:-1)

实际上有一个相当简单和优雅的解决方案:

combo.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode()==KeyEvent.VK_ENTER && !combo.isPopupVisible()) {
            System.out.println("SEARCH!");
        }
    }
});

请注意,如果KeyListener直接添加到JComboBox,则EditorComponent无法使用,但必须添加到<form method="post" <input type="text" name="search_keyword"> <input type="submit" name="button_search"> </form>