绘制2个球在Java上向不同方向移动但是一个消失了

我正在尝试创建一个可以绘制2个球的程序,其中一个在北方中心,另一个在南方中心。 我需要向不同方向移动球,北方的第一个球随机向南移动,另一个球向南移动向北移动。 我可以让North Center球向下移动,但是南方的第二个球在被拉出之后就消失了。

PS:我需要有2个内部类,分别是Ball1Ball2 。 请帮忙。 非常感谢。

问题…

  1. Event Dispatching Thread中的while-loop ,用于调整图形对象的位置
  2. paint方法中的Thread.sleep
  3. 不调用super.paintComponent
  4. paintComponent方法中更新对象的状态。

Swing使用单线程模型,该模型负责(其中包括)将重绘请求分派给所有组件。

在EDT中执行任何停止处理这些事件的操作将阻止Swing重新绘制UI。 这将使您的动画看起来像一步一步突然从开始到结束。

有关更多详细信息,请参阅Swing中的Concurrency 。 特别是,看看初始线程和如何使用Swing Timers

我应该强调点4-

您无法控制重绘周期。 重绘请求可能会因为您没有要求的多种原因而引发,这些原因会导致您的对象更新超出您的控制范围或您不希望它们更新。 您永远不应该在任何paint方法中更改UI的任何部分的状态。

简单的例子

这是一个非常简单的示例,但它演示了在Swing中进行任何动画时需要理解的基本概念

 public class SimpleBouncyBall { public static void main(String[] args) { new SimpleBouncyBall(); } public SimpleBouncyBall() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ex) { } JFrame frame = new JFrame("Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new CourtPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class CourtPane extends JPanel { private Ball ball; private int speed = 5; public CourtPane() { Timer timer = new Timer(40, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Rectangle bounds = new Rectangle(new Point(0, 0), getSize()); if (ball == null) { ball = new Ball(bounds); } speed = ball.move(speed, bounds); repaint(); } }); timer.setRepeats(true); timer.setCoalesce(true); timer.start(); } @Override public Dimension getPreferredSize() { return new Dimension(100, 100); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (ball != null) { Graphics2D g2d = (Graphics2D) g.create(); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Point p = ball.getPoint(); g2d.translate(px, py); ball.paint(g2d); g2d.dispose(); } } } public class Ball { private Point p; private int radius = 12; public Ball(Rectangle bounds) { p = new Point(); px = 0; py = bounds.y + (bounds.height - radius) / 2; } public Point getPoint() { return p; } public int move(int speed, Rectangle bounds) { px += speed; if (px + radius >= (bounds.x + bounds.width)) { speed *= -1; px = ((bounds.x + bounds.width) - radius) + speed; } else if (px <= bounds.x) { speed *= -1; px = bounds.x + speed; } py = bounds.y + (bounds.height - radius) / 2; return speed; } public void paint(Graphics2D g) { g.setColor(Color.RED); g.fillOval(0, 0, radius, radius); } } }