当前位置: 首页 > 知识库问答 >
问题:

如何使用箭头键移动JPanel中的对象

暨正真
2023-03-14

我正在尝试用Windowbuilder创建一个小程序,它只需在JPanel中绘制一个红色矩形(称为car1),并通过按箭头键来移动它;为了做到这一点,我将一个改变x位置的方法与箭头相关联,并调用Repait方法,但矩形根本不移动——因此,我可能会把KeyEvent和/或Repait搞砸。

每次按正确的箭头键移动并刷新面板时,我应该怎么做才能使矩形移动并刷新面板?

public class Car extends JPanel {
    int x;
    int y;

    public Car(int x,int y){
        this.x=x;
        this.y=y;
    }


    public void paint(Graphics g) {
        g.setColor(Color.RED);
        g.fillRect(x, y, 20, 20);
    }

    public void move_right(){
        x=x+20;
    }

    public void move_left(){
        x=x-20;
    }

}



public class Form extends JFrame {

    //private JPanel contentPane;
    Car car1;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Form frame = new Form();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Form() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 727, 550);
        getContentPane().setLayout(null);
        car1 = new Car(350, 480);
        car1.addKeyListener(new KeyAdapter() {
            public void keyTyped(KeyEvent e) {
                int key = e.getKeyCode();
                if (key == KeyEvent.VK_KP_LEFT) {
                    car1.move_left();
                    car1.repaint();
                }
                if (key == KeyEvent.VK_KP_RIGHT) {
                    car1.move_right();
                    car1.repaint();
                }
            }
        });
        car1.setBounds(0, 0, 700, 500);
        car1.setBackground(new Color(255, 255, 255));
        getContentPane().add(car1);
    }

}

共有2个答案

金谭三
2023-03-14

这是一个解决方案:

addKeyListener(new KeyAdapter() {
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_LEFT) {
            car1.move_left();
            car1.repaint();
        }
        if (key == KeyEvent.VK_RIGHT) {
            car1.move_right();
            car1.repaint();
        }
    }
});

错误在哪里:

  1. addKeyListener:将密钥侦听器添加到帧,而不是面板
  2. VK_KP_u:改用VK_前缀
  3. keyTyped:使用按键

下一步你必须解决的是删除以前的矩形

单淳
2023-03-14

至少有3个问题:

  1. 使用KeyListener<众所周知,code>KeyListener只响应可聚焦且具有键盘焦点的组件上发生的按键事件。默认情况下,JPanel不可聚焦,因此无法接收键盘聚焦。更好的解决方案是使用键绑定API,它允许定义组件在触发绑定之前必须具有的焦点级别,并允许您对多个键重复使用操作,减少代码重复

例如

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 javax.swing.AbstractAction;
import javax.swing.Action;
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 Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                    ex.printStackTrace();
                }

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

    public class TestPane extends JPanel {

        private int xPos;

        public TestPane() {
            Action leftAction = new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    xPos -= 2;
                    if (xPos < 0) {
                        xPos = 0;
                    }
                    repaint();
                }
            };
            Action rightAction = new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    xPos += 2;
                    if (xPos + 10 > getWidth()) {
                        xPos = getWidth() - 10;
                    }
                    repaint();
                }
            };

            bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.left", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), leftAction);
            bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.left", KeyStroke.getKeyStroke(KeyEvent.VK_KP_LEFT, 0), leftAction);
            bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.left", KeyStroke.getKeyStroke(KeyEvent.VK_4, 0), leftAction);
            bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.left", KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), leftAction);

            bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.right", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), rightAction);
            bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.right", KeyStroke.getKeyStroke(KeyEvent.VK_KP_RIGHT, 0), rightAction);
            bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.right", KeyStroke.getKeyStroke(KeyEvent.VK_6, 0), rightAction);
            bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.right", KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), rightAction);
        }

        protected void bindKeyStroke(int condition, String name, KeyStroke keyStroke, Action action) {
            InputMap im = getInputMap(condition);
            ActionMap am = getActionMap();

            im.put(keyStroke, name);
            am.put(name, action);
        }

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

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int yPos = (getHeight() - 10) / 2;
            g2d.drawRect(xPos, yPos, 10, 10);
            g2d.dispose();
        }

    }

}
 类似资料:
  • 我现在正在实验JavaFX,教自己如何使用箭头键移动文本和项。我做了一个程序,如果按下箭头键,就可以简单地在舞台上移动文本。 我想使一个圆圈移动我的窗格,而不是文本。要使用箭头键移动我的圆圈,我必须做哪些更改?

  • 问题内容: 我正在尝试创建一个简单游戏的开始。我要做的第一件事是将图形导入到我的代码中,然后在屏幕上移动它。我能够在屏幕上画一个球并四处移动,但是当我从文件导入图形时,无法四处移动。我想念什么或做错什么? 我的司机是在另一个班级,如下所示: 问题答案: 这里有两个大问题: 您正在从中读取文件。 永远 不要这样做,因为这会不必要地减慢绘图速度。可能在构造函数中读取一次图像,然后在图形中使用存储的im

  • 问题内容: 我正在尝试通过keyEvent向左移动一个圆圈。到目前为止,圆已在窗口上绘制,但不会向左移动!我觉得问题是我在容器中添加了Window()构造函数。在控制台上没有输出告诉我它正在工作。因此,我认为它甚至不会到达KeyEvent类。这是我的代码: 问题答案: 实际上,这是您要添加到的内容,但重点是,因此,当您键入内容时,该内容将转到与类无关的内容。因此,为了克服它,你只需要调用的类的对象

  • 问题内容: 我在JScrollPane中有一个JTextArea组件,并且文本区域不可编辑。我想使用向上和向下箭头键滚动文本区域(即,按箭头键将文本区域滚动一行)。任何想法如何实现这一目标? 问题答案: 是的,键绑定是必经之路,但是您不一定总是需要创建自己的动作。Swing组件带有您经常可以重用的默认操作。 有关这些操作的完整列表,请参见键绑定。 现在您知道了动作名称,您可以将其绑定到keyStr

  • 我有一个名为“DisplayPanel”的类(它扩展了JPanel),我在那里画了一个正方形,它来自一个名为“square”的类(它扩展了JComponent)。如何使用键在JPanel中移动矩形? 正方形类有通常的绘制方法: “squarishThing”是一个普通矩形: 问题是:与“游戏库”不同,尝试“手动”做这样的事情是相当令人困惑的。我不知道“while循环”去哪里了。我试图在显示面板中放

  • 问题内容: 所有四个箭头键(左上右下)的utf8代码是什么? 我正在学习node.js,并且试图检测何时按下了这些键。 这是我的工作,但是没有一个能捕获箭头键…我是node.js的新手,所以我在这里可能做得很愚蠢。 谢谢。 问题答案: 您可以使用按键包。尝试页面上给出的示例。 您可以按顺序获取箭头键的UTF-8值。