Hello all,
I'm trying to inherit a "CarPanel" I created using arrays to draw various shapes in order to make a car. Now I am trying to essentially create a subclass that inherits that class, but add a Timer Action to move the car across the screen. I got it to work for my non-array using shapes, but the shapes that use the arrays are not working.

Here is my driver:

package drawcar;

import javax.swing.*;

public class DrawCar 
{
    public static void main(String[] args) 
    {
        JFrame frame = new JFrame("Car");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        final MovingCar panel = new MovingCar();
        
        frame.getContentPane().add(panel);
        frame.pack();
        frame.setVisible(true);
    }
}

and my parent class that draws the original car

package drawcar;

import javax.swing.*;
import java.awt.*;

public class CarPanel extends JPanel
{
    private final int W = 700, H = 300;
    private int top = 0;
    protected int mid = 0;
    
    private int xCar[] = {mid + 20, mid + 80, mid + 130, mid + 275, mid + 305, 
        mid + 400, mid + 400, mid + 20 };  //over
    private int yCar[] = {115, 105, 50, 35, 100, 115, 185, 185}; //down
    
    private int xWindow1[] = {130, 163, 152, 97};
    private int yWindow1[] = {62, 60, 100, 102};
    private int xWindow2[] = {180, 265, 272, 168};
    private int yWindow2[] = {55, 50, 95, 98};
    private int xWindow3[] = {275, 280, 304, 285};
    private int yWindow3[] = {50, 48, 95, 98};
    
    private int xMirror[] = {268, 280, 265};
    private int yMirror[] = {80, 105, 115};
    
    private int xBBumper[] = {15, 20, 20, 30, 28, 12};
    private int yBBumper[] = {178, 178, 183, 183, 193, 195};
    
    private int xFBumper[] = {383, 405, 402, 380};
    private int yFBumper[] = {178, 175, 197, 200};
    
    private int xHandle[] = {160, 203, 203, 160};
    private int yHandle[] = {118, 118, 128, 128};
    
    private int xBrake[] = {17, 25, 25, 17};
    private int yBrake[] = {120, 120, 145, 145};
    
    private int xLight[] = {380, 403, 405, 405, 403, 380};
    private int yLight[] = {118, 118, 122, 130, 145, 145};
    
    private int xDoor[] = {176, 265, 280, 300, 283, 275, 155, 145, 155, 176};
    private int yDoor[] = {52, 48, 102, 118, 165, 180, 180, 118, 107, 52};
    
    public CarPanel()
    {        
        setBackground(Color.BLUE);                              //Sky
        setPreferredSize (new Dimension(W, H));
        
    }
     
    public void paintComponent(Graphics page)
    {
        super.paintComponent(page);
        page.setColor(Color.ORANGE);
        page.fillPolygon(xCar, yCar, xCar.length);
        
        page.setColor(Color.CYAN);
        page.fillPolygon(xWindow1, yWindow1, xWindow1.length);  //back window
        page.fillPolygon(xWindow2, yWindow2, xWindow2.length);  //side window
        page.fillPolygon(xWindow3, yWindow3, xWindow3.length);  //Windsheild
        
        page.setColor(Color.GRAY);
        page.fillPolygon(xMirror, yMirror, xMirror.length);
        
        page.setColor(Color.BLACK);
        page.fillOval(mid + 50, top + 150, 100, 100);   //Back tire
        page.fillOval(mid + 275, top + 150, 100, 100);  //Front tire
        
        page.setColor(Color.LIGHT_GRAY);
        page.fillOval(mid + 70, top + 170, 60, 60);     //Back rim
        page.fillOval(mid + 295, top + 170, 60, 60);    //Front rim
        page.fillPolygon(xBBumper, yBBumper, xBBumper.length);  //Back bumper
        page.fillPolygon(xFBumper, yFBumper, xFBumper.length);  //Front bumper
        page.fillPolygon(xHandle, yHandle, xHandle.length);     //Door Handle
        
        page.setColor(Color.GRAY);
        page.fillOval(mid + 80, top + 180, 40, 40);     //back wheel hub
        page.fillOval(mid + 305, top + 180, 40, 40);   //front wheel hub
        
        page.setColor(Color.RED);
        page.fillPolygon(xBrake, yBrake, xBrake.length);        //Brake light
        page.setColor(Color.WHITE);
        page.fillPolygon(xLight, yLight, xLight.length);        //Headlight
        
        page.setColor(Color.BLACK);
        page.drawPolyline(xDoor, yDoor, xDoor.length);
        
        page.setColor(Color.ORANGE);
        //Fill to shape door handle
        page.fillArc(mid + 160, top + 97, 43, 25, 190, 160);
                
        page.setColor(Color.GREEN);
        page.fillRect (0, 250, W, 250);                      //Ground
    }
    
    public int getW()
    {
        return W;
    }
}

and finally, my inherited class to make it move

package drawcar;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class MovingCar extends CarPanel
{
    private final int DELAY = 20;
    private int moveMid = 5;
    private Timer timer;
            
    public MovingCar()
    {
        CarPanel car = new CarPanel();
        
        timer = new Timer(DELAY, new CarListener());
    }
    
    public void paintComponent(Graphics g)
    {
        CarPanel car = new CarPanel();
        
        super.paintComponent(g);
        timer.start();
        
    }
    
    private class CarListener implements ActionListener
    {
        public void actionPerformed(ActionEvent ae)
        {
            mid += moveMid;
            
            if (mid > getW())
            {
                mid = -getW();
            }
            
            repaint();
        }
    }
    
}

I've tried adding the moveMid value to the "x" values (ie. page.fillPolygon(xWindow1 + mid...), but they are of different types (int/int []). I also tried setting my arrays up to be something like:

private int xCar[] = {mid + 20, mid + 80, mid + 130, mid + 275, mid + 305, 
        mid + 400, mid + 400, mid + 20 };

But that doesn't seem to register. Any ideas?

Recommended Answers

All 12 Replies

they are of different types (int/int [])

I'm not sure what your problem is. An element of an int array is an int.
What did the API doc for the method you were trying to use say? Did it take an int or an array of int?

Please post the full text of your error messages that show the source line and the error message.

I'm not sure what your problem is. An element of an int array is an int.
What did the API doc for the method you were trying to use say? Did it take an int or an array of int?

Please post the full text of your error messages that show the source line and the error message.

I get "bad operand types for binary operator '+' first type: int[] second type: int"

That's if I change my

page.fillPolygon(xCar, yCar, xCar.length);

to

page.fillPolygon(xCar + mid, yCar, xCar.length);

If xCar is an int array then you can NOT add an int value to the array with a simple statement like you are trying to do.
If you want to add an int value to each of the elements in the xCar array, you will need a loop to select each element in the array and add to it.

That's what I thought.
I did go back and add lops to update the array values, but when I run the program, the non-Polygon objects move across the window at a much slower rate than the Polygon objects, even though they are incrementing using the same variable. Also, the polygon object rubber band back to the start point to restart the loop, where the non-Polygon objects just keep scrolling. Below is what I have now. Obviously I have a logic error here somewhere, but I don't understand what.

Parent class:

import javax.swing.*;
import java.awt.*;

public class CarPanel extends JPanel
{
    private final int W = 700, H = 300;
    private int top = 0;
    protected int mid = 0;
    
    private int xCar[] = {20, 80, 130, 275, 305, 400, 400, 20 };  //over
    private int yCar[] = {115, 105, 50, 35, 100, 115, 185, 185};  //down
    
    private int xWindow1[] = {130, 163, 152, 97};
    private int yWindow1[] = {62, 60, 100, 102};
    private int xWindow2[] = {180, 265, 272, 168};
    private int yWindow2[] = {55, 50, 95, 98};
    private int xWindow3[] = {275, 280, 304, 285};
    private int yWindow3[] = {50, 48, 95, 98};
    
    private int xMirror[] = {268, 280, 265};
    private int yMirror[] = {80, 105, 115};
    
    private int xBBumper[] = {15, 20, 20, 30, 28, 12};
    private int yBBumper[] = {178, 178, 183, 183, 193, 195};
    
    private int xFBumper[] = {383, 405, 402, 380};
    private int yFBumper[] = {178, 175, 197, 200};
    
    private int xHandle[] = {160, 203, 203, 160};
    private int yHandle[] = {118, 118, 128, 128};
    
    private int xBrake[] = {17, 25, 25, 17};
    private int yBrake[] = {120, 120, 145, 145};
    
    private int xLight[] = {380, 403, 405, 405, 403, 380};
    private int yLight[] = {118, 118, 122, 130, 145, 145};
    
    private int xDoor[] = {176, 265, 280, 300, 283, 275, 155, 145, 155, 176};
    private int yDoor[] = {52, 48, 102, 118, 165, 180, 180, 118, 107, 52};
    
    public CarPanel()
    {        
        setBackground(Color.BLUE);                              //Sky
        setPreferredSize (new Dimension(W, H));
    }
     
    public void paintComponent(Graphics page)
    {
        //update all the arrays for movement  -- Just added this piece
        for(int i=0; i < xCar.length; i++)
           xCar[i] += mid;
        for(int i=0; i < xWindow1.length; i++)
           xWindow1[i] += mid;
        for(int i=0; i < xWindow2.length; i++)
           xWindow2[i] += mid;
        for(int i=0; i < xWindow3.length; i++)
           xWindow3[i] += mid;
        for(int i=0; i < xMirror.length; i++)
           xMirror[i] += mid;
        for(int i=0; i < xBBumper.length; i++)
           xBBumper[i] += mid;   
        for(int i=0; i < xFBumper.length; i++)
           xFBumper[i] += mid; 
        for(int i=0; i < xHandle.length; i++)
           xHandle[i] += mid; 
        for(int i=0; i < xBrake.length; i++)
           xBrake[i] += mid;   
        for(int i=0; i < xLight.length; i++)
           xLight[i] += mid; 
        for(int i=0; i < xDoor.length; i++)
           xDoor[i] += mid;
        
        super.paintComponent(page);
        page.setColor(Color.ORANGE);
        page.fillPolygon(xCar, yCar, xCar.length);
        
        page.setColor(Color.CYAN);
        page.fillPolygon(xWindow1, yWindow1, xWindow1.length);  //back window
        page.fillPolygon(xWindow2, yWindow2, xWindow2.length);  //side window
        page.fillPolygon(xWindow3, yWindow3, xWindow3.length);  //Windsheild
        
        page.setColor(Color.GRAY);
        page.fillPolygon(xMirror, yMirror, xMirror.length);
        
        page.setColor(Color.BLACK);
        page.fillOval(mid + 50, top + 150, 100, 100);   //Back tire
        page.fillOval(mid + 275, top + 150, 100, 100);  //Front tire
        
        page.setColor(Color.LIGHT_GRAY);
        page.fillOval(mid + 70, top + 170, 60, 60);     //Back rim
        page.fillOval(mid + 295, top + 170, 60, 60);    //Front rim
        page.fillPolygon(xBBumper, yBBumper, xBBumper.length);  //Back bumper
        page.fillPolygon(xFBumper, yFBumper, xFBumper.length);  //Front bumper
        page.fillPolygon(xHandle, yHandle, xHandle.length);     //Door Handle
        
        page.setColor(Color.GRAY);
        page.fillOval(mid + 80, top + 180, 40, 40);     //back wheel hub
        page.fillOval(mid + 305, top + 180, 40, 40);   //front wheel hub
        
        page.setColor(Color.RED);
        page.fillPolygon(xBrake, yBrake, xBrake.length);        //Brake light
        page.setColor(Color.WHITE);
        page.fillPolygon(xLight, yLight, xLight.length);        //Headlight
        
        page.setColor(Color.BLACK);
        page.drawPolyline(xDoor, yDoor, xDoor.length);
        
        page.setColor(Color.ORANGE);
        //Fill to shape door handle
        page.fillArc(mid + 160, top + 97, 43, 25, 190, 160);
                
        page.setColor(Color.GREEN);
        page.fillRect (0, 250, W, 250);                      //Ground
    }
    
    public int getW()
    {
        return W;
    }
    public int getMid()
    {
        return mid;
    }
    public int getTop()
    {
        return top;
    }
}

Child class:

package drawcar;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class MovingCar extends CarPanel
{
    private final int DELAY = 20;
    private int moveMid = 5;
    private Timer timer;
            
    public MovingCar()
    {
        CarPanel car = new CarPanel();
        
        timer = new Timer(DELAY, new CarListener());
    }
    
    public void paintComponent(Graphics g)
    {
        CarPanel car = new CarPanel();
        
        super.paintComponent(g);
        timer.start();
        
    }
    
    private class CarListener implements ActionListener
    {
        public void actionPerformed(ActionEvent ae)
        {
            mid += moveMid;
            
            if (mid > getW())
            {
                mid = -getW();
            }
            
            repaint();
        }
    }
    
}

Driver:

package drawcar;

import javax.swing.*;

public class DrawCar 
{
    public static void main(String[] args) 
    {
        JFrame frame = new JFrame("Car");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        final MovingCar panel = new MovingCar();
        
        frame.getContentPane().add(panel);
        frame.pack();
        frame.setVisible(true);
    }
}

What value is in the mid variable?
What is in the moveMid variable? If moveMid is a constant you should make it final.
What value do you want to add to the xCar[] elements?

Print out the value of mid and xCar[0] every time they change to see how your code is changing them and what the results are.

Another method you should look at is in the Graphics class. See if translate will do what you want.

That's an awful lot of drawing to repeat every 20 mSec, especially since nothing changes except an x position offset.
Why not create an Image and draw the car into that just once, then you can draw that Image to the panel's Graphics with a single call, which will be just one place to specify the x position of the whole car?

Not quite following you.

Are you saying draw the car as an object, then just move the whole object "x" pixels over?

James is suggesting you create a BufferedImage, draw your car in the created image and then draw that image at changing locations in paint. You only create the image once and you draw it many times as it moves.

Yes,just like Norm said.

Yes,just like Norm said.

Thanks, I don't know anything about BufferedImages, so I will read up on that and see if I can get it to work. Thanks.

Look for the constructor that has a width/height, and use a type of TYPE_4BYTE_ABGR (ordinary RGB image, with an alpha channel so it can be transparent where you haven't drawn). You'll also find a method that creates a Graphics2D that you can draw your car on to create the actual image.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.