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
.
Still many things wrong.
Seeing as this is your first animation (package firstanimation;), let me get you started in the right direction.
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 } }
Never use getGraphics
on a component to do any painting.
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.
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.
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.