我可以从KeyListener调用方法吗?

时间:2017-11-08 21:04:50

标签: java swing

我有一个带KeyListener的简单JFrame类和一些方法。

 public class MyClass extends JFrame{
     MyClass(){
        //build window
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
               if(e.getKeyCode() == 32){
                   myMethod();
               }
            }
        });    
     }

     private void myMethod(){
        //do something
     }
 }

如果我从main()调用它,MyMethod可以正常工作。但是从Listener它什么也没做。我可以根据KeyListener调用方法吗?如果答案是否定的,我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

这取决于您希望如何使用JFrame。您需要通过从main()方法实例化它来创建窗口:

public class Main {

    public static void main(String[] args) {
        // this is your frame instance
        MyClass frame = new MyClass();
    }
}

并且您必须实现KeyListener提供的所有方法:

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;

public class MyClass extends JFrame {

    public MyClass() {
        // "this." can be omitted, it is just for better understanding
        // that each method applies to instance of JFrame
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setBounds(50, 50, 300, 300);
        this.setVisible(true);
        // add key listener
        this.addKeyListener(new KeyListener() {

            @Override
            public void keyPressed(KeyEvent e) {

            }

            @Override
            public void keyReleased(KeyEvent e) {
                // call this method on key release
                myMethod(e.getKeyCode());   
            }

            @Override
            public void keyTyped(KeyEvent e) {

            }

        });
    }

    private void myMethod(int key) {
        this.setTitle("Key released: " + key);
    }
}

答案 1 :(得分:0)

KeyListener是...代码中的痛苦。它依赖于它注册的组件是可聚焦的并具有键盘焦点。

通常,更好的解决方案是使用key bindings API。它可以让您更好地控制何时触发绑定。

例如

import java.awt.Dimension;
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.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class MyClass extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                MyClass myClass = new MyClass();
                myClass.pack();
                myClass.setLocationRelativeTo(null);
                myClass.setVisible(true);
            }
        });
    }

    public MyClass() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // This is here because I don't like setSize or setPreferredSize
        JPanel panel = new JPanel() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(300, 300);
            }
        };
        setContentPane(panel);

        InputMap im = panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap am = panel.getActionMap();

        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "spaced");
        am.put("spaced", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                myMethod();
            }
        });
    }

    private void myMethod() {
        System.out.println("Pressed");
    }
}