简体   繁体   English

JButton KeyPressed-什么都不会发生

[英]JButton KeyPressed - Nothing Happens

I'm trying to make it so that pressing the right arrow key does the same thing as pressing a JButton . 我正在尝试使其按右箭头键与按JButton相同。 I can bind the right arrow key to the button itself - but that means I have to have pressed the button before the right key works. 我可以将右箭头键绑定到按钮本身-但这意味着我必须先按一下按钮才能使用右键。 Now I'm trying to see if binding to the actual JFrame is what I want, but I can't get anything to happen when I bind to the frame at all: 现在,我正在尝试查看是否要绑定到实际的JFrame ,但是当我完全绑定到框架时,什么也没发生:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    onButtonPress();
}                                        

private void formKeyPressed(java.awt.event.KeyEvent evt) {                                
    if (evt.getKeyCode() == KeyEvent.VK_RIGHT){
        onButtonPress();
    }
} 

private void onButtonPress() {
    pressNum++;
    jLabel1.setText("Button has been pressed " + pressNum + " times.");
}

在此处输入图片说明

As a general rule of thumb, you should avoid KeyListener . 作为一般经验法则,应避免使用KeyListener The main reason is, in order for a KeyListener to generate key events, the component it is registered to must be focusable AND have keyboard focus. 主要原因是,为了使KeyListener生成键事件,其注册到的组件必须是可聚焦的并且具有键盘焦点。 In your case, this would probably mean adding a KeyListener to every component in your UI which "might" gain keyboard focus, not something which is practical in the real world. 在您的情况下,这可能意味着向您的UI中的每个组件添加“可能”获得键盘焦点的KeyListener ,而不是在现实世界中实用的东西。

Instead, you should make use of the Key Bindings API , which provides you the means to define the level of focus required in order for it to trigger the associated actions. 相反,您应该使用Key Bindings API ,它为您提供了定义所需焦点级别的方法,以便它触发关联的操作。

The Key Bindings API and the example make use of the Action s API , which allows me to define a single unit of work which can be applied to a number of "actionable" controls Key Bindings API和示例使用了Action的API ,这使我可以定义一个单一的工作单元,该单元可以应用于多个“可操作的”控件

The example also makes use of a delegate/callback/listener (namely CounterListener ) which allows me to decouple the "side effects" from the action itself. 该示例还利用了委托/回调/侦听器(即CounterListener ),它使我可以将“副作用”与动作本身分离。

This basically means that the Action can do what it needs to do, but "other" interested parties can perform some other action when it changes. 这基本上意味着该Action可以执行其需要执行的操作,但是“其他”相关方可以在其更改时执行其他操作。 You could, equally attach an ActionListener to the Action , but this was just simpler and quicker to implement 您可以将ActionListener附加地附加到Action ,但这只是实现起来更加简单快捷。

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            JLabel label = new JLabel("...");
            MyAwesomeAction action = new MyAwesomeAction(new CounterListener() {
                @Override
                public void counterChanged(int count) {
                    label.setText("Button has been pressed " + count + " times");
                }
            });

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            JButton button = new JButton(action);
            add(button, gbc);
            add(label, gbc);

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "MakeItSo");
            am.put("MakeItSo", action);
        }

    }

    public interface CounterListener {

        public void counterChanged(int count);
    }

    public class MyAwesomeAction extends AbstractAction {

        private int count;
        private CounterListener listener;

        public MyAwesomeAction(CounterListener listener) {
            putValue(NAME, "Make it so");
            this.listener = listener;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            count++;
            listener.counterChanged(count);
        }

    }

}

This example has a JButton with two listeners: an ActionListener and and a KeyListener . 此示例具有一个JButton带有两个侦听器: ActionListenerKeyListener The key listener is implemented with the KeyAdapter abstract class. 密钥侦听器通过KeyAdapter 抽象类实现。 From the API documentation: 从API文档中:

KeyAdapter is for receiving keyboard events. KeyAdapter用于接收键盘事件。 The methods in this class are empty. 此类中的方法为空。 This class exists as convenience for creating listener objects. 此类的存在是为了方便创建侦听器对象。

Create a listener object using the extended class and then register it with a component using the component's addKeyListener method. 使用扩展类创建一个侦听器对象,然后使用组件的addKeyListener方法将其注册到组件。 When a key is pressed, released, or typed, the relevant method in the listener object is invoked, and the KeyEvent is passed to it. 按下,释放或键入某个键时,将调用侦听器对象中的相关方法,并将KeyEvent传递给它。

The example code: 示例代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ButtonListeners {
    private JLabel label;
    private int counter;
    public static void main(String [] args) {
        new ButtonListeners().gui();
    }
    private void gui() {
        JFrame frame = new JFrame();
        frame.setTitle("JButton Listeners");
        JButton button = new JButton("jButton1");
        button.addActionListener(actionEvent -> displayLabel());
        button.addKeyListener(new ButtonKeyPressListener());
        label = new JLabel("Press button or -> key");
        frame.add(button, BorderLayout.SOUTH);
        frame.add(label, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setSize(300, 150);        
        frame.setVisible(true);
    }
    private void displayLabel() {
        label.setText("Action count: " + ++counter);
    }
    private class ButtonKeyPressListener extends KeyAdapter {
        @Override public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_RIGHT){
                displayLabel();
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM