使用JButton启动简单动画

时间:2015-05-02 10:41:27

标签: java swing animation event-dispatch-thread thread-sleep

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

2 个答案:

答案 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()并且它应该工作。