Java KeyListener没有响应

时间:2016-04-25 22:29:53

标签: java keylistener

请原谅我,如果我问的问题太大,我会尝试学习编码,而且我认为我错过了关于KeyListiner的详细信息。我正在尝试制作一个简单的程序,以便骰子和#34;并且当用户按下键时显示数字1到6的图片。我的程序似乎没有响应任何用户输入。

我做错了什么?

感谢您的帮助,我只是想学习,所以任何建议都表示赞赏。

public class Dice   {

 public static void  main (String arg[]) {
     new DD(); 
 }
}   

class DD extends JPanel {   
DD(){

    JFrame frame = new JFrame();
    ImageIcon icon = new ImageIcon("dice.jpg");
    JLabel label = new JLabel(icon);
    frame.add(label);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
    addKeyListener(new Roll());
    }   
}

class Roll extends JFrame implements KeyListener {

public void keyPressed(KeyEvent event){}
public void keyReleased(KeyEvent event){}
public void keyTyped(KeyEvent event){   
    int d = event.getKeyCode();
    if(d == KeyEvent.VK_UP){
        int roll = (int) (Math.random()*6) + 1;
        System.out.println(roll);
  }
 }  
}   

1 个答案:

答案 0 :(得分:1)

让我们仔细看看你的DD班级......

class DD extends JPanel {

    DD() {

        JFrame frame = new JFrame();
        ImageIcon icon = new ImageIcon("dice.jpg");
        JLabel label = new JLabel(icon);
        frame.add(label);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
        addKeyListener(new Roll());
    }
}
  • 您在JFrame的构造函数中创建JPanel的实例,这是一个值得怀疑的行为......
  • 您创建了JLabel并将其添加到JFrame
  • 您显示JFrame
  • 您向KeyListener DD
  • 添加了JPanel

但是等一下,DD永远不会附加到任何可见组件,它怎么能够接收到关键事件?!

KeyListener仅在其注册的组件可聚焦且具有焦点时才有效,但如果它从未在屏幕上显示,则它永远不会有焦点!

首先,我要避免使用KeyListener,它有与焦点相关的问题,而是使用Key Bindings API

例如......

import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Dice {

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

    public Dice() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new DD());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    class DD extends JPanel {

        DD() {
            setLayout(new GridBagLayout());
            JLabel label = new JLabel(" - ");
            add(label);

            addKeyBindingFor(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "Action.roll", new DiceRollAction(label));
        }

        protected void addKeyBindingFor(KeyStroke keyStroke, String name, Action action) {
            InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap actionMap = getActionMap(); 

            inputMap.put(keyStroke, name);
            actionMap.put(name, action);
        }

        public class DiceRollAction extends AbstractAction {

            private JLabel label;

            public DiceRollAction(JLabel label) {
                this.label = label;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                int roll = (int) (Math.random() * 6) + 1;
                label.setText(Integer.toString(roll));
            }
        }

    }

}