Java对象移动

我试图让一个圆圈通过键盘输入。 我根本无法移动物体。 有人能帮我弄清楚出了什么问题吗? 这是我的代码:

import java.awt.Color; import java.awt.Graphics; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JPanel; public class AlienInvader extends JPanel implements KeyListener{ Constants constant = new Constants(); public void update() { constant.x += constant.xvel; addKeyListener(this); } public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.MAGENTA); g.fillOval(constant.x, constant.y, 30, 30); repaint(); } @Override public void keyPressed(KeyEvent e) { System.out.println(constant.x); switch(e.getKeyCode()) { case KeyEvent.VK_LEFT: constant.xvel = -1; break; case KeyEvent.VK_RIGHT: constant.xvel = 1; break; } } @Override public void keyReleased(KeyEvent e) { switch(e.getKeyCode()) { case KeyEvent.VK_LEFT: constant.xvel = -1; break; case KeyEvent.VK_RIGHT: constant.xvel = 1; break; } } @Override public void keyTyped(KeyEvent arg0) { // TODO Auto-generated method stub } } 

我不确定我做错了什么。 我以为是因为我没有调用update方法,但是当我在paintComponent中添加一个if语句(所以它只调用一次)并尝试了它时,我没有运气。

首先,不要在任何paintXxx方法中调用repaint 。 通常会调用绘制方法来响应repaint的调用,因此您正在创建一个讨厌的,永无止境的,永远消耗的资源地狱循环。

其次, KeyListener只响应键事件1-注册的组件是可聚焦的2-当他们注册的组件具有焦点时。

在这种情况下,他们是一个糟糕的选择。 请改用键绑定

第三,您没有为布局管理器提供preferredSize提示。 在你的情况下这可能是坏事,也可能不是坏事,但你的组件可能会被布局为0x0

就像是….

 import java.awt.BorderLayout; import java.awt.Color; 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.ActionListener; import java.awt.event.KeyEvent; 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 MoveCircle { public static void main(String[] args) { new MoveCircle(); } public MoveCircle() { 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 TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private int xDelta = 0; private int keyPressCount = 0; private Timer repaintTimer; private int xPos = 0; private int radius = 10; public TestPane() { InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); ActionMap am = getActionMap(); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "pressed.left"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "pressed.right"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "released.left"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "released.right"); am.put("pressed.left", new MoveAction(-2, true)); am.put("pressed.right", new MoveAction(2, true)); am.put("released.left", new MoveAction(0, false)); am.put("released.right", new MoveAction(0, false)); repaintTimer = new Timer(40, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { xPos += xDelta; if (xPos < 0) { xPos = 0; } else if (xPos + radius > getWidth()) { xPos = getWidth() - radius; } repaint(); } }); repaintTimer.setInitialDelay(0); repaintTimer.setRepeats(true); repaintTimer.setCoalesce(true); } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); g2d.setColor(Color.RED); g2d.drawOval(xPos, 0, radius, radius); g2d.dispose(); } public class MoveAction extends AbstractAction { private int direction; private boolean keyDown; public MoveAction(int direction, boolean down) { this.direction = direction; keyDown = down; } @Override public void actionPerformed(ActionEvent e) { xDelta = direction; if (keyDown) { if (!repaintTimer.isRunning()) { repaintTimer.start(); } } else { repaintTimer.stop(); } } } } } 

例如…