使用JButton启动简单动画

Using JButton to start simple animation

我正在关注 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();
            }
        }
}

我发现您在 class SimpleAnimation 中声明了 animate() 函数,但您在 class OnclickListener 中调用了该函数。这不可能。当在 class OnclickListener 方法 actionPerformed 中调用函数 animate() 时,这意味着 this.animate()。所以程序试图在 OnclickListener class 中找到 animate() 函数,但找不到它应该给出编译错误。

为了做你想做的事,你将 SimpleAnimation 的引用传递给 class OnclickListener 在变量中说 simpleAnimation 然后调用simpleAnimation.animate() 它应该可以工作。

调用 repaint() 将重绘请求放入队列;您可能认为它会立即重新绘制屏幕。您的请求都堆积在这个队列中等待执行,然后实际上所有请求都立即执行。

您需要一个计时器,而不是调用 Thread.sleep() 来设置不同动画之间的距离。 java.util 中提供了一个计时器,但您应该使用 Swing 中的计时器。

我建议在 "animation in Java" 上进行 google 搜索,那里有几个网站详细解释了事情。