简体   繁体   中英

timer.schedule() in not working at all (in Java)

I made a simple program in Java which draws a rectangle on a canvas. And then the rectangle starts moving along X-axis, from left to right. But the timer.schedule() function is not working. Following is the code:-

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.
    }

}

But the strange thing is... Every time i'm maximizing and restoring the frame, the box is moving. Why is this happening?

"But the strange thing is... Every time i'm maximizing and restoring the frame, the box is moving. Why is this happening?"

Because repaint() is called when you resize which update the graphics, which you should be doing, instead of trying to call paint .

But...

Still many things wrong.

Seeing as this is your first animation (package firstanimation;), let me get you started in the right direction.

  1. Don't use Canvas. Use JPanel or JComponent instead. When you do, don't override paint but paintComponent instead. Also make sure you call super.paintComponent so you aren't let with any paint artifact during the animation.

     public class MyCanvas extends JPanel { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); //painting code } } 
  2. Never use getGraphics on a component to do any painting.

  3. You shouldn't ever have to explicitly call paint . The paint[Component] method will be implicitly called for you. A simple call to repaint() will repaint the component.

  4. I just realized you're using all AWT components. Don't use them, they're out-dated. Instead use Swing component. The majority of them are just prefixed with a J , like Frame -> JFrame . They are in the javax.swing.* package.

  5. For animation use a javax.swing.Timer . You can see more at How to Use Timers . The basic construct is

     Timer ( int delayInMillis, ActionListener listener ) 

    where delayInMillis is the time to delay between ticks(in this case animations) and the ActionListener listens for "ticks". Each tick, the actionPerformed of the ActionListener is called. There, you can put the code to update any variables you use for animation.


I suggest you read the tutorials Performing Custom Painting to see the proper way to paint.

Here's a simple example with all the points above mentioned

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class AnimateBall extends JPanel {

    private static final int D_W = 500;
    private static final int D_H = 300;

    private Ball ball;

    public AnimateBall() {
        Random rand = new Random();
        int randX = rand.nextInt(D_W);
        int randY = rand.nextInt(D_H);
        ball = new Ball(randX, randY);

        Timer timer = new Timer(15, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ball.animate();

                repaint();
            }
        });
        timer.start();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
            ball.drawBall(g);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(D_W, D_H);
    }

    public class Ball {

        int x = 0;
        int y = 0; // Current ball position
        int dx = 4; // Increment on ball's x-coordinate
        int dy = 4; // Increment on ball's y-coordinate
        int radius = 15; // Ball radius

        public Ball(int x, int y) {
            this.x = x;
            this.y = y;
        }

        Color color = new Color((int) (Math.random() * 256),
                (int) (Math.random() * 256), (int) (Math.random() * 256));

        public void drawBall(Graphics g) {
            g.setColor(color);
            g.fillOval(x - radius, y - radius, radius * 2, radius * 2);
        }

        public void animate() {
            if (x < 0 || x > getWidth()) {
                dx = -dx;
            }
            if (y < 0 || y > getHeight()) {
                dy = -dy;
            }
            // Adjust ball position
            x += dx;
            y += dy;
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new AnimateBall());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM