【问题标题】:Adding JTextField to JMenuBar cancels KeyListener responses!! - How to fix?将 JTextField 添加到 JMenuBar 会取消 KeyListener 响应! - 怎么修?
【发布时间】:2016-07-06 21:52:02
【问题描述】:

以下是SSCCE代码;它工作正常,KeyListener 响应正确,但将JTextField 添加到JMenuBar 会导致KeyListener 根本不响应。

去取消注释/注释添加JTextField 的行以查看差异:menuBar.add(textField);

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class JMenueWithKeyListenerExample extends JPanel {

    JTextField textField;
    JMenuBar menuBar;
    JFrame f;

    public JMenueWithKeyListenerExample() {

        textField = new JTextField();

        menuBar = new JMenuBar();
        JMenu fileMenue = new JMenu("File");
        JMenuItem menuItem1 = new JMenuItem("Item 1");
        JMenuItem menuItem2 = new JMenuItem("Item 2");

        fileMenue.add(menuItem1);
        fileMenue.add(menuItem2);

        menuBar.add(fileMenue);
      //menuBar.add(textField); // switch between comment & uncomment to see the difference

        f = new JFrame();
        f.setJMenuBar(menuBar);
        f.add(this);

        f.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                if ((e.getKeyCode() == KeyEvent.VK_Z) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
                    System.out.println("undo");
                }
            }
        });

        f.setSize(400, 400);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }

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

【问题讨论】:

  • 为什么不使用action map / input map呢?
  • @SergeyTachenov - 实际上我没有找到展示如何使用动作映射/输入映射来完成按键组合的示例

标签: java swing jtextfield keylistener jmenubar


【解决方案1】:

添加快捷键的首选方法是使用input map and action map,如下所示:

f.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
        .put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.CTRL_DOWN_MASK),
             "Undo");
f.getRootPane().getActionMap()
        .put("Undo", new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("undo");
    }
});

当然,在实际代码中,您应该定义一个常量,而不是直接硬编码"Undo" 操作名称。并且可能单独定义动作,给它一个适当的名称和其他有用的属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-17
    • 2012-11-29
    • 1970-01-01
    • 2013-12-24
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多