如何让 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");
我为此绞尽脑汁已经有一段时间了。当我 运行 以下代码时,在调用 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");