首页 > 解决方案 > 使用 KeyListener 移动矩形

问题描述

我正在尝试使用 KeyListener 移动一个矩形。我见过其他人使用相同的代码,但由于某种原因我无法让它移动。现在矩形确实出现了。我不确定如果我遗漏了什么,我是否忘记了什么。这是我的代码:

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.Graphics;
public class roomwars extends JPanel implements ActionListener, KeyListener {
    //public JPanel pane;
    public JFrame frame;
    public JButton start, help;
    public JTextField box;
    int x=0, y=0, velx =0, vely =0;
    Timer t = new Timer(5, this);
    public void run(){
        frame = new JFrame("ROOM WARS!");
        frame.setSize(700, 700);
        frame.setVisible(true);
        frame.add(this);
    }
    public void second (){
        t.start();
        addKeyListener(this);
        //setFocusalbe(true);
        //SETFocusTraversalKeyEnabled(false);
    }
    public void paintComponent(Graphics g) {
        Color mypurple = new Color(34, 0, 56);
        g.setColor(mypurple);
        g.fillRect(x, y, 30, 30);
        //g.setColor(Color.PINK);
        //g.fillRect(655,632,30,30);
    }

    public void actionPerformed(ActionEvent e){
        repaint();
        x+= velx;
        y+= vely;
    }

     public void keyPressed(KeyEvent e){
        int code = e.getKeyCode();
        if (code == KeyEvent.VK_UP){
            vely = -1;
            velx = 0;
        }
        else if (code == KeyEvent.VK_DOWN) {
            vely = 1;
            velx = 0;
        }
        else if (code == KeyEvent.VK_RIGHT) {
            velx = -1;
            vely = 0;
        }
        else if (code == KeyEvent.VK_LEFT) {
            velx = 1;
            vely = 0;
        }
    }
    public void keyTyped(KeyEvent e){}
    public void keyReleased(KeyEvent e) {}

    public static void main(String[] args) {
        new roomwars().run();
    }

}

标签: javaswinguser-interfacegraphicskeylistener

解决方案


除了不尊重油漆链(和调用super.paintComponent)之外,你的主要问题是使用KeyListener.

少量的搜索会很快告诉您,KeyListener因为不响应而臭名昭著,因为这通常是不可靠的。

最常见的解决方案是使用键绑定 API

以下是在当前代码库中实现键绑定的非常简单的示例

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.IOException;
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.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) throws IOException, InterruptedException {
        new Test();
    }

    public Test() {
        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 RoomWars());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class RoomWars extends JPanel implements ActionListener {
        //public JPanel pane;

        int x = 0, y = 0, velx = 0, vely = 0;
        Timer t = new Timer(5, this);

        public RoomWars() {
            t.start();

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

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "up.pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "up.released");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "down.pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "down.released");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "left.pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "left.released");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "right.pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "right.released");

            am.put("up.pressed", new MoveAction(-1, 0));
            am.put("up.released", new MoveAction(0, 0));
            am.put("down.pressed", new MoveAction(1, 0));
            am.put("down.released", new MoveAction(0, 0));
            am.put("left.pressed", new MoveAction(0, -1));
            am.put("left.released", new MoveAction(0, 0));
            am.put("right.pressed", new MoveAction(0, 1));
            am.put("right.released", new MoveAction(0, 0));
        }

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

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Color mypurple = new Color(34, 0, 56);
            g.setColor(mypurple);
            g.fillRect(x, y, 30, 30);
            //g.setColor(Color.PINK);
            //g.fillRect(655,632,30,30);
        }

        public class MoveAction extends AbstractAction {
            private int yDelta;
            private int xDelta;

            public MoveAction(int yDelta, int xDelta) {
                this.yDelta = yDelta;
                this.xDelta = xDelta;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                vely = yDelta;
                velx = xDelta;
            }
        }

        public void actionPerformed(ActionEvent e) {
            repaint();
            x += velx;
            y += vely;
        }

    }
}

推荐阅读