简体   繁体   中英

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 . 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:

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 . 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. 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.

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.

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

The example also makes use of a delegate/callback/listener (namely CounterListener ) which allows me to decouple the "side effects" from the action itself.

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. You could, equally attach an ActionListener to the Action , but this was just simpler and quicker to implement

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 . The key listener is implemented with the KeyAdapter abstract class. From the API documentation:

KeyAdapter is for receiving keyboard events. 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. When a key is pressed, released, or typed, the relevant method in the listener object is invoked, and the KeyEvent is passed to it.

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();
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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