【问题标题】:How to stop spacebar from triggering click effect on a button?如何阻止空格键触发按钮的点击效果?
【发布时间】:2017-06-25 20:29:28
【问题描述】:

我创建了一个 jframe,并添加了一个按钮,单击该按钮后,它会要求您按下任何按钮,该按钮也会显示在按钮上。
(它的显示应该是这样的 -> “点击我” -> “按任意按钮” -> “空格键”)
我的问题 1 是,我不想通过按空格键从“单击我”转到“按任意按钮”。
我的问题 2 是,当我在“按任意按钮”并按空格键时,在释放时,它会回到“按任意按钮”而不是停留在“空格键”。
这是我的代码。

    public class Test {

/**
 * @param args the command line arguments
 */

static class starton implements ActionListener {
    private JButton button;
    private JFrame frame;

    public starton(JButton button, JFrame frame) {
        this.button = button;
        this.frame = frame;
    }

    public void actionPerformed(ActionEvent e) {
        button.setText("Press A Button");
        button.setSize(button.getPreferredSize());
        button.addKeyListener(
        new KeyListener() {
            @Override 
            public void keyPressed(KeyEvent e){
                String text = null;

                    char a = e.getKeyChar();
                    text = ""+a+"";
                    if (a == ' '){
                        text = "Space Bar";
                    }

                button.setText(""+text+"");
                button.setSize(button.getPreferredSize());
                button.removeKeyListener(this);
            }

            @Override
            public void keyTyped(KeyEvent e) {
            }

            @Override
            public void keyReleased(KeyEvent ke) {
            }
        });
    }
}

public static void main(String[] args) throws IOException {

    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    double width = screenSize.getWidth();
    double height = screenSize.getHeight();
    int frame1w = 600;
    int frame1h = 400;

    JFrame frame1 = new JFrame("Foo");
    frame1.setSize(frame1w, frame1h);
    frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel contentPane = new JPanel();
    contentPane.setBackground(Color.WHITE);
    contentPane.setLayout(null);
    frame1.setContentPane(contentPane);

    JButton button1 = new JButton("Click Me");
        button1.setSize(button1.getPreferredSize());
        button1.addActionListener(new starton(button1, frame1));
            // add more code here
        contentPane.add(button1);
        frame1.setVisible(true);
}

}

【问题讨论】:

    标签: java swing netbeans actionlistener keylistener


    【解决方案1】:

    JButton 安装了一系列键绑定来控制用户输入

    你可以使用类似...的东西来检查这些是什么

    JButton btn = new JButton("Test");
    InputMap im = btn.getInputMap();
    for (KeyStroke ik : im.allKeys()) {
        System.out.println(ik + " = " + im.get(ik));
    }
    

    在我的系统上,它会打印

    pressed SPACE = pressed
    released SPACE = released
    

    这告诉我 Space 键绑定到操作键 pressedreleased

    要禁用这些键,您需要提供自己的绑定...

    Action blankAction = new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
        }
    };
    
    ActionMap am = btn.getActionMap();
    am.put("pressed", blankAction);
    am.put("released", blankAction);
    

    这只是将pressedreleased 绑定替换为空的Action,它什么都不做。

    现在,提醒一句 - 不同平台/外观和感觉上的键绑定可能不同;您还应该注意,用户通常对某些控件可以做什么和不能做什么有一个预定义的期望,更改它们会影响他们对您的程序的反应

    关于你的第二个问题,button 仍然使用你最初注册的 ActionListener,所以每当你按 Space 时,它会再次触发 ActionListener,并添加一个新的KeyListener 这会让你的问题更加复杂

    您要么想对两个按钮使用单独的 ActionListener,要么想在按钮第一次触发时从按钮中删除 ActionListener - 我会选择第二个,这样更容易理解代码

    不,我的意思是,如果我禁用空格键的“按下”,当我在“按下任意按钮”时,我可以按下它吗?

    最简单的解决方案是使用两个不同的按钮,一个带有一个 ActionListener 来设置另一个按钮,它附加了一个 KeyListener

    如果由于某种原因您“真的”不想这样做,那么您需要在按钮第一次触发时从按钮中删除 ActionListener

    static class starton implements ActionListener {
    
        //...
    
        public void actionPerformed(ActionEvent e) {
            button.setText("Press A Button");
            button.setSize(button.getPreferredSize());
            button.addKeyListener(...);
            button.removeActionListener(this);
        }
    }
    

    【讨论】:

    • 关于第一个,为什么我要禁用空格键的“按下”?这不应该是重点吗?我的意思是按空格键?我也没有多个按钮,它只是 1 .. 同样在第二个问题上,我尝试成功删除动作侦听器,但我希望能够多次执行该例程,而不仅仅是一次跨度>
    • 它把你的整个问题当作“如何阻止空格键触发按钮上的点击效果?”和“我不想从“点击我”通过按空格键来“按任意按钮”。” 意思是,您想禁用按钮的 [空格] 栏功能。 " 我也没有多个按钮,它只有 1 个" - 是的,这就是你的“核心”问题;
    • " 我尝试成功删除动作侦听器,但我希望能够多次执行该例程,而不仅仅是一次" 那么?同样,两个按钮将有助于解决您遇到的许多问题。您可以根据需要简单地将它们交换到位。因为您在按钮上同时注册了一个KeyListener 和一个ActionListener,所以每次按下[空格],它们都会被触发,在我看来,你只是在自找麻烦,使用两个更容易解决(或更多)按钮,每个按钮都有自己的目标功能
    • 还有那些 am.put 是什么?
    • 查找ActionMap
    【解决方案2】:

    问题是由于您在动作侦听器中对KeyListener 的嵌套控制而出现的。由于 Space Bar 是相当于单击按钮的默认键盘按钮,因此每次您点击 Space Bar actionPerformed 按钮 ActionListener 的方法都会被触发。如果您得到ActionEventactionCommand 并打印它,您就会看到这种情况。您还可以使用它来控制执行哪些代码。像这样:

    public void actionPerformed(ActionEvent e) 
    {
        System.out.println("Button Action: " + e.getActionCommand());
        if(e.getActionCommand().equals("Click Me"))
        {
            //Your existing code but remove this line
            //button.removeKeyListener(this);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-11
      • 1970-01-01
      • 2020-09-14
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多