To avoid a code dump I have removed most of the code and left the first few lines of constructors and methods and anything relevant. Full code at the bottom.
The purpose of this code is to use threads to process the application. Each of the following components needs to run on separate threads: a current time stamp in 1-second intervals, a traffic light display for each intersection, and the speed and position of each "car" as it moves through the lights(obviously stopping at red).
Currently, the GUI accomplishes that, my question is more about whether the threads are accomplishing those objectives correctly. Can someone please review the code and give feedback on what I did right or ways to improve?
Light.java
public class Light {
static Color[] colors = new Color[] { array of colors };
int colorIndex;
int seconds;
Point pos;
public int getSeconds() {return seconds;}
public void setSeconds(int seconds) {}
public Point getPos() {}
public void setPos(Point pos) {}
public void setColorIndex(int c) {}
public Color getColor() {return colors[colorIndex];}
public void transition() {}
Simulator.java
public class Simulator extends JFrame {
ArrayList<Light> lights = new ArrayList<>();
ArrayList<Car> cars = new ArrayList<>();
int ticks = 0;
Timer t;
Random rand = new Random();
JButton btnStart;
JButton btnPause;
Simulator() {
btnStart = new JButton("Start");
btnPause = new JButton("Pause");
btnPause.setEnabled(false);
t = new Timer(100, e -> {clockTicks();});
btnStart.addActionListener(e -> {startSimulation();
t.start();} else {t.stop();}});
btnPause.addActionListener(e -> {t.stop();
} else {t.start();}});}
private void startSimulation() {
lights.clear();
cars.clear();
for loop here}
for loop here Car car = new Car();car.start();}}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {new Simulator();}});}
private Light getLight(double x) {}}}
private void clockTicks() {car.start();}
for loop here}
class Road extends JPanel {
@Override protected void paintComponent(Graphics g) {
super.paintComponent(g);
for loop here}}for loop here}}}}}
Car.java
public class Car extends Thread {
public static final Color[] colors = new Color[] { "colors" };
private double x;
private double velocity;
private Color color;
private Light light;
public double getX() {}
public void setX(double pos) {}
public double getVelocity() {}}
public void setVelocity(double velocity) {}
public Color getColor() {}
public void setColor(Color color) {}
private Boolean isStopped() {}
public void animate() {}}
public Light getLight() {}
public void setLight(Light light) {}
@Override
public void run() {
while(x < 1200) {
try {
Thread.sleep(100);
animate();
} catch (InterruptedException e) {
e.printStackTrace();}}}}
Complete Code
Light.java
package traffic;
import java.awt.Color;
import java.awt.Point;
public class Light {
static Color[] colors = new Color[] { Color.red, Color.green, Color.yellow };
int colorIndex;
int seconds;
Point pos;
public int getSeconds() {
return seconds;
}
public void setSeconds(int seconds) {
this.seconds = seconds;
if (this.seconds == 0) {
transition();
}
}
public Point getPos() {
return pos;
}
public void setPos(Point pos) {
this.pos = pos;
}
public void setColorIndex(int c) {
this.colorIndex = c;
if (colorIndex == 0) {
// red get 15 seconds
seconds = 15;
}
else if (colorIndex == 1) {
seconds = 10;//green light
} else {
seconds = 3;//yellow light
}
}
public Color getColor() {
return colors[colorIndex];
}
public void transition() {
// the light changes!
colorIndex++;
if (colorIndex == colors.length) {
colorIndex = 0;//color index starts at 0
}
if (colorIndex == 0) {
// red get 15 seconds
seconds = 15;
}
else if (colorIndex == 1) {
seconds = 10;//green light
} else {
seconds = 3;//yellow light
}
}
}
Simulator.java
package traffic;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
@SuppressWarnings("serial")
public class Simulator extends JFrame {
ArrayList<Light> lights = new ArrayList<>();
ArrayList<Car> cars = new ArrayList<>();
int ticks = 0;
Timer t;
Random rand = new Random();
JButton btnStart;
JButton btnPause;
Simulator() {
btnStart = new JButton("Start");
btnPause = new JButton("Pause");
btnPause.setEnabled(false);
t = new Timer(100, e -> {
clockTicks();
});
btnStart.addActionListener(e -> {
if (btnStart.getText().equals("Start")) {
startSimulation();
t.start();
btnStart.setText("Stop");
} else {
t.stop();
btnStart.setText("Start");
btnPause.setEnabled(false);
}
});
btnPause.addActionListener(e -> {
if (btnPause.getText().equals("Pause")) {
btnPause.setText("Continue");
t.stop();
} else {
t.start();
btnPause.setText("Pause");
}
});
JPanel jp = new JPanel();
jp.setLayout(new BorderLayout());
JPanel south = new JPanel();
south.setLayout(new FlowLayout());
south.add(btnStart);
south.add(btnPause);
jp.add(south, BorderLayout.SOUTH);
Road road = new Road();
jp.add(road, BorderLayout.CENTER);
getContentPane().add(jp);
}
private void startSimulation() {
lights.clear();
cars.clear();
btnPause.setEnabled(true);
int n = rand.nextInt(2) + 3;
int distance = 1000 / n;
for (int i = 0; i < n; i++) {
Point pos = new Point((i + 1) * distance, 350);
Light l = new Light();
l.setPos(pos);
int c = rand.nextInt(3);
l.setColorIndex(c);
lights.add(l);
}
for (int i = 0; i < 3; i++) {
Car car = new Car();
int c = rand.nextInt(Car.colors.length);
car.setColor(Car.colors[c]);
int v = rand.nextInt(25);
car.setVelocity(v);
int x = rand.nextInt(500);
car.setX(x);
cars.add(car);
car.start();
}
}
public static void main(String[] args) {
Simulator sim = new Simulator();
sim.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
sim.setSize(1200, 700);
sim.setVisible(true);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Simulator();
}
});
}
private Light getLight(double x) {
for (Light light : lights) {
Point point = light.getPos();
double diff = point.x - x;
if (diff < 5 && diff > -1) {
return light;
}
}
return null;
}
private void clockTicks() {
int n = rand.nextInt(100);
ticks++;
if (n == 5) {
Car car = new Car();
int c = rand.nextInt(Car.colors.length);
car.setColor(Car.colors[c]);
int velocity = rand.nextInt(25);
car.setVelocity(velocity);
car.setX(50);
cars.add(car);
car.start();
}
for (Car car : cars) {
double x = car.getX();
Light light = getLight(x);
car.setLight(light);
}
if (ticks % 10 == 0) {
for (Light light : lights) {
int seconds = light.getSeconds();
if (seconds > 0) {
light.setSeconds(seconds - 1);
} else {
light.transition();
}
}
}
getContentPane().repaint();
}
class Road extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Light light : lights) {
if (light != null) {
Point pos = light.getPos();
g.setColor(Color.BLACK);
g.drawString(Integer.toString(light.getSeconds()), pos.x, pos.y - 60);
Color c = light.getColor();
g.setColor(c);
g.fillOval(pos.x, pos.y, 40, 40);
g.drawLine(pos.x + 20, pos.y + 20, pos.x + 20, pos.y + 60);
}
}
int i = 0;
for (Car car : cars) {
if (car != null) {
Color c = car.getColor();
g.setColor(c);
int x = (int) car.getX();
g.fillRect(x, 400, 20, 20);
g.setColor(Color.black);
g.drawString(String.format("(%.0f, 0) %.2f kmh",
car.getX(), car.getVelocity()), x, 470 + (i % 5) * 10);
i++;
}
}
}
}
}
Car.java
package traffic;
import java.awt.Color;
public class Car extends Thread {
public static final Color[] colors = new Color[] { Color.blue, Color.lightGray, Color.cyan, Color.magenta };
private double x;
private double velocity;
private Color color;
private Light light;
public double getX() {
return x;
}
public void setX(double pos) {
this.x = pos;
}
public double getVelocity() {
if(!isStopped()) {
return velocity;
}
return 0;
}
public void setVelocity(double velocity) {
this.velocity = velocity;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
private Boolean isStopped() {
if (light == null) return false;
if(light.getColor().equals(Color.red)) return true;
return false;
}
public void animate() {
if (! isStopped()) {
x += (velocity * 0.1);
}
}
public Light getLight() {
return light;
}
public void setLight(Light light) {
this.light = light;
}
@Override
public void run() {
while(x < 1200) {
try {
Thread.sleep(100);
animate();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
this. Light = light;
(similar for color, etc.) doesn't make much sense and won't compile. \$\endgroup\$a.b
into an English sentence ending,a. B
. \$\endgroup\$