简体   繁体   English

使用KeyListener移动矩形

[英]Moving a Rectangle Using KeyListener

I'm trying to get a rectangle to move using KeyListener. 我正在尝试使用KeyListener使矩形移动。 I have seen others use the same code but for some reason I can't get it to move. 我见过其他人使用相同的代码,但是由于某种原因我无法移动它。 Right now the rectangle does show up. 现在,矩形确实出现了。 I'm not sure if I'm forgetting something if there is something I'm missing. 如果不确定我缺少什么,我不确定是否会忘记。 Here's my code: 这是我的代码:

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

}

Apart from not honouring the paint chain (and calling super.paintComponent ), you're primary issue is the use of KeyListener . 除了不遵守绘画链(并调用super.paintComponent )之外,主要的问题是KeyListener的使用。

A short amount of searching will tell you quickly that KeyListener is notorious for not responding as is generally unreliable. 一小段搜索就会很快告诉您KeyListener因通常不可靠而没有响应而臭名昭著。

The most common solution is to use the key bindings API 最常见的解决方案是使用键绑定API

The following is very simply example of implementing key bindings into your current code base 以下是将键绑定实现到当前代码库中的非常简单的示例

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

    }
}

Note that in your code snippet, second() isn't called so the key listener isn't registered. 请注意,在您的代码段中,未调用second()因此未注册键侦听器。 Your panel also needs to be focusable in order to receive key press events. 您的面板还需要具有焦点,以便接收按键事件。 You may also want to call super.paintComponent() first in your method. 您可能还想先在方法中调用super.paintComponent()

See here for details: 详细信息请参见此处:

https://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html https://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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