如果我在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); } } }
有些要记住的要点:
-
不要使用
Thread.sleep()
,有时挂起整个swing应用程序,而不是尝试使用最适合swing应用程序的Swing Timer 。阅读更多如何使用摆动计时器
-
不要忘记在重写的
paintComponent()
方法中调用super.paintComponent()
。 -
添加所有组件后,最后调用
frame.setVisible(true)
。 -
使用
frame.pack()
而不是frame.setSize(500,500)
,根据组件的首选大小调整组件。 -
在自定义绘制的情况下,覆盖
getPreferredSize()
以设置JPanel
的首选大小。 -
使用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(..., ...); } }