除非先单击JButton,否则keyPressed不起作用

时间:2018-12-11 08:53:42

标签: java focus jbutton keylistener

我创建了一个使用JButton递增数字的小应用程序。这些按钮不是可单击的,而是由键盘激活的(即textField中的数字随键盘的按下而增加,而不是通过鼠标单击按钮来增加)。我的问题是,在首次启动该应用程序时,键盘没有执行任何操作,直到我先单击其中一个按钮为止-即使单击该按钮不会执行任何操作。我试图制作一个按钮requestFocusInWindow()的想法是,如果它已经集中在上面,那么这些键就可以工作,但是无论将其放在主方法还是控制器类中,这似乎都行不通。我试图弄清楚是否需要执行KeyboardFocusManageraddFocusListener()(但是我不希望按钮获得/失去焦点时总会发生某些事情)。我已经尝试了很多东西,试图将其添加到带有frame的主方法或控制器类中。下面是我当前的代码:

主类的

import javax.swing.JFrame;

public class Count {

    public static void main(String[] args) {
        CountController frame = new CountController();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(560, 150); 
        frame.setVisible(true); 
        //I've tried to add the button and requestFocusInWindow here
        //as well as tried a frame.addWindowFocusListener
    }
} // end class

控制器类

imports ...
public class CountController extends JFrame implements KeyListener {
    private JLabel ...
    private JTextField ...
    private JButton ....
    int ...
    // no-argument constructor
    public CountController() {
        super("Title");
        setLayout(null); // position GUI components explicitly

        //set up JLabels in following manner
        label = new JLabel("some label");
        label.setBounds(47, 5, 45, 25);
        label.setHorizontalAlignment(JLabel.CENTER);
        add(label);

        //set up JTextFields in following manner
        textField = new JTextField("0");
        textField.setBounds(47, 30, 45, 25);
        textField.setHorizontalAlignment(JTextField.CENTER);
        textField.setBackground(Color.WHITE);
        textField.setEditable(false);
        add(textField);

        //set up JButtons in the following manner
        button = new JButton("some text");
        button.setBounds(15, 70, 110, 25);
        button.setBackground(Color.WHITE);
        add(button);
        button.addKeyListener(this);
        //I've tried adding requestFocusInWindow() here as well
    } // end constructor

    //begin KeyListener stuff
    @Override
    public void keyPressed(KeyEvent event){
        int keyCode = event.getKeyCode();
        switch(keyCode){
            case #: //# is ASCII #
                do some things;
                call a method();
                break;
        }
    }
    @Override
    public void keyReleased(KeyEvent event){
        button.setBackground(Color.WHITE);
    }
    @Override
    public void keyTyped(KeyEvent event){
        // nothing but this is needed for implementing KeyListener
    }

    //List of methods that are called from switch
        ...

    //I've tried to add a public void initialize(){}

}//end CountController class

对于使此功能生效,我将不胜感激,这样我就不必在按键起作用之前先单击一个按钮。 谢谢!

2 个答案:

答案 0 :(得分:1)

为了使侦听器触发事件​​,其注册到的组件必须首先成为焦点并具有焦点。请改用key bindings API

以下内容使用x = np.asarray(img, dtype=dtype)定义将在其下生成键事件的上下文。在这种配置下,什么焦点都没有关系,只要窗口当前处于焦点状态,事件仍然会生成

JComponent.WHEN_IN_FOCUSED_WINDOW

尽管我是将绑定绑定到父容器而不是按钮,但仅是我。

而且,不使用import java.awt.Color; 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.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JTextField; import javax.swing.KeyStroke; public class Count { public static void main(String[] args) { CountController frame = new CountController(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(560, 150); frame.setVisible(true); //I've tried to add the button and requestFocusInWindow here //as well as tried a frame.addWindowFocusListener } public static class CountController extends JFrame { // no-argument constructor public CountController() { super("Title"); setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = GridBagConstraints.REMAINDER; //set up JLabels in following manner JLabel label = new JLabel("some label"); label.setHorizontalAlignment(JLabel.CENTER); add(label, gbc); //set up JTextFields in following manner JTextField textField = new JTextField("0", 20); textField.setHorizontalAlignment(JTextField.CENTER); textField.setBackground(Color.WHITE); textField.setEditable(false); add(textField, gbc); //set up JButtons in the following manner JButton button = new JButton("some text"); add(button, gbc); InputMap im = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); ActionMap am = button.getActionMap(); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_3, KeyEvent.SHIFT_DOWN_MASK), "Pressed.#"); am.put("Pressed.#", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { textField.setText(textField.getText() + "#"); } }); } // end constructor }//end CountController class } // end class 布局的原因...这就是您原始代码在我的PC上的样子

Reasons for not using null layouts

答案 1 :(得分:-1)

尽管我不太清楚您的代码应该完成什么操作,但是您的问题是您addKeyListener(this)button,但是按钮没有焦点并且键没有任何作用当按下。尝试将KeyListener()添加到其他GUI组件,例如textfield,因为它是第一个组件,并且着重于start(从您提供的代码开始),然后看是否有效。