timer.schedule()根本不工作(用Java)

时间:2014-06-19 11:59:13

标签: java swing animation timer awt

我在Java中创建了一个简单的程序,它在画布上绘制一个矩形。然后矩形开始沿着X轴从左向右移动。 但是timer.schedule()函数不起作用。以下是代码: -

package firstanimation;

import java.awt.*;
import java.util.Timer;


public class FirstAnimation {

    public static void main(String[] args) {

        Frame frame = new Frame("SomeRandomName");

        frame.setBounds(50, 50, 700, 500);
        frame.setBackground(Color.red);

        MyCanvas canvas = new MyCanvas();

        frame.add(canvas);
        frame.setVisible(true);

        Graphics graph = frame.getGraphics();

        Timer timer = new Timer();
        Task task = new Task(canvas, graph);

        timer.schedule(task, 1000,1000);

    }
}



package firstanimation;
import java.awt.*;

public class MyCanvas extends Canvas{

    public int x,y,width,height;

    public MyCanvas()
    {
        x = 0;
        y = 0;
        width = 50;
        height = 50;
    }

    @Override
    public void paint(Graphics g) {
        g.setColor(Color.LIGHT_GRAY);
        g.fillRect(x, y, width, height);
    }

    @Override
    public void update(Graphics g) {
        x+=10;
        g.fillRect(x, y, width, height);
    }



}



package firstanimation;
import java.util.TimerTask;
import java.awt.Graphics;

public class Task extends TimerTask{

    private MyCanvas canvas;
    private Graphics graphics;

    public Task(MyCanvas can, Graphics g)
    {
        super();
        canvas = can;
        graphics = g;
        canvas.paint(g);
    }

    @Override
    public void run() {
        canvas.update(graphics);
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

}

但奇怪的是......每当我最大化并恢复框架时,框就会移动。 为什么会这样?

1 个答案:

答案 0 :(得分:4)

  

"但奇怪的是......每当我最大化并恢复框架时,框就会移动。为什么会这样?"

因为调整大小时会调用repaint()来更新图形,应该做什么,而不是尝试调用paint

但是......

还有很多不妥之处。

看到这是你的第一个动画(包装第一个动画;),让我开始你的正确的方向。

  1. 不要使用Canvas。请改用JPanelJComponent。如果您这样做,请不要覆盖paint,而是覆盖paintComponent。另外,请务必致电super.paintComponent,这样您就不会在动画过程中使用任何油漆工件。

    public class MyCanvas extends JPanel {
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
    
            //painting code
        }
    }
    
  2. 切勿在组件上使用getGraphics进行任何绘画。

  3. 您不应该明确致电paint。将隐式调用paint[Component]方法。对repaint()的简单调用将重新绘制该组件。

  4. 我刚刚意识到您正在使用所有AWT组件。不要使用它们,它们已经过时了。而是使用Swing组件。其中大部分都以J为前缀,如Frame - > JFrame。它们位于javax.swing.*包中。

  5. 对于动画,请使用javax.swing.Timer。您可以在How to Use Timers查看更多信息。基本结构是

    Timer ( int delayInMillis, ActionListener listener )
    

    其中delayInMillis是在刻度线之间延迟的时间(在本例中为动画),而ActionListener则为"刻度线"。每个标记都会调用actionPerformed的{​​{1}}。在那里,您可以放置​​代码来更新用于动画的任何变量。


  6. 我建议你阅读教程Performing Custom Painting以了解正确的绘画方式。

    这是一个简单的例子,其中包含上述所有要点

    ActionListener