如何设置Java默认按钮以对ENTER键_released_作出反应?

在我的应用程序中,我使用默认按钮。 我希望它在释放 ENTER键时做出反应。 按下 ENTER键时不显示。

我从按钮的InputMap中删除了KeyStroke 。 但它对我不起作用。 我该怎么做?


 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; public class ButtonTest { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { buildFrame(); } }); } private static void buildFrame() { JFrame f = new JFrame("Test"); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); JButton button = new JButton(new AbstractAction("Button") { @Override public void actionPerformed(ActionEvent e) { System.out.println("ButtonTest::actionPerformed: CALLED"); } }); JButton button2 = new JButton("Button 2"); InputMap im = button.getInputMap(); im.put(KeyStroke.getKeyStroke("ENTER"), "none"); im.put(KeyStroke.getKeyStroke("released ENTER"), "released"); f.setLayout(new GridBagLayout()); f.add(button); f.add(button2); f.getRootPane().setDefaultButton(button); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } } 

这是示例代码。

 JRootPane rootPane = SwingUtilities.getRootPane(/* Your JButton */); rootPane.setDefaultButton(/* Your JButton */); 

默认按钮的键(即,在输入时触发的按钮,无论哪个组件是focusOwner)都绑定在rootPane的componentInputMap中,即它的WHEN_IN_FOCUSED_WINDOW类型的inputMap。 从技术上讲,这是调整的地方:

 JComponent content = new JPanel(); content.add(new JTextField("some focusable")); content.add(new JTextField("something else")); JXFrame frame = wrapInFrame(content, "default button on released"); Action action = new AbstractAction("do something") { @Override public void actionPerformed(ActionEvent e) { LOG.info("clicked"); } }; JButton button = new JButton(action); content.add(button); frame.getRootPane().setDefaultButton(button); // remove the binding for pressed frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) .put(KeyStroke.getKeyStroke("ENTER"), "none"); // retarget the binding for released frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) .put(KeyStroke.getKeyStroke("released ENTER"), "press"); 

注意:这仍然与非默认按钮的按下/释放行为不同,因为rootPane操作只是调用了button.doClick而没有经过布防/按下buttonModel的移动来间接触发操作。

  InputMap im = button.getInputMap(); im.put(KeyStroke.getKeyStroke("ENTER"), "pressed"); im.put(KeyStroke.getKeyStroke("released ENTER"), "released"); 

这样做的结果是,当ENTER被释放时,按钮只执行一次actionPerformed(如果我理解正确,这就是你想要的)。

编辑:运行以下代码演示了actionPerformed仅在ENTER版本中执行(虽然在视觉上按钮出现在ENTER按钮上已按下)

 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; public class ButtonTest { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { buildFrame(); } }); } private static void buildFrame() { JFrame f = new JFrame("Test"); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); JButton button = new JButton(new AbstractAction("Button") { @Override public void actionPerformed(ActionEvent e) { System.out.println("ButtonTest::actionPerformed: CALLED"); } }); InputMap im = button.getInputMap(); im.put(KeyStroke.getKeyStroke("ENTER"), "pressed"); im.put(KeyStroke.getKeyStroke("released ENTER"), "released"); f.add(button); f.getRootPane().setDefaultButton(button); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } } 

您可以使用getKeyStroke()版本,它允许您将onKeyRelease设置为true ,就像在这个答案中一样

编辑:您可以停止重复,就像在这个答案中 。

Interesting Posts