【发布时间】:2015-05-02 10:41:27
【问题描述】:
我正在关注 HeadFirst Java 2nd Edition 并尝试执行一个简单的动画,即单击一个按钮即可从一个点斜向另一个点移动一个圆圈。 我正在使用 JPanel 绘制圆圈和 ActionListener 接口以从按钮获取事件。 当我直接从 'main()' 调用 animate 函数时,动画效果很好。但是当我点击按钮后尝试这样做时,程序冻结并直接显示最终结果。
代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SimpleAnimation{
int x=70;
int y=70;
JFrame frame;
MyDrawPanel drawPanel;
public static void main(String[] args) {
SimpleAnimation gui=new SimpleAnimation();
gui.initialize();
// gui.animate(); //animation method
}
public void initialize(){
frame=new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawPanel=new MyDrawPanel();
frame.getContentPane().add(BorderLayout.CENTER,drawPanel);
frame.setSize(400,400);
frame.setVisible(true);
JButton button=new JButton("Click me!");
frame.getContentPane().add(BorderLayout.EAST,button);
button.addActionListener(new OnclickListener());
}
public void animate(){
for (int i=0;i<130 ;i++ ) {
x++;
y++;
drawPanel.repaint();
try{
Thread.sleep(50);
}catch(Exception e){}
}
}
class MyDrawPanel extends JPanel{
public void paintComponent(Graphics g){
g.setColor(Color.white);
g.fillRect(0,0,this.getWidth(), this.getHeight());
g.setColor(Color.green);
g.fillOval(x,y,40,40);
}
}
class OnclickListener implements ActionListener{
public void actionPerformed(ActionEvent event){
animate();
}
}
}
【问题讨论】:
-
你应该看看
Timerdocumentation。您不应该在 UI 线程上休眠(或执行任何其他非 UI 逻辑),因为它会阻止重绘您的 GUI。 -
请参阅 Detection/fix for the hanging close bracket of a code block 了解我无法再费心解决的问题。
-
不要阻塞 EDT(事件调度线程)。发生这种情况时,GUI 将“冻结”。有关详细信息和修复,请参阅 Concurrency in Swing。
标签: java swing animation event-dispatch-thread thread-sleep