【发布时间】:2014-07-23 19:38:04
【问题描述】:
我有以下代码用于从左上角到右下角为球设置动画。
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class MainFrame{
int i=0,j=0;
JFrame frame = new JFrame();
public void go(){
Animation anim = new Animation();
anim.setBackground(Color.red);//Why color is not changing to red for the panel.
frame.getContentPane().add(anim);
frame.setVisible(true);
frame.setSize(475,475);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
for(i=0,j=0;i<frame.getHeight()&&j<frame.getWidth();++i,++j){
anim.repaint();//Main problem is here,described below.
try{
Thread.sleep(50);
}
catch(Exception ex){}
}
}
public static void main(String[] args) {
MainFrame mf = new MainFrame();
mf.go();
}
class Animation extends JPanel{
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D)g;
g.fillOval(i,j,25,25);
}
}
}
问题
- 当我在方法
go中执行anim.repaint()时,我没有让球从左上角动画到右下角,但它会沿着路径涂抹。但是如果我用frame.repaint()替换它,我会得到想要的结果是一个移动的球。那么这两个对repaint的调用有什么区别? - 为什么在
go方法中anim.setBackground(Color.red);之后面板的颜色没有改变? - 如果你运行这个程序,你会发现球并没有完全在底部边缘,那么我怎样才能做到这一点?
【问题讨论】:
-
不要在 EDT 上睡觉; 做见Concurrency in Swing和How to Use Swing Timers;在这个可能的duplicate 中检查了一个完整的示例。
-
Don't sleep on the EDT- 这总是个好建议,但循环代码实际上并未在 EDT 上执行,因为您没有正确创建 GUI。所有 GUI 组件都应该在 EDT 上创建。这是通过使用上面链接的教程中演示的SwingUtilities.invokeLater()方法完成的。但是,一旦这样做,您将遇到绘画问题,因为您将导致 EDT 休眠,这意味着在循环结束之前它无法绘制移动的球。因此,您需要按照建议使用计时器。 -
@camickr 做了一个重要的观察:你在initial thread 上睡觉 在调用
setVisible(); EDT 将开始异步运行,结果将不可预测。
标签: java swing animation background paintcomponent