我正在关注 HeadFirst Java第二版并试图通过点击按钮执行一个简单的圆圈动画,从一个点对角移动。 我正在使用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();
}
}
}
答案 0 :(得分:1)
对repaint()的调用将重绘请求放入队列中;你可能会认为它会立即重新粉刷屏幕。您的请求全部堆叠在此队列中等待执行,然后有效地立即执行。
你需要一个计时器,而不是调用Thread.sleep(),以便在不同的动画之间设置距离。 java.util中提供了一个计时器,但您应该使用Swing中的计时器。
我建议谷歌搜索“Java中的动画”,其中有几个网站详细解释了这些内容。
答案 1 :(得分:0)
我发现您在类animate()
中声明了SimpleAnimation
函数,但是您正在调用类OnclickListener
中的函数。这是不可能的。在方法OnclickListener
中的课程actionPerformed
中,您正在调用函数animate()
,这意味着this.animate()
。因此,程序试图找到animate()
类中的OnclickListener
函数,该函数无法找到应该产生编译错误的函数。
为了做你想做的事,你可以在SimpleAnimation
变量中将OnclickListener
的引用传递给类simpleAnimation
,然后调用simpleAnimation.animate()
并且它应该工作。