Reputation: 161
I am new to Java swing. I want to create 2 cars that move from one end of the screen to another and for now I am testing it out with one.
But after three movements(indicated by "In paint component" printed 3 times) there is no movement.
I have attached the complete code below.
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Polygon;
public class Application {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame("Demo");
Car car = new Car();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(car);
f.pack();
f.setVisible(true);
Thread thread = new Thread(car);
thread.start();
}
});
}
}
class Car extends JPanel implements Runnable {
private int xBase = 0, yBase = 50;
@Override
public Dimension getPreferredSize() {
return new Dimension(250, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("In paint component");
xBase = xBase + 20;
// Draw two wheels
g.setColor(Color.BLACK);
g.fillOval(xBase + 10, yBase - 10, 10, 10);
g.fillOval(xBase + 30, yBase - 10, 10, 10);
// Draw the car body
g.setColor(Color.BLUE);
g.fillRect(xBase, yBase - 20, 50, 10);
// Draw the top
g.setColor(Color.DARK_GRAY);
Polygon polygon = new Polygon();
polygon.addPoint(xBase + 10, yBase - 20);
polygon.addPoint(xBase + 20, yBase - 30);
polygon.addPoint(xBase + 30, yBase - 30);
polygon.addPoint(xBase + 40, yBase - 20);
g.fillPolygon(polygon);
}
@Override
public void run() {
try {
validate();
repaint();
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println(ex.getMessage());
}
}
}
What am I doing wrong.?
Upvotes: 2
Views: 310
Reputation: 22484
You need to call the repaint()
method in a loop in order for the car to continue moving after you start the thread.
For example:
@Override
public void run() {
int limit = 10;
try {
while (limit > 0) {
limit--;
repaint();
Thread.sleep(1000);
}
} catch (InterruptedException ex) {
System.out.println(ex.getMessage());
}
}
Currently the repaint()
method gets called three time but you don't see any movement because the repaint takes place before the Car
object is completely visible.
In response to your comment: You can create a method to draw the car like so:
private void drawCar(Graphics g, int x, int y) {
g.fillOval(x, y, 10, 10);
g.fillOval(x + 20, y, 10, 10);
// Draw the car body
g.setColor(Color.BLUE);
g.fillRect(x - 10, y - 10, 50, 10);
// Draw the top
g.setColor(Color.DARK_GRAY);
Polygon polygon = new Polygon();
polygon.addPoint(x, y - 10);
polygon.addPoint(x + 10, y - 20);
polygon.addPoint(x + 20, y - 20);
polygon.addPoint(x + 30, y - 10);
g.fillPolygon(polygon);
}
and call it in the paintComponent(...)
method multiple times:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("In paint component");
xBase = xBase + 20;
drawCar(g, xBase, yBase);// draw the first car
drawCar(g, xBase + 80, yBase);// draw the second car 80 pixels ahead
drawCar(g, xBase, yBase + 100); // draw the third car 100 pixels lower
g.dispose();
}
Upvotes: 2