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

除了不尊重绘制链(并调用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; } } } 

请注意,在您的代码段中,未调用second()因此未注册键侦听器。 您的面板也需要可以集中精力才能接收重要的新闻事件。 您可能还希望先在方法中调用super.paintComponent()

详情请见此处:

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