I have a \"car\" made with various objects using graphics g and I want to move it when a button is pressed. With that, I had no problem, but I have a problem with its path. When
It looks like the problem lies with your implementation. You could create a class for your Car objects and each car object keep track of their own coordinates.
For your case, if you are only moving the cars only when the button is clicked, you don't even need a Timer. Just update the car's position in the ActionListener for every button click.
OUTPUT:
class Car
{
private Color carColor;
private int x, y;
private int speed;
private static int carWidth = 100;
private static int carHeight = 30;
public Car(Color carColor, int speed){
this.carColor = carColor;
this.speed = speed;
x = 0;
y = 0;
}
public void moveTo(int x, int y){
this.x = x;
this.y = y;
}
public void draw(Graphics g){
//Draw a car object
g.setColor(carColor);
g.fillRect(x, y, carWidth, carHeight);
g.setColor(Color.BLACK);
//Draw Wheels
g.fillOval(x, y+carHeight, 30, 30);
g.fillOval(x+carWidth-30, y+carHeight, 30, 30);
}
public int getX(){return x;}
public int getY(){return y;}
public int getSpeed(){return speed;}
}
So when you move your car(s), just update their positions and that's all you need to do. Pay special attention to my paintComponent()
method. You should keep that method simple and clutter free. It is only responsible for painting. All the movements of cars is done else where.
class DrawingSpace extends JPanel implements ActionListener{
Car c1, c2, c3;
public DrawingSpace(){
setPreferredSize(new Dimension(800, 400));
c1 = new Car(Color.RED, 5);
c2 = new Car(Color.GREEN, 8);
c3 = new Car(Color.BLUE, 10);
c1.moveTo(10, 50);
c2.moveTo(10, 180);
c3.moveTo(10, 280);
}
public void moveCars(){
}
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
c1.draw(g);
c2.draw(g);
c3.draw(g);
}
@Override
public void actionPerformed(ActionEvent e){
//Used for timer (to animate moving cars)
c1.moveTo((c1.getX()+c1.getSpeed()), c1.getY());
c2.moveTo(c2.getX()+c2.getSpeed(), c2.getY());
c3.moveTo(c3.getX()+c3.getSpeed(), c3.getY());
if(c1.getX() > 800)
c1.moveTo(0, c1.getY());
if(c2.getX() > 800)
c2.moveTo(0, c2.getY());
if(c3.getX() > 800)
c3.moveTo(0, c3.getY());
repaint();
}
}
For a task like this, it will be better and easier to use javax.swing.timer
instead of implementing your own loop with Thread.sleep()
.
class MovingCars{
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run() {
JFrame f = new JFrame("Moving Cars");
DrawingSpace ds = new DrawingSpace();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(ds);
f.pack();
f.setLocationRelativeTo(null);
Timer t = new Timer(50, ds); //Delay of 50 milliseconds
t.start();
}
});
}
}