KeyListener有效,但不是

时间:2014-03-27 03:29:09

标签: java swing keyboard keylistener japplet

我对keylistener很新,但最近我做了一个小程序,它将在下面,它使用keylistener使A,W,S,D键移动一个正方形。好吧,我使用Dropbox来获取这台笔记本电脑上的程序,现在它不起作用。我觉得它可以在键盘上工作,但在笔记本电脑键盘上却不行,这似乎很奇怪。有什么想法吗?这是代码,很好的一部分:

   public class Game extends JApplet implements KeyListener
{
    public boolean isMoving = false;
    int test = 0;
    Rect r = new Rect();
            public void keyPressed(KeyEvent e){}
            public void keyReleased(KeyEvent e){} // ignore
            public void keyTyped(KeyEvent e)
            {
                char keyChar = e.getKeyChar();
                if (keyChar == KeyEvent.VK_S)
                    {
                        r.yVelocity -= 1;
                    }
                if (keyChar == KeyEvent.VK_W)
                    {
                        r.yVelocity+=1;
                    }
                if (keyChar == KeyEvent.VK_A)
                    {
                        r.xVelocity -=1;
                    }
                if (keyChar == KeyEvent.VK_D)
                    {
                        r.xVelocity +=1;
                    }
            }

1 个答案:

答案 0 :(得分:2)

KeyListener有焦点问题。也就是说,它只会在可聚焦且具有焦点时响应关键事件。

简单的解决方案是使注册KeyListener的组件可以聚焦并使用requestFocusInWindow,但这并不能使组件获得关键板的重点。

更好的解决方案是使用Key Bindings API,它允许您配置引发关键事件所需的焦点水平......

使用键绑定示例/测试

进行了更新
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestKeyBindings {

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

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

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

    public class KeyPane extends JPanel {

        private Triangle up;
        private Triangle down;
        private Triangle left;
        private Triangle right;

        private Set<String> activeKeys;

        public KeyPane() {
            activeKeys = new HashSet<>(4);

            up = new Triangle(20);
            down = new Triangle(20);
            left = new Triangle(20);
            right = new Triangle(20);

            AffineTransform at = AffineTransform.getRotateInstance(Math.toRadians(-90), 10, 10);
            left.transform(at);
            at = AffineTransform.getRotateInstance(Math.toRadians(180), 10, 10);
            down.transform(at);
            at = AffineTransform.getRotateInstance(Math.toRadians(-270), 10, 10);
            right.transform(at);

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "upPressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "downPressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "leftPressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "rightPressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "upReleased");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "downReleased");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "leftReleased");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "rightReleased");

            ActionMap am = getActionMap();
            am.put("upPressed", new DirectionAction("up", true));
            am.put("downPressed", new DirectionAction("down", true));
            am.put("leftPressed", new DirectionAction("left", true));
            am.put("rightPressed", new DirectionAction("right", true));
            am.put("upReleased", new DirectionAction("up", false));
            am.put("downReleased", new DirectionAction("down", false));
            am.put("leftReleased", new DirectionAction("left", false));
            am.put("rightReleased", new DirectionAction("right", false));
        }

        public void addKey(String name) {
            activeKeys.add(name);
            repaint();
        }

        public void removeKey(String name) {
            activeKeys.remove(name);
            repaint();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            int x = (getWidth() - (up.getBounds().width * 3)) / 2;
            int y = (getHeight() - 10) / 2;

            AffineTransform at = AffineTransform.getTranslateInstance(x, y);
            if (activeKeys.contains("left")) {
                g2d.fill(left.createTransformedShape(at));
            } else {
                g2d.draw(left.createTransformedShape(at));
            }
            at = AffineTransform.getTranslateInstance(x + 40, y);
            if (activeKeys.contains("right")) {
                g2d.fill(right.createTransformedShape(at));
            } else {
                g2d.draw(right.createTransformedShape(at));
            }
            at = AffineTransform.getTranslateInstance(x + 20, y - 20);
            if (activeKeys.contains("up")) {
                g2d.fill(up.createTransformedShape(at));
            } else {
                g2d.draw(up.createTransformedShape(at));
            }
            at = AffineTransform.getTranslateInstance(x + 20, y + 20);
            if (activeKeys.contains("down")) {
                g2d.fill(down.createTransformedShape(at));
            } else {
                g2d.draw(down.createTransformedShape(at));
            }

            g2d.dispose();
        }

        public class DirectionAction extends AbstractAction {

            private String name;
            private boolean pressed;

            public DirectionAction(String name, boolean pressed) {
                this.name = name;
                this.pressed = pressed;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                if (pressed) {
                    addKey(name);
                } else {
                    removeKey(name);
                }
            }

        }
    }

    public class Triangle extends Path2D.Double {

        public Triangle(int size) {

            moveTo(size / 2, 0);
            lineTo(size, size);
            lineTo(0, size);
            closePath();

        }

    }

}