如何让 JComboBox 响应回车键

How to get JComboBox to respond to enter key

我为此绞尽脑汁已经有一段时间了。当我 运行 以下代码时,在调用 JComboBox 的 showPopup() 方法时,任何其他键都可以正常工作,但是每当按下 enter 时,什么也没有发生。我曾尝试触发鼠标事件来模拟用户在 JComboBox 上的物理点击,但到目前为止没有任何效果。 (我 可以 使用 java.awt.Robot,但我真的不想这样做。)。下面是一个示例程序,它简单地显示了一个 JComboBox,并向其添加了一个 KeyAdapter:

import java.awt.Dimension;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SpringLayout;

public class Test {

    public static void main(String[] args) {
        JFrame testFrame = new JFrame();
        testFrame.setLocationRelativeTo(null);
        testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        SpringLayout layout = new SpringLayout();
        testFrame.getContentPane().setLayout(layout);

        JComboBox testingComboBox = new JComboBox(new String[] {"Option 1", "Option 2", "Option 3"});
        testingComboBox.addKeyListener(new KeyAdapter(){

            @Override
            public void keyPressed(KeyEvent e) {
                if(e.getKeyCode() == KeyEvent.VK_ENTER){
                    testingComboBox.showPopup();
                } else if (e.getKeyCode() == KeyEvent.VK_2){
                    testingComboBox.showPopup();
                }
            }

        });

        testFrame.add(testingComboBox);
        layout.putConstraint(SpringLayout.NORTH, testingComboBox, 0, SpringLayout.NORTH, testFrame);
        layout.putConstraint(SpringLayout.WEST, testingComboBox, 0, SpringLayout.WEST, testFrame);
        testFrame.pack();
        testingComboBox.requestFocusInWindow();
        int differenceInWidth = testFrame.getWidth() - testFrame.getContentPane().getWidth();
        int differenceInHeight = testFrame.getHeight() - testFrame.getContentPane().getHeight();
        testFrame.setMinimumSize(new Dimension(testingComboBox.getWidth() + differenceInWidth, testingComboBox.getHeight() + differenceInHeight));
        testFrame.setVisible(true);
    }

}

我不太确定发生了什么,希望得到任何可能的帮助。

注意:我也尝试过使用ActionListener,但也会出现同样的问题。如果我在 showPopup() 调用之前放置 System.out.println("Test");,"Test" 仍会打印在命令行中,但不会出现任何内容。

不要使用 KeyListener。请改用键绑定。这应该有效:

testingComboBox.getInputMap().put(KeyStroke.getKeyStroke("ENTER"),
                "showPopup");
testingComboBox.getActionMap().put("showPopup",
                new AbstractAction() {
                    public void actionPerformed(ActionEvent e) {
                        testingComboBox.showPopup();
                    }
});

Swing 设计用于 Key Bindings

Enter 键已定义为 JComboBox 的绑定,因此该操作基本上导致弹出窗口关闭。这可以通过使用来证明:

SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
        testingComboBox.showPopup();
    }
});

通过使用 invokeLater(),代码被放置在 EDT 的末尾,因此它在默认的 Enter 键处理之后执行。

因此实际上您不应该尝试监听 Enter 键事件,因为它们已经由 UI 处理。

查看 Key Binding Defaults 以获得每个组件的默认键绑定列表。

当您查看列表时,您会注意到组合框已经有一个操作来切换弹出窗口,因此如果您确实创建了一个键绑定,您应该使用现有的操作。以上 link 向您展示了如何做到这一点:

KeyStroke ks = KeyStroke.getKeyStroke("2");
InputMap im = comboBox.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
im.put(ks, "togglePopup");