如果我在for循环后添加球,为什么球不出现在框架中?

该程序让球从左上角到右下角滑动并起作用。 但如果我要改变界限

frame.getContentPane().add(ball); 

从当前位置到for循环之后,为什么球不会出现在框架上。 我同意球不应再移动,因为在我将球添加到JFrame之前,所有在for循环中完成的移动都会发生,但我不明白为什么当我最终将球放在屏幕上时将其添加到框架中。 这是工作程序的代码,如果你将上面提到的线移到for循环之后,球就不再出现了

 import java.awt.*; import javax.swing.*; import java.awt.event.*; public class Animate { private JFrame frame; private int x,y; public static void main(String args[]) { Animate ballRoll = new Animate(); ballRoll.go(); } public void go() { frame = new JFrame(); frame.setSize(500,500); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); MyRoll ball = new MyRoll(); frame.getContentPane().add(ball); for(x = 5;x<=350;x++) { y=x; try { Thread.sleep(50); } catch(Exception e) { System.out.println("dsfsd"); } ball.repaint(); } } class MyRoll extends JPanel { public void paintComponent(Graphics g) { g.setColor(Color.BLACK); g.fillRect(0, 0, this.getWidth(), this.getHeight()); g.setColor(Color.ORANGE); g.fillOval(x, y, 100, 100); } } } 

有些要记住的要点:

  1. 不要使用Thread.sleep() ,有时挂起整个swing应用程序,而不是尝试使用最适合swing应用程序的Swing Timer 。

    阅读更多如何使用摆动计时器

  2. 不要忘记在重写的paintComponent()方法中调用super.paintComponent()

  3. 添加所有组件后,最后调用frame.setVisible(true)

  4. 使用frame.pack()而不是frame.setSize(500,500) ,根据组件的首选大小调整组件。

  5. 在自定义绘制的情况下,覆盖getPreferredSize()以设置JPanel的首选大小。

  6. 使用SwingUtilities.invokeLater()或EventQueue.invokeLater()确保正确初始化EDT 。

    阅读更多

    • 为什么在main方法中使用SwingUtilities.invokeLater?

    • SwingUtilities.invokeLater

    • 我们是否应该在Java桌面应用程序中使用EventQueue.invokeLater进行任何GUI更新?


示例代码:( 根据您的自定义绘画更改

 private Timer timer; ... timer = new javax.swing.Timer(50, new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { y = ++x; ball.repaint(); if (x > 350) { timer.stop(); } } }); timer.setRepeats(true); timer.start(); public static void main(String args[]) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { Animate ballRoll = new Animate(); ballRoll.go(); } }); } class MyRoll extends JPanel { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); ... } @Override public Dimension getPreferredSize() { return new Dimension(..., ...); } }