0

I've been coding a traffic simulation in Java, and now want to animate the simulation using swing. I'm calling the RoadNetwork class in my main function as follows:

RoadNetwork roadnetwork = new RoadNetwork();

The getcoords() function gets each vehicle's position as an xy coordinate for use in plotting the vehicles on the JPanel. My main class' name is AMEC. The spawned variable shows whether a vehicle has spawned in the simulation, the finished variable indicates whether it has exited the simulation, the vehiclecounter variable shows the total amount of vehicles throughout the simulation, and the iconNumber variable holds the index of which truckIcon said vehicle is assigned to.

However, when I run my main program, I receive no visual output whatsoever. What am I doing wrong? Also, what is the best way to insert a timer and updating my view with this program?

    public class RoadNetwork extends JPanel {
// create array size of the amount of trucks generated
BufferedImage truckicons[] = new BufferedImage[100];
int populated[] = new int[100]; // array that indicates the identifier of the truck occupying the corresponding position in truckicons[]

public RoadNetwork() throws IOException{
for (int i = 0; i < 100; i++) {
    populated[i] = -1;  // initialization value
    truckicons[i] = ImageIO.read(getClass().getResource("Truck.png"));  // assign icon to each truck
}
}


protected void paintComponent (Graphics g) {
super.paintComponent(g);
int coords[] = new int[2];
for (int i = 0; i < 100; i++) {
    if (populated[i] != -1) {
    coords = AMEC.getcoord(populated[i]);
    g.drawImage(truckicons[i], coords[0], coords[1], this);
    }
}
for (int k = 0; k < AMEC.vehiclecounter; k++) {
    if (AMEC.vehicle[k].spawned == true && AMEC.vehicle[k].finished == false) { // if the truck is somewhere on the plant
    if (AMEC.vehicle[k].iconNumber == -1) { // if the vehicle hasn't been assigned an icon yet
        for (int l = 0; l < 100; l++) {
        if (populated[l] == -1) {
            populated[l] = k;
            AMEC.vehicle[k].iconNumber = l;
            break;
        }
        }
    }
    }
    else if (AMEC.vehicle[k].spawned == true && AMEC.vehicle[k].finished == true && AMEC.vehicle[k].iconNumber != -1) { // if the vehicle is done but hasn't been cleared from the icon list yet
    populated[AMEC.vehicle[k].iconNumber] = -1;
    AMEC.vehicle[k].iconNumber = -1;
    }
}
this.repaint();
}
}
Martin
  • 277
  • 2
  • 5
  • 17

2 Answers2

1

If you need to perform tasks in background, like an animation, you should use Swingworker. This class allows you to perform a long task in the background (in another thread) and bring back changes to the UI in a managed manner that will be executed in the right thread.

http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html

Someone filled a nice tutorial here:

How do I use SwingWorker in Java?

Community
  • 1
  • 1
Jorge_B
  • 9,712
  • 2
  • 17
  • 22
1

"Also, what is the best way to insert a timer and updating my view with this program?"

Use a javax.swing.Timer. The basic structure is simple. It's just like using a button with an ActionListener, but instead the Timer fires the ActionEvent every so many millisecond, based on the duration you pass it. The constructor looks like this

Timer(int duration, ActionListener)

So a sample usage would be something like this, where 50 is the duration for every event to be fired

public RoadNetwork() {

    Timer timer = new Timer(50, new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            // do something with image positions like loop through an array to move coordinates
            repaint();
        }
    });
    timer.start();
}

Also, there's no need to call repaint() inside the paintComponent() method

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720