Traffic Simulator

Traffic simulator with GUI.
This commit is contained in:
Fernando Méndez 2020-09-17 20:09:51 +02:00 committed by GitHub
parent 725180763f
commit d5a97c6c95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
92 changed files with 5552 additions and 0 deletions

View File

@ -0,0 +1,10 @@
To run, you must compile the "launcher/Main.java" file, with one of the example arguments:
Example command lines:
//
-i resources/examples/ex1.json
-i resources/examples/ex1.json -t 300
-i resources/examples/ex1.json -o resources/tmp/ex1.out.json
-i resources/examples/ex1.json -m gui
-i resources/examples/ex1.json -t 100 -m console
--help

View File

@ -0,0 +1,73 @@
package extra.dialog;
import javax.swing.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings("serial")
public class DialogWindowExample extends JFrame {
public DialogWindowExample() {
super("Custom Dialog Example");
initGUI();
}
private void initGUI() {
JPanel mainPanel = new JPanel();
this.setContentPane(mainPanel);
mainPanel.add(new JLabel("Click "));
JButton here = new JButton("HERE");
here.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
select_food();
}
});
mainPanel.add(here);
mainPanel.add(new JLabel(" to select your food"));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
protected void select_food() {
// if you're in a JPanel class, you can use the following
//
// (Frame) SwingUtilities.getWindowAncestor(this)
//
// in order to get the parent JFrame. Then pass it to the constructor
// of MyDialogWindow instead of 'this'
//
MyDialogWindow dialog = new MyDialogWindow(this);
List<Dish> dishes = new ArrayList<Dish>();
for (int i = 0; i < 10; i++) {
dishes.add(new Dish("Yum Yum " + i));
}
int status = dialog.open(dishes);
if (status == 0) {
System.out.println("Canceled");
} else {
System.out.println("Your favorite dish is: " + dialog.getDish());
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new DialogWindowExample();
}
});
}
}

View File

@ -0,0 +1,18 @@
package extra.dialog;
public class Dish {
private String _name;
Dish(String name) {
_name = name;
}
public String get_name() {
return _name;
}
@Override
public String toString() {
return _name;
}
}

View File

@ -0,0 +1,115 @@
package extra.dialog;
import javax.swing.JPanel;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
class MyDialogWindow extends JDialog {
private static final long serialVersionUID = 1L;
private int _status;
private JComboBox<Dish> _dishes;
private DefaultComboBoxModel<Dish> _dishesModel;
public MyDialogWindow(Frame parent) {
super(parent, true);
initGUI();
}
private void initGUI() {
_status = 0;
setTitle("Food Selector");
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
setContentPane(mainPanel);
JLabel helpMsg = new JLabel("Select your favorite");
helpMsg.setAlignmentX(CENTER_ALIGNMENT);
mainPanel.add(helpMsg);
mainPanel.add(Box.createRigidArea(new Dimension(0, 20)));
JPanel viewsPanel = new JPanel();
viewsPanel.setAlignmentX(CENTER_ALIGNMENT);
mainPanel.add(viewsPanel);
mainPanel.add(Box.createRigidArea(new Dimension(0, 20)));
JPanel buttonsPanel = new JPanel();
buttonsPanel.setAlignmentX(CENTER_ALIGNMENT);
mainPanel.add(buttonsPanel);
_dishesModel = new DefaultComboBoxModel<>();
_dishes = new JComboBox<>(_dishesModel);
viewsPanel.add(_dishes);
JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
_status = 0;
MyDialogWindow.this.setVisible(false);
}
});
buttonsPanel.add(cancelButton);
JButton okButton = new JButton("OK");
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (_dishesModel.getSelectedItem() != null) {
_status = 1;
MyDialogWindow.this.setVisible(false);
}
}
});
buttonsPanel.add(okButton);
setPreferredSize(new Dimension(500, 200));
pack();
setResizable(false);
setVisible(false);
}
public int open(List<Dish> dishes) {
// update the comboxBox model -- if you always use the same no
// need to update it, you can initialize it in the constructor.
//
_dishesModel.removeAllElements();
for (Dish v : dishes)
_dishesModel.addElement(v);
// You can chenge this to place the dialog in the middle of the parent window.
// It can be done using uing getParent().getWidth, this.getWidth(),
// getParent().getHeight, and this.getHeight(), etc.
//
setLocation(getParent().getLocation().x + 10, getParent().getLocation().y + 10);
setVisible(true);
return _status;
}
Dish getDish() {
return (Dish) _dishesModel.getSelectedItem();
}
}

View File

@ -0,0 +1,177 @@
package extra.json;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import org.json.*;
public class UsageExample {
// a string with a JSON structure to be used in the examples
static String jsonString = "{ \"a\": 1234, \"b\": 2e-10, \"c\": \"Hola!\", \"d\": [1,2,3], \"e\": { \"k\" : 123, \"h\" : \"Helloooo!\", \"f\": 23.3e-10 }}";
/**
* Accessing the elements of a JSONObject.
*/
static public void accessExample(JSONObject jo) {
System.out.println("==============================");
System.out.println("Accessing a JSONObject Example");
System.out.println("==============================");
System.out.println();
// We can print all keys like in a MAP
//
System.out.println();
System.out.println("** Printing keys");
System.out.println();
for (String key : jo.keySet()) {
System.out.println("-> " + key);
}
// You can ask if it has a key
//
System.out.println();
System.out.println("** Check is a key is defined");
System.out.println();
if (jo.has("a"))
System.out.println("It has a key 'a'!!");
else
System.out.println("It does not have a key 'a'!!");
if (jo.has("bla"))
System.out.println("It has a key 'bla'!!");
else
System.out.println("It does not have a key 'bla'!!");
// Accessing the value of a key of a known type, already converted to a specific
// type (it simple uses casting!). It throws an exception if the type does not
// match -- usually you know what type you expect.
//
System.out.println();
System.out.println("** Check is a key is defined");
System.out.println();
System.out.println("a = " + jo.getInt("a"));
System.out.println("b = " + jo.getDouble("b"));
System.out.println("c = " + jo.getString("c"));
// Array values are special!
//
System.out.println();
System.out.println("** Access and traverse array values");
System.out.println();
JSONArray ja = jo.getJSONArray("d");
for (int i = 0; i < ja.length(); i++) {
System.out.println(ja.getInt(i)); // We know the elements are Int
}
// Nested JSON Objects
//
System.out.println();
System.out.println("** Access a JSON structure value");
System.out.println();
JSONObject jo2 = jo.getJSONObject("e");
for (String key : jo2.keySet()) {
System.out.println("-> " + key);
}
}
/**
* Create a JSONObject and fill it with key-value attributes
*/
private static void createExample() {
System.out.println("=============================");
System.out.println("Creating a JSONObject Example");
System.out.println("=============================");
System.out.println();
JSONObject jo1 = new JSONObject();
// we put some keys with simple values into 'jo1'
jo1.put("a", 1234);
jo1.put("b", 123.3e-10);
jo1.put("c", "Hollaaa");
// we put an array into 'jo1', the elements of the array
JSONArray ja = new JSONArray();
ja.put(123.34);
ja.put(3.23);
ja.put(4.234);
jo1.put("d", ja);
// we put another JSON into 'jo1'
JSONObject jo2 = new JSONObject();
// we put some keys with simple values into 'jo2', and the 'jo2' into 'jo1'
jo2.put("g", 1234);
jo2.put("h", "Hollaaa");
jo1.put("data", jo2);
// print it
System.out.println(jo1);
System.out.println();
// print nicely
System.out.println(jo1.toString(2));
System.out.println();
}
// check if two JSON structure are semantically equal: have same keys with same
// values (order is not important)
//
private static String checkSemanticEquality(JSONObject jo1, JSONObject jo2) {
return jo1.similar(jo2) ? "Yes" : "No";
}
public static void main(String[] args) throws JSONException, FileNotFoundException {
// Example 1: Parse JSON from a string or from a file
//
// build a JSONObject from a string
JSONObject joFromString = new JSONObject(jsonString);
// build a JSONObject from a file
JSONObject joFromFile1 = new JSONObject(
new JSONTokener(new FileInputStream(new File("resources/other/json-example-1.json"))));
JSONObject joFromFile2 = new JSONObject(
new JSONTokener(new FileInputStream(new File("resources/other/json-example-2.json"))));
JSONObject joFromFile3 = new JSONObject(
new JSONTokener(new FileInputStream(new File("resources/other/json-example-3.json"))));
accessExample(joFromString);
accessExample(joFromFile1);
accessExample(joFromFile2);
accessExample(joFromFile3);
// Example 2: compare two JSON structures
//
System.out.println();
System.out.println("=======================");
System.out.println("Compare JSON structures");
System.out.println("=======================");
System.out.println();
System.out
.println("Are joFromString and joFromFile1 euqal? " + checkSemanticEquality(joFromString, joFromFile1));
System.out
.println("Are joFromString and joFromFile2 euqal? " + checkSemanticEquality(joFromString, joFromFile2));
System.out
.println("Are joFromString and joFromFile3 euqal? " + checkSemanticEquality(joFromString, joFromFile3));
System.out.println();
// Example 3: create JSON structure
//
createExample();
}
}

View File

@ -0,0 +1,24 @@
package extra.jtable;
public class EventEx {
private Integer _time;//tiempo en el que se produce el evento
private Integer _priority;//respecto de otros eventos
public EventEx(Integer time, Integer prioridad) {
_time = time;
_priority = prioridad;
}
public int getTime() {
return _time;
}
public int getPriority() {
return _priority;
}
}

View File

@ -0,0 +1,87 @@
package extra.jtable;
import java.util.List;
import javax.swing.table.AbstractTableModel;
public class EventsTableModel extends AbstractTableModel {
/**
*
*/
private static final long serialVersionUID = 1L;
private List<EventEx> _events;
private String[] _colNames = { "#", "Time", "Priority" };
public EventsTableModel() {
_events=null;
}
public void update() {
// observar que si no refresco la tabla no se carga
// La tabla es la represantación visual de una estructura de datos,
// en este caso de un ArrayList, hay que notificar los cambios.
// We need to notify changes, otherwise the table does not refresh.
fireTableDataChanged();;
}
public void setEventsList(List<EventEx> events) {
_events = events;
update();
}
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
//si no pongo esto no coge el nombre de las columnas
//
//this is for the column header
@Override
public String getColumnName(int col) {
return _colNames[col];
}
@Override
// método obligatorio, probad a quitarlo, no compila
//
// this is for the number of columns
public int getColumnCount() {
return _colNames.length;
}
@Override
// método obligatorio
//
// the number of row, like those in the events list
public int getRowCount() {
return _events == null ? 0 : _events.size();
}
@Override
// método obligatorio
// así es como se va a cargar la tabla desde el ArrayList
// el índice del arrayList es el número de fila pq en este ejemplo
// quiero enumerarlos.
//
// returns the value of a particular cell
public Object getValueAt(int rowIndex, int columnIndex) {
Object s = null;
switch (columnIndex) {
case 0:
s = rowIndex;
break;
case 1:
s = _events.get(rowIndex).getTime();
break;
case 2:
s = _events.get(rowIndex).getPriority();
break;
}
return s;
}
}

View File

@ -0,0 +1,150 @@
package extra.jtable;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
import javax.swing.border.Border;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
//Vamos a sacar los datos de un ArrayList en un JTable
//Para esto necesitamos un modelo de tabla.
//Pues no siempre los datos van a venir en un array bidimensional
//
// In this example we will show the information stored in an List using
// a JTable
public class JTableExamples extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private Border _defaultBorder = BorderFactory.createLineBorder(Color.red, 1);
private EventsTableModel _model;
private JTable _eventsTable;
private JButton addButton;
// this is what we show in the table
// esto es lo que mostramos en la table
private List<EventEx> _events;
private JSpinner _time;
private JComboBox<Integer> _priotiry;
public JTableExamples() {
super("JTable Example");
initGUI();
}
public void initGUI() {
JPanel mainPanel = new JPanel(new BorderLayout());
this.setContentPane(mainPanel);
JPanel buttonsPanel = new JPanel();
mainPanel.add(buttonsPanel, BorderLayout.PAGE_START);
// spinner for selecting time
_time = new JSpinner(new SpinnerNumberModel(10, 1, 10000, 1));
_time.setToolTipText("Simulation tick to run: 1-10000");
_time.setMaximumSize(new Dimension(80, 40));
_time.setMinimumSize(new Dimension(80, 40));
_time.setPreferredSize(new Dimension(80, 40));
// comboxfor selecting priority
_priotiry = new JComboBox<Integer>();
for (int i = 0; i < 10; i++) {
_priotiry.addItem(i);
}
addButton = new JButton("Add Event");
addButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
addEvent();
}
});
buttonsPanel.add( new JLabel("Time: "));
buttonsPanel.add(_time);
buttonsPanel.add( new JLabel("Priority: "));
buttonsPanel.add(_priotiry);
buttonsPanel.add(addButton);
// table
JPanel eventsPanel = new JPanel(new BorderLayout());
mainPanel.add(eventsPanel,BorderLayout.CENTER);
// add border
eventsPanel.setBorder(BorderFactory.createTitledBorder(_defaultBorder, "Events", TitledBorder.LEFT,
TitledBorder.TOP));
// the model
_model = new EventsTableModel();
_eventsTable = new JTable(_model);
eventsPanel.add(new JScrollPane(_eventsTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
// the actual events list
_events = new ArrayList<EventEx>();
_model.setEventsList(_events);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(700, 300);
pack();
setVisible(true);
}
public void addEvent() {
try {
Integer time = (Integer) _time.getValue();
Integer priority = (Integer) _priotiry.getSelectedItem();
_events.add(new EventEx(time, priority));
// avisamos al modelo de tabla para que se actualize. En la
// práctica esto no hace falta porque se le avisa directamente
// el TrafficSimulator
//
// We notify the table model that the list has been changed. This is not
// required in the assignment, it will be notified directly by the
// TrafficSimulator since it is an observer
//
_model.update();
} catch (Exception e) {
JOptionPane.showMessageDialog( //
(Frame) SwingUtilities.getWindowAncestor(this), //
"Something went wrong ...",
"ERROR", //
JOptionPane.ERROR_MESSAGE);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JTableExamples();
}
});
}
}

View File

@ -0,0 +1,98 @@
package extra.testing;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
public class TestExamples {
static PrintStream _stdOut = System.out;
static PrintStream _stdErr = System.err;
static PrintStream nullStream = new PrintStream(new OutputStream() {
@Override
public void write(int b) throws IOException {
}
});
public static void start(String path, boolean testMode) throws JSONException, FileNotFoundException {
JSONObject jo = new JSONObject(new JSONTokener(new FileInputStream(new File(path + "/db.json"))));
JSONArray tests = jo.getJSONArray("tests");
if (testMode) {
System.setOut(nullStream);
System.setErr(nullStream);
for (int i = 0; i < tests.length(); i++) {
test(path, tests.getJSONObject(i));
}
} else {
for (int i = 0; i < tests.length(); i++) {
run(path, tests.getJSONObject(i));
}
}
}
private static void run(String path, JSONObject info) {
String inFile = path + "/" + info.getString("file") + ".json";
String outFile = path + "/" + info.getString("file") + ".expout.json";
Integer ticks = info.getInt("ticks");
System.out.println("-> Running: " + inFile);
try {
simulator.launcher.Main.main(new String[] { "-i", inFile, "-o", outFile, "-t", ticks.toString() });
System.out.println("OK!");
} catch (Exception e) {
System.out.println("Failed (exception thrown).");
}
}
private static void test(String path, JSONObject info) {
File inFile = new File(path + "/" + info.getString("file") + ".json");
File outFile = new File(path + "/" + info.getString("file") + ".expout.json");
File myoutFile = new File(path + "/" + info.getString("file") + ".myout.json");
Integer ticks = info.getInt("ticks");
_stdOut.println("-> Running: " + inFile);
try {
simulator.launcher.Main
.main(new String[] { "-i", inFile.getPath(), "-o", myoutFile.getPath(), "-t", ticks.toString() });
JSONObject jo1 = new JSONObject(new JSONTokener(new FileInputStream(outFile)));
JSONObject jo2 = new JSONObject(new JSONTokener(new FileInputStream(myoutFile)));
if (jo1.similar(jo2)) {
_stdOut.println("OK!");
myoutFile.delete(); // delete the file
} else {
_stdOut.println("Failed (output is not equal)!");
}
} catch (Exception e) {
_stdOut.println("Failed (exception thrown).");
}
}
// The full path to the examples directory, where db.json is, should be passed
// as the first command-line argument. If not passed it looks in the default
// examples directory "resources/examples"
//
public static void main(String[] args) throws JSONException, FileNotFoundException {
String path = args.length == 0 ? "resources/examples" : args[0];
// change 'true' to 'false' to generate the expected output instead of testing
start(path, true);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 998 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1020 B

View File

@ -0,0 +1,95 @@
package simulator.control;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
import simulator.exceptions.UnsupportedFileException;
//import simulator.factories.BuilderBasedFactory;
import simulator.factories.Factory;
import simulator.model.Event;
import simulator.model.TrafficSimObserver;
import simulator.model.TrafficSimulator;
/**
* @author Fernando Méndez Torrubiano
*
*/
public class Controller {
private TrafficSimulator trafficSimulator;
private Factory<Event> eventsFactory;
public Controller(TrafficSimulator sim, Factory<Event> eventsFactory){
if(sim != null || eventsFactory != null) {
this.trafficSimulator = sim;
this.eventsFactory = eventsFactory;
}
else {
throw new NullPointerException("Atributo nulo.");
}
}
public void loadEvents(InputStream in) throws UnsupportedFileException {
JSONObject jo = new JSONObject(new JSONTokener(in));
if (jo.has("events")) {
JSONArray ja = jo.getJSONArray("events");
for (int i = 0; i < ja.length(); i++) {
this.trafficSimulator.addEvent(this.eventsFactory.createInstance(ja.getJSONObject(i)));
}
}
else {
throw new UnsupportedFileException();
}
}
public void run(int n, OutputStream out) {
PrintStream p = new PrintStream(out);
p.println("{");
p.println(" \"states\": [");
for (int i = 0; i < n; i++) {
this.trafficSimulator.advance();
p.println(this.trafficSimulator.report());
p.print(",");
}
p.println("]");
p.println("}");
}
public void reset() {
this.trafficSimulator.reset();
}
/*P2*/
public void run(int n) {
for (int i = 0; i < n; i++) {
this.trafficSimulator.advance();
}
}
//A<EFBFBD>adido como parte opcional:
public void save(OutputStream output) {
this.trafficSimulator.save(output);
}
public void addObserver(TrafficSimObserver o) {
this.trafficSimulator.addObserver(o);
}
public void removeObserver(TrafficSimObserver o) {
this.trafficSimulator.removeObserver(o);
}
public void addEvent(Event e) {
this.trafficSimulator.addEvent(e);
}
}

View File

@ -0,0 +1,39 @@
package simulator.exceptions;
public class ContClassException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
private String message;
public ContClassException() {
this.message = "El valor de contaminación debe ser positivo.";
}
public ContClassException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public ContClassException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
public ContClassException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public ContClassException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public String getMessage() {
return message;
}
}

View File

@ -0,0 +1,39 @@
package simulator.exceptions;
public class DestJuncException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
private String message;
public DestJuncException() {
this.message = "El valor no puede ser nulo.";
}
public DestJuncException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public DestJuncException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
public DestJuncException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public DestJuncException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public String getMessage() {
return message;
}
}

View File

@ -0,0 +1,39 @@
package simulator.exceptions;
public class ItineraryException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
private String message;
public ItineraryException() {
this.message = "Itinerario no válido.";
}
public ItineraryException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public ItineraryException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
public ItineraryException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public ItineraryException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public String getMessage() {
return message;
}
}

View File

@ -0,0 +1,39 @@
package simulator.exceptions;
public class LeghtException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
private String message;
public LeghtException() {
this.message = "La longitud de la carretera no puede ser negativo.";
}
public LeghtException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public LeghtException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
public LeghtException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public LeghtException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public String getMessage() {
return message;
}
}

View File

@ -0,0 +1,39 @@
package simulator.exceptions;
public class MaxSpeedException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
private String message;
public MaxSpeedException() {
this.message = "La velocidad no puede ser negativa.";
}
public MaxSpeedException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public MaxSpeedException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
public MaxSpeedException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public MaxSpeedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public String getMessage() {
return message;
}
}

View File

@ -0,0 +1,39 @@
package simulator.exceptions;
public class SrcJuncException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
private String message;
public SrcJuncException() {
this.message = "El valor no puede ser nulo.";
}
public SrcJuncException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public SrcJuncException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
public SrcJuncException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public SrcJuncException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public String getMessage() {
return message;
}
}

View File

@ -0,0 +1,40 @@
package simulator.exceptions;
public class UnsupportedFileException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
private String message;
public UnsupportedFileException() {
// TODO Auto-generated constructor stub
this.message = "El archivo no es compatible.";
}
public UnsupportedFileException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public UnsupportedFileException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
public UnsupportedFileException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public UnsupportedFileException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public String getMessage() {
return message;
}
}

View File

@ -0,0 +1,39 @@
package simulator.exceptions;
public class WeatherException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
private String message;
public WeatherException() {
this.message = "El tiempo atmosférico no pueder ser nulo.";
}
public WeatherException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public WeatherException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
public WeatherException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public WeatherException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public String getMessage() {
return message;
}
}

View File

@ -0,0 +1,27 @@
package simulator.factories;
import org.json.JSONObject;
public abstract class Builder<T> {
protected String _type;
Builder(String type) {
if (type == null)
throw new IllegalArgumentException("Invalid type: " + type);
else
_type = type;
}
public T createInstance(JSONObject info) {
T b = null;
if (_type != null && _type.equals(info.getString("type"))) {
b = createTheInstance(info.has("data") ? info.getJSONObject("data") : null);
}
return b;
}
protected abstract T createTheInstance(JSONObject data);
}

View File

@ -0,0 +1,28 @@
package simulator.factories;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONObject;
public class BuilderBasedFactory<T> implements Factory<T> {
private List<Builder<T>> _builders;
public BuilderBasedFactory(List<Builder<T>> builders) {
_builders = new ArrayList<>(builders);
}
@Override
public T createInstance(JSONObject info) {
if (info != null) {
for (Builder<T> bb : _builders) {
T o = bb.createInstance(info);
if (o != null)
return o;
}
}
throw new IllegalArgumentException("Invalid value for createInstance: " + info);
}
}

View File

@ -0,0 +1,7 @@
package simulator.factories;
import org.json.JSONObject;
public interface Factory<T> {
public T createInstance(JSONObject info);
}

View File

@ -0,0 +1,26 @@
package simulator.factories;
import org.json.JSONObject;
import simulator.model.LightSwitchingStrategy;
import simulator.model.MostCrowdedStrategy;
public class MostCrowdedStrategyBuilder extends Builder<LightSwitchingStrategy> {
protected int timeslot;
public MostCrowdedStrategyBuilder() {
super("most_crowded_lss");
this.timeslot = 1;
}
@Override
protected LightSwitchingStrategy createTheInstance(JSONObject data) {
if(data.has("timeslot")) { //!data.isNull("timeslot")?
return new MostCrowdedStrategy(data.getInt("timeslot"));
}
else {
return new MostCrowdedStrategy(this.timeslot);
}
}
}

View File

@ -0,0 +1,20 @@
package simulator.factories;
import org.json.JSONObject;
import simulator.model.DequeuingStrategy;
import simulator.model.MoveAllStrategy;
public class MoveAllStrategyBuilder extends Builder<DequeuingStrategy> {
public MoveAllStrategyBuilder() {
super("most_all_dqs");
// TODO Auto-generated constructor stub
}
@Override
protected DequeuingStrategy createTheInstance(JSONObject data) {
return new MoveAllStrategy();
}
}

View File

@ -0,0 +1,20 @@
package simulator.factories;
import org.json.JSONObject;
import simulator.model.DequeuingStrategy;
import simulator.model.MoveFirstStrategy;
public class MoveFirstStrategyBuilder extends Builder<DequeuingStrategy> {
public MoveFirstStrategyBuilder() {
super("move_first_dqs");
// TODO Auto-generated constructor stub
}
@Override
protected DequeuingStrategy createTheInstance(JSONObject data) {
return new MoveFirstStrategy();
}
}

View File

@ -0,0 +1,24 @@
package simulator.factories;
import org.json.JSONObject;
import simulator.model.Event;
import simulator.model.NewCityRoadEvent;
import simulator.model.Weather;
public class NewCityRoadEventBuilder extends Builder<Event> {
public NewCityRoadEventBuilder() {
super("new_city_road");
// TODO Auto-generated constructor stub
}
@Override
protected Event createTheInstance(JSONObject data) {
return new NewCityRoadEvent(data.getInt("time"), data.getString("id"),
data.getString("src"), data.getString("dest"), data.getInt("length"),
data.getInt("co2limit"), data.getInt("maxspeed"),
Weather.valueOf(data.getString("weather").toUpperCase()));
}
}

View File

@ -0,0 +1,23 @@
package simulator.factories;
import org.json.JSONObject;
import simulator.model.Event;
import simulator.model.NewInterCityRoadEvent;
import simulator.model.Weather;
public class NewInterCityRoadEventBuilder extends Builder<Event> {
public NewInterCityRoadEventBuilder() {
super("new_inter_city_road");
// TODO Auto-generated constructor stub
}
@Override
protected Event createTheInstance(JSONObject data) {
return new NewInterCityRoadEvent(data.getInt("time"), data.getString("id"),
data.getString("src"), data.getString("dest"), data.getInt("length"), data.getInt("co2limit"),
data.getInt("maxspeed"), Weather.valueOf(data.getString("weather").toUpperCase()));
}
}

View File

@ -0,0 +1,29 @@
package simulator.factories;
import org.json.JSONObject;
import simulator.model.DequeuingStrategy;
import simulator.model.Event;
import simulator.model.LightSwitchingStrategy;
import simulator.model.NewJunctionEvent;
public class NewJunctionEventBuilder extends Builder<Event> {
protected Factory<LightSwitchingStrategy> lssFactory;
protected Factory<DequeuingStrategy> dqsFactory;
public NewJunctionEventBuilder(Factory<LightSwitchingStrategy>
lssFactory, Factory<DequeuingStrategy> dqsFactory) {
super("new_junction");
this.lssFactory = lssFactory;
this.dqsFactory = dqsFactory;
}
@Override
protected Event createTheInstance(JSONObject data) {
return new NewJunctionEvent(data.getInt("time"), data.getString("id"),
this.lssFactory.createInstance(data.getJSONObject("ls_strategy")),
this.dqsFactory.createInstance(data.getJSONObject("dq_strategy")),
data.getJSONArray("coor").getInt(0), data.getJSONArray("coor").getInt(1));
}
}

View File

@ -0,0 +1,36 @@
package simulator.factories;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import simulator.model.Event;
import simulator.model.NewVehicleEvent;
public class NewVehicleEventBuilder extends Builder<Event> {
public NewVehicleEventBuilder() {
super("new_vehicle");
// TODO Auto-generated constructor stub
}
@Override
protected Event createTheInstance(JSONObject data) {
return new NewVehicleEvent(data.getInt("time"), data.getString("id"),
data.getInt("maxspeed"), data.getInt("class"),
this.createArray(data.getJSONArray("itinerary")));
}
private List<String> createArray(JSONArray itineraryArray){
List<String> itinerary = new ArrayList<>();
for (int i = 0; i < itineraryArray.length(); i++) {
itinerary.add(itineraryArray.getString(i));
}
return itinerary;
}
}

View File

@ -0,0 +1,26 @@
package simulator.factories;
import org.json.JSONObject;
import simulator.model.LightSwitchingStrategy;
import simulator.model.RoundRobinStrategy;
public class RoundRobinStrategyBuilder extends Builder<LightSwitchingStrategy> {
protected int timeslot;
public RoundRobinStrategyBuilder() {
super("round_robin_lss");
this.timeslot = 1;
}
@Override
protected LightSwitchingStrategy createTheInstance(JSONObject data) {
if(data.has("timeslot")) {
return new RoundRobinStrategy(data.getInt("timeslot"));
}
else {
return new RoundRobinStrategy(this.timeslot);
}
}
}

View File

@ -0,0 +1,47 @@
package simulator.factories;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import simulator.exceptions.ContClassException;
import simulator.misc.Pair;
import simulator.model.Event;
import simulator.model.NewSetContClassEvent;
public class SetContClassEventBuilder extends Builder<Event> {
public SetContClassEventBuilder() {
super("set_cont_class");
// TODO Auto-generated constructor stub
}
@Override
protected Event createTheInstance(JSONObject data) {
try {
return new NewSetContClassEvent(data.getInt("time"), this.createArray(data.getJSONArray("info")));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (ContClassException e) {
// TODO Auto-generated catch block
e.getMessage();
return null;
}
}
private List<Pair<String, Integer>> createArray(JSONArray infoArray){
List<Pair<String, Integer>> info = new ArrayList<Pair<String, Integer>>();
for (int i = 0; i < infoArray.length(); i++) {
info.add(i, new Pair<String, Integer>(infoArray.getJSONObject(i).getString("vehicle"),
infoArray.getJSONObject(i).getInt("class")));
}
return info;
}
}

View File

@ -0,0 +1,49 @@
package simulator.factories;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import simulator.exceptions.WeatherException;
import simulator.misc.Pair;
import simulator.model.Event;
import simulator.model.NewSetWeatherEvent;
import simulator.model.Weather;
public class SetWeatherEventBuilder extends Builder<Event> {
public SetWeatherEventBuilder() {
super("set_weather");
// TODO Auto-generated constructor stub
}
@Override
protected Event createTheInstance(JSONObject data) {
try {
return new NewSetWeatherEvent(data.getInt("time"), this.createArray(data.getJSONArray("info")));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (WeatherException e) {
// TODO Auto-generated catch block
e.getMessage();
return null;
}
}
private List<Pair<String, Weather>> createArray(JSONArray infoArray){
List<Pair<String, Weather>> info = new ArrayList<Pair<String, Weather>>();
for (int i = 0; i < infoArray.length(); i++) {
info.add(i, new Pair<String, Weather>(infoArray.getJSONObject(i).getString("road"),
Weather.valueOf(infoArray.getJSONObject(i).getString("weather"))));
}
return info;
}
}

View File

@ -0,0 +1,249 @@
package simulator.launcher;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.swing.SwingUtilities;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import simulator.control.Controller;
import simulator.exceptions.UnsupportedFileException;
import simulator.factories.Builder;
import simulator.factories.BuilderBasedFactory;
import simulator.factories.Factory;
import simulator.factories.MostCrowdedStrategyBuilder;
import simulator.factories.MoveAllStrategyBuilder;
import simulator.factories.MoveFirstStrategyBuilder;
import simulator.factories.NewCityRoadEventBuilder;
import simulator.factories.NewInterCityRoadEventBuilder;
import simulator.factories.NewJunctionEventBuilder;
import simulator.factories.NewVehicleEventBuilder;
import simulator.factories.RoundRobinStrategyBuilder;
import simulator.factories.SetContClassEventBuilder;
import simulator.factories.SetWeatherEventBuilder;
import simulator.model.DequeuingStrategy;
import simulator.model.Event;
import simulator.model.LightSwitchingStrategy;
import simulator.model.TrafficSimulator;
import simulator.view.MainWindow;
/**
* @author Fernando Méndez Torrubiano
*
*/
public class Main {
private final static Integer _timeLimitDefaultValue = 10;
private static int _timeLimitValue = 0;
private static String _inFile = null;
private static String _outFile = null;
private static String _mode = "gui";
private static boolean _GUI = true;
private static Factory<Event> _eventsFactory = null;
private static void parseArgs(String[] args) {
// define the valid command line options
//
Options cmdLineOptions = buildOptions();
// parse the command line as provided in args
//
CommandLineParser parser = new DefaultParser();
try {
CommandLine line = parser.parse(cmdLineOptions, args);
parseHelpOption(line, cmdLineOptions);
parseInFileOption(line);
parseOutFileOption(line);
parseTicksOption(line);
parseModeOption(line);
// if there are some remaining arguments, then something wrong is
// provided in the command line!
//
String[] remaining = line.getArgs();
if (remaining.length > 0) {
String error = "Illegal arguments:";
for (String o : remaining)
error += (" " + o);
throw new ParseException(error);
}
} catch (ParseException e) {
System.err.println(e.getLocalizedMessage());
System.exit(1);
}
}
private static Options buildOptions() {
Options cmdLineOptions = new Options();
cmdLineOptions.addOption(Option.builder("i").longOpt("input").hasArg().desc("Events input file").build());
cmdLineOptions.addOption(
Option.builder("o").longOpt("output").hasArg().desc("Output file, where reports are written.").build());
cmdLineOptions.addOption(Option.builder("h").longOpt("help").desc("Print this message").build());
cmdLineOptions.addOption(Option.builder("t").longOpt("ticks").hasArg().desc("Select number of ticks.").build());
cmdLineOptions.addOption(Option.builder("m").longOpt("mode").hasArg().desc("Use GUI or Console.").build());
return cmdLineOptions;
}
private static void parseModeOption(CommandLine line) throws ParseException {
_mode = line.getOptionValue("m");
if(_mode == null) {
throw new ParseException("Mode not found");
}
else{
if(_mode.toLowerCase().equals("console")) {
_GUI = false;
}
else {
_GUI = true;
}
}
}
private static void parseTicksOption(CommandLine line) {
if(line.hasOption("t")) {
//_timeLimitValue = Integer.parseInt(line.getArgList().get(0));
_timeLimitValue = Integer.parseInt(line.getOptionValue("t"));
}
}
private static void parseHelpOption(CommandLine line, Options cmdLineOptions) {
if (line.hasOption("h")) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(Main.class.getCanonicalName(), cmdLineOptions, true);
System.exit(0);
}
}
private static void parseInFileOption(CommandLine line) throws ParseException {
_inFile = line.getOptionValue("i");
if (_inFile == null) {
throw new ParseException("An events file is missing");
}
}
private static void parseOutFileOption(CommandLine line) throws ParseException {
_outFile = line.getOptionValue("o");
}
private static void initFactories() {
// TODO complete this method to initialize _eventsFactory
List<Builder<LightSwitchingStrategy>> lsbs = new ArrayList<>();
lsbs.add( new RoundRobinStrategyBuilder() );
lsbs.add( new MostCrowdedStrategyBuilder() );
Factory<LightSwitchingStrategy> lssFactory = new BuilderBasedFactory<>(lsbs);
List<Builder<DequeuingStrategy>> dqbs = new ArrayList<>();
dqbs.add( new MoveFirstStrategyBuilder() );
dqbs.add( new MoveAllStrategyBuilder() );
Factory<DequeuingStrategy> dqsFactory = new BuilderBasedFactory<>(dqbs);
List<Builder<Event>> ebs = new ArrayList<>();
ebs.add( new NewJunctionEventBuilder(lssFactory, dqsFactory) );
ebs.add( new NewCityRoadEventBuilder() );
ebs.add( new NewInterCityRoadEventBuilder() );
ebs.add( new NewVehicleEventBuilder() );
ebs.add( new SetWeatherEventBuilder() );
ebs.add( new SetContClassEventBuilder() );
_eventsFactory = new BuilderBasedFactory<>(ebs);
}
private static void startBatchMode() throws IOException {
// TODO complete this method to start the simulation
TrafficSimulator sim = new TrafficSimulator();
Controller c = new Controller(sim, _eventsFactory);
InputStream input = new FileInputStream(_inFile);
OutputStream output = _outFile == null ? System.out : new FileOutputStream(_outFile);
try {
c.loadEvents(input);
} catch (UnsupportedFileException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(_timeLimitValue == 0) {
c.run(_timeLimitDefaultValue, output);
}
else {
c.run(_timeLimitValue, output);
}
input.close();
System.out.println("Fin de la simulaci<63>n.");
}
private static void startGUIMode() throws IOException {
TrafficSimulator sim = new TrafficSimulator();
Controller ctrl = new Controller(sim, _eventsFactory);
InputStream input = _inFile == null ? System.in : new FileInputStream(_inFile);
try {
ctrl.loadEvents(input);
} catch (UnsupportedFileException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
input.close();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new MainWindow(ctrl);
}
});
System.out.println("Iniciado el simulador.");
}
private static void start(String[] args) throws IOException {
initFactories();
parseArgs(args);
if(_GUI == false) {
startBatchMode();
}
else {
startGUIMode();
}
}
// example command lines:
//
// -i resources/examples/ex1.json
// -i resources/examples/ex1.json -t 300
// -i resources/examples/ex1.json -o resources/tmp/ex1.out.json
// -i resources/examples/ex1.json -m gui
// -i resources/examples/ex1.json -t 100 -m console
// --help
public static void main(String[] args) {
try {
start(args);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,20 @@
package simulator.misc;
public class Pair<T1, T2> {
private T1 _first;
private T2 _second;
public Pair(T1 first, T2 second) {
_first = first;
_second = second;
}
public T1 getFirst() {
return _first;
}
public T2 getSecond() {
return _second;
}
}

View File

@ -0,0 +1,70 @@
package simulator.misc;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
public class SortedArrayList<E> extends ArrayList<E> {
/**
*
*/
private static final long serialVersionUID = 1L;
private Comparator<E> _cmp;
public SortedArrayList(Comparator<E> cmp) {
super();
_cmp = cmp;
}
public SortedArrayList() {
_cmp = new Comparator<E>() {
@SuppressWarnings("unchecked")
@Override
public int compare(E o1, E o2) {
return ((Comparable<E>) o1).compareTo(o2);
}
};
}
@Override
public boolean add(E e) {
int j = size() - 1;
// Start from the end, and look for the first
// element that is smaller than or equal to e
while (j >= 0 && _cmp.compare(get(j), e) == 1) {
j--;
}
super.add(j + 1, e);
return true;
}
@Override
public boolean addAll(Collection<? extends E> c) {
for (E e : c) {
add(e);
}
return true;
}
@Override
public void add(int index, E element) {
throw new UnsupportedOperationException("Cannot insert to a sorted list");
}
@Override
public boolean addAll(int index, Collection<? extends E> c) {
throw new UnsupportedOperationException("Cannot insert to a sorted list");
}
@Override
public E set(int index, E element) {
throw new UnsupportedOperationException("Cannot set an element in a sorted list");
}
}

View File

@ -0,0 +1,42 @@
package simulator.model;
import simulator.exceptions.ContClassException;
import simulator.exceptions.DestJuncException;
import simulator.exceptions.LeghtException;
import simulator.exceptions.MaxSpeedException;
import simulator.exceptions.SrcJuncException;
import simulator.exceptions.WeatherException;
public class CityRoad extends Road {
//Constructor:
public CityRoad(String id, Junction srcJunc, Junction destJunc, int maxSpeed, int contLimit, int length,
Weather weather) throws SrcJuncException, DestJuncException, MaxSpeedException, ContClassException,
LeghtException, WeatherException {
super(id, srcJunc, destJunc, maxSpeed, contLimit, length, weather);
// TODO Auto-generated constructor stub
}
//Métodos:
@Override
protected void reduceTotalContamination() {
switch (this.weather) {
case WINDY: this.totalCont -= 10; break;
case STORM: this.totalCont -= 10; break;
default:
this.totalCont -= 2;
break;
}
if(this.totalCont < 0) { this.totalCont = 0; }
}
@Override
protected void updateSpeedLimit() {}
@Override
protected int calculateVehicleSpeed(Vehicle v) {
//return (int)((11.0-v.getContClass()/11.0)*this.maxSpeed);
return (int) Math.ceil((((11.0-v.getContClass())/11.0)*this.maxSpeed));
}
}

View File

@ -0,0 +1,7 @@
package simulator.model;
import java.util.List;
public interface DequeuingStrategy {
List<Vehicle> dequeue(List<Vehicle> q);
}

View File

@ -0,0 +1,29 @@
package simulator.model;
public abstract class Event implements Comparable<Event> {
protected int _time;
Event(int time) {
if (time < 1)
throw new IllegalArgumentException("Time must be positive (" + time + ")");
else
_time = time;
}
public int getTime() {
return _time;
}
@Override
public int compareTo(Event o) {
if (this._time == o._time) return 0;
else if (this._time < o._time) return -1;
else return 1;
}
abstract void execute(RoadMap map);
public abstract String toString();
}

View File

@ -0,0 +1,62 @@
package simulator.model;
import simulator.exceptions.ContClassException;
import simulator.exceptions.DestJuncException;
import simulator.exceptions.LeghtException;
import simulator.exceptions.MaxSpeedException;
import simulator.exceptions.SrcJuncException;
import simulator.exceptions.WeatherException;
public class InterCityRoad extends Road {
//Contructor:
protected InterCityRoad(String id, Junction srcJunc, Junction destJunc, int maxSpeed, int contLimit, int length,
Weather weather) throws SrcJuncException, DestJuncException, MaxSpeedException, ContClassException,
LeghtException, WeatherException {
super(id, srcJunc, destJunc, maxSpeed, contLimit, length, weather);
// TODO Auto-generated constructor stub
}
//Métodos:
@Override
protected void reduceTotalContamination() {
int x = 0;
switch (this.weather) {
case SUNNY: x = 2; break;
case CLOUDY: x = 3; break;
case RAINY: x = 10; break;
case WINDY: x = 15; break;
case STORM: x = 20; break;
}
this.totalCont = (int)((100-x)/100)*(this.totalCont);
}
@Override
protected void updateSpeedLimit() {
if(this.totalCont >= this.contLimit) {
//this.curentSpeedLimit = (int)(this.maxSpeed * 0.5);
this.curentSpeedLimit = (int)Math.ceil((this.maxSpeed * 0.5));
}
else {
this.curentSpeedLimit = this.maxSpeed;
}
}
@Override
protected int calculateVehicleSpeed(Vehicle v) {
int speed = 0;
if(this.weather.equals(Weather.STORM)) {
//speed = (int)(this.curentSpeedLimit * 0.8);
speed = (int)Math.ceil(this.maxSpeed * 0.8);
}
else {
speed = this.curentSpeedLimit;
}
return speed;
}
}

View File

@ -0,0 +1,157 @@
package simulator.model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONObject;
import simulator.exceptions.DestJuncException;
import simulator.exceptions.ItineraryException;
import simulator.exceptions.SrcJuncException;
public class Junction extends SimulatedObject {
//Atributos:
protected List<Road> inRoads; //Lista de carreteras entrantes.
protected Map<Junction, Road> outRoads; //Mapa de carreteras salientes.
protected List<List<Vehicle>> queues; //Lista de colas de vehículos esperando para entrar (usar en RECOORRIDOS).
protected Map<Road, List<Vehicle>> queuesRoad; //Mapa de colas de vehículos (usar en las BÚSQUEDAS).
protected int greenLightIndex; //Índice de la carretera con el semáforo en verde.
protected int lastLightTime; //Paso en el cuál el índice del semáforo en verde ha cambiado.
protected LightSwitchingStrategy lss; //Estrategia de cambio de semáforo.
protected DequeuingStrategy dqs; //Estrategia para eliminar vehículos de las colas.
protected int x, y; //Coordenadas (para la siguiente práctica).
//Constructor:
public Junction(String id, LightSwitchingStrategy lsStrategy, DequeuingStrategy
dqStrategy, int xCoor, int yCoor) {
super(id);
this.inRoads = new LinkedList<Road>();
this.outRoads = new HashMap<Junction, Road>();
this.queues = new ArrayList<List<Vehicle>>();
this.queuesRoad = new HashMap<Road, List<Vehicle>>();
this.greenLightIndex = -1;
this.lastLightTime = 0;
if(lsStrategy != null) { this.lss = lsStrategy; }
else { throw new NullPointerException("Estrategia de cambio de semáforo es nula."); }
if(dqStrategy != null) { this.dqs = dqStrategy; }
else { throw new NullPointerException("Estrategia de eliminación de vehículos nula."); }
if(xCoor >= 0) { this.x = xCoor; }
else { throw new NumberFormatException("La coordenada 'X' deber ser positiva."); }
if(yCoor >= 0) { this.y = yCoor; }
else { throw new NumberFormatException("La coordenada 'Y' deber ser positiva."); }
}
//Métodos:
@Override
protected void advance(int time) {
if(this.greenLightIndex != -1) {
//Calcula la lista de vehículos que deben avanzar:
List<Vehicle> listVehicles = new ArrayList<Vehicle>();
listVehicles = this.dqs.dequeue(this.queues.get(greenLightIndex));
//Mueve los vehículos que deben avanzar y los elimina de las colas correspondientes:
for (int i = 0; i < this.queues.get(this.greenLightIndex).size(); i++) {
//listVehicles.get(i).advance(time);
try {
listVehicles.get(i).moveToNextRoad();
} catch (ItineraryException e) {
e.getMessage();
}
this.queuesRoad.remove(listVehicles.get(i).getRoad());
this.queues.get(this.greenLightIndex).remove(i);
}
}
//Cambia el índice de la carretera de la que hay que poner el semáforo en verde:
int nextGreen = this.lss.chooseNextGreen(this.inRoads, this.queues,
this.greenLightIndex, this.lastLightTime, time);
if(nextGreen != this.greenLightIndex) {
this.greenLightIndex = nextGreen;
this.lastLightTime = time;
}
}
protected void addInconmmigRoad(Road r) throws DestJuncException {
if(r.getJDest() == this) {
//Añade la carretera al final de la lista de carreteras entrantes:
this.inRoads.add(r);
//Crea una cola para la carretera:
List<Vehicle> q = new LinkedList<Vehicle>();
//Añade la nueva cola al final de la lista de colas:
this.queues.add(q);
//Añade el par carretera-cola al mapa de colas de vehículos:
this.queuesRoad.put(r, this.queues.get(this.queues.size()-1));
//this.queuesRoad.put(r, q);
}
else {
throw new DestJuncException("Esta no es una carretera entrante al cruce.");
}
}
protected void addOutGoingRoad(Road r) throws SrcJuncException {
if(r.getJSoruce() == this) { //&& this.outRoads.get(r.getJSoruce()) != null
this.outRoads.put(r.getJDest(), r);
}
else {
throw new SrcJuncException("No se puede añadir la carretera saliente.");
}
}
protected void enter(Vehicle v) {
this.queuesRoad.get(v.getRoad()).add(v);
}
protected Road roadTo(Junction j) {
return this.outRoads.get(j);
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public int getGreenLightIndex() {
return this.greenLightIndex;
}
public List<Road> getInRoads() {
return this.inRoads;
}
public List<List<Vehicle>> getQueues(){
return this.queues;
}
@Override
public JSONObject report() {
JSONObject js = new JSONObject();
JSONObject queuesJS = new JSONObject();
JSONArray vehiclesJS = new JSONArray();
js.put("id", this._id);
if(this.greenLightIndex != 0) {
js.put("green", this.greenLightIndex);
}
else {
js.put("green", "none");
}
for (int i = 0; i < this.queues.size(); i++) {
queuesJS.put("road", this.inRoads.get(i).getId());
for (int j = 0; j < this.queues.get(i).size(); j++) {
vehiclesJS.put(this.queues.get(i).get(j).getId());
}
queuesJS.put("vehicles", vehiclesJS);
}
js.put("queues", queuesJS);
return js;
}
}

View File

@ -0,0 +1,10 @@
package simulator.model;
import java.util.List;
public interface LightSwitchingStrategy {
int chooseNextGreen(List<Road> roads, List<List<Vehicle>> qs, int
currGreen, int lastSwitchingTime, int currTime);
}

View File

@ -0,0 +1,53 @@
package simulator.model;
import java.util.List;
public class MostCrowdedStrategy implements LightSwitchingStrategy {
private int timeSlot; //Número de ticks consecutivos durante los cuales, la carretera puede mantener el semáforo en verde.
public MostCrowdedStrategy(int timeSlot) {
this.timeSlot = timeSlot;
}
public int chooseNextGreen(List<Road> roads, List<List<Vehicle>> qs, int
currGreen, int lastSwitchingTime, int currTime) {
int index = -1;
if(!roads.isEmpty()) {
if(currGreen == -1) {
int max = 0;
for (int i = 0; i < qs.size(); i++) {
if(qs.get(i).size() > max) {
max = qs.indexOf(qs.get(i));
}
}
index = max;
}
else if((currTime-lastSwitchingTime) < timeSlot) {
index = currGreen;
}
else {
//TODO
int max = 0;
for (int i = ((currGreen+1) % roads.size()); i < qs.size(); i++) {
if(qs.get(i).size() > max) {
max = qs.indexOf(qs.get(i));
}
}
if(max == 0) {
for (int i = 0; i <= currGreen; i++) {
if(qs.get(i).size() > max) {
max = qs.indexOf(qs.get(i));
}
}
}
index = max;
}
}
return index;
}
}

View File

@ -0,0 +1,23 @@
package simulator.model;
import java.util.ArrayList;
import java.util.List;
public class MoveAllStrategy implements DequeuingStrategy {
public MoveAllStrategy() {
// TODO Auto-generated constructor stub
}
@Override
public List<Vehicle> dequeue(List<Vehicle> q) {
List<Vehicle> aux = new ArrayList<Vehicle>();
if(!q.isEmpty()) {
for (int i = 0; i < q.size(); i++) {
aux.add(q.get(i));
}
}
return aux;
}
}

View File

@ -0,0 +1,21 @@
package simulator.model;
import java.util.ArrayList;
import java.util.List;
public class MoveFirstStrategy implements DequeuingStrategy {
public MoveFirstStrategy() {
// TODO Auto-generated constructor stub
}
@Override
public List<Vehicle> dequeue(List<Vehicle> q) {
List<Vehicle> aux = new ArrayList<Vehicle>();
if(!q.isEmpty()) {
aux.add(q.get(0));
}
return aux;
}
}

View File

@ -0,0 +1,33 @@
package simulator.model;
import simulator.exceptions.ContClassException;
import simulator.exceptions.DestJuncException;
import simulator.exceptions.LeghtException;
import simulator.exceptions.MaxSpeedException;
import simulator.exceptions.SrcJuncException;
import simulator.exceptions.WeatherException;
public class NewCityRoadEvent extends NewRoadEvent{
public NewCityRoadEvent(int time, String id, String srcJun, String destJunc,
int length, int co2Limit, int maxSpeed, Weather weather) {
super(time, id, srcJun, destJunc, length, co2Limit, maxSpeed, weather);
}
@Override
void execute(RoadMap map) {
try {
map.addRoad(new CityRoad(this.id, map.getJunction(this.srcJun), map.getJunction(this.destJunc),
this.maxSpeed, this.co2limit, this.length, this.weather));
} catch (DestJuncException | SrcJuncException | MaxSpeedException | ContClassException
| LeghtException | WeatherException e) {
e.getMessage();
}
}
@Override
public String toString() {
return "New CityRoad '"+id+"'";
}
}

View File

@ -0,0 +1,33 @@
package simulator.model;
import simulator.exceptions.ContClassException;
import simulator.exceptions.DestJuncException;
import simulator.exceptions.LeghtException;
import simulator.exceptions.MaxSpeedException;
import simulator.exceptions.SrcJuncException;
import simulator.exceptions.WeatherException;
public class NewInterCityRoadEvent extends NewRoadEvent {
public NewInterCityRoadEvent(int time, String id, String srcJun, String destJunc,
int length, int co2Limit, int maxSpeed, Weather weather) {
super(time, id, srcJun, destJunc, length, co2Limit, maxSpeed, weather);
}
@Override
void execute(RoadMap map) {
try {
map.addRoad(new InterCityRoad(this.id, map.getJunction(this.srcJun), map.getJunction(this.destJunc),
this.maxSpeed, this.co2limit, this.length, this.weather));
} catch (DestJuncException | SrcJuncException | MaxSpeedException | ContClassException | LeghtException
| WeatherException e) {
e.getMessage();
}
}
@Override
public String toString() {
return "New InterCityRoad '"+id+"'";
}
}

View File

@ -0,0 +1,32 @@
package simulator.model;
public class NewJunctionEvent extends Event {
//Atributos:
protected String id;
protected LightSwitchingStrategy lsStrategy;
protected DequeuingStrategy dqStrategy;
protected int xCoor, yCoor;
public NewJunctionEvent(int time, String id, LightSwitchingStrategy
lsStrategy, DequeuingStrategy dqStrategy, int xCoor, int yCoor) {
super(time);
this.id = id;
this.lsStrategy = lsStrategy;
this.dqStrategy = dqStrategy;
this.xCoor = xCoor;
this.yCoor = yCoor;
}
@Override
void execute(RoadMap map) {
map.addJunction(new Junction(this.id, this.lsStrategy, this.dqStrategy, this.xCoor, this.yCoor));
}
@Override
public String toString() {
return "New Junction '"+id+"'";
}
}

View File

@ -0,0 +1,24 @@
package simulator.model;
public abstract class NewRoadEvent extends Event {
//Atributos:
protected String id;
String srcJun, destJunc;
protected int length, co2limit, maxSpeed;
protected Weather weather;
public NewRoadEvent(int time, String id, String srcJun, String
destJunc, int length, int co2Limit, int maxSpeed, Weather weather) {
super(time);
this.id = id;
this.srcJun = srcJun;
this.destJunc = destJunc;
this.length = length;
this.co2limit = co2Limit;
this.maxSpeed = maxSpeed;
this.weather = weather;
}
abstract void execute(RoadMap map);
}

View File

@ -0,0 +1,61 @@
package simulator.model;
import java.util.List;
import simulator.exceptions.ContClassException;
import simulator.exceptions.ItineraryException;
import simulator.misc.Pair;
public class NewSetContClassEvent extends Event {
List<Pair<String,Integer>> cs;
public NewSetContClassEvent(int time, List<Pair<String,Integer>> cs) throws ContClassException {
super(time);
if(cs != null) {
this.cs = cs;
}
else {
throw new ContClassException();
}
}
@Override
void execute(RoadMap map) {
Vehicle v;
for (int i = 0; i < this.cs.size(); i++) {
v = map.getVehicle(this.cs.get(i).getFirst());
try {
setContamination(v, i);
} catch (ItineraryException e) {
e.getMessage();
}
}
}
private void setContamination(Vehicle v, int i) throws ItineraryException {
if (v != null) {
try {
v.setContaminationClass(this.cs.get(i).getSecond());
} catch (ContClassException e) {
e.getMessage();
}
}
else {
throw new ItineraryException("El vehículo no existe.");
}
}
@Override
public String toString() {
String events = "";
for (int i = 0; i < this.cs.size(); i++) {
events += "(" + this.cs.get(i).getFirst() + ", "
+ this.cs.get(i).getSecond() + ")";
}
return "New SetContaminationClass" + "[" + events + "]";
}
}

View File

@ -0,0 +1,58 @@
package simulator.model;
import java.util.List;
import simulator.exceptions.ItineraryException;
import simulator.exceptions.WeatherException;
import simulator.misc.Pair;
public class NewSetWeatherEvent extends Event {
protected List<Pair<String,Weather>> ws;
public NewSetWeatherEvent(int time, List<Pair<String,Weather>> ws) throws WeatherException {
super(time);
if(ws != null) {
this.ws = ws;
}
else {
throw new WeatherException("El tiempo atmosférico no puede ser nulo.");
}
}
@Override
void execute(RoadMap map) {
Road r;
for (int i = 0; i < this.ws.size(); i++) {
r = map.getRoad(this.ws.get(i).getFirst());
try {
setWeather(r, i);
} catch (ItineraryException e) {
e.getMessage();
}
}
}
private void setWeather(Road r, int i) throws ItineraryException {
if(r != null) {
try {
r.setWeather(this.ws.get(i).getSecond());
} catch (WeatherException e) {
e.getMessage();
}
}
else {
throw new ItineraryException("La carretera no existe.");
}
}
@Override
public String toString() {
String events = "";
for (int i = 0; i < this.ws.size(); i++) {
events += "(" + this.ws.get(i).getFirst() + ", "
+ this.ws.get(i).getSecond() + ")";
}
return "New SetWeather: " + "[" + events + "]";
}
}

View File

@ -0,0 +1,52 @@
package simulator.model;
import java.util.ArrayList;
import java.util.List;
import simulator.exceptions.ContClassException;
import simulator.exceptions.ItineraryException;
import simulator.exceptions.MaxSpeedException;
public class NewVehicleEvent extends Event {
//Atributos:
protected int maxSpeed, contClass;
protected String id;
protected List<String> itinerary;
public NewVehicleEvent(int time, String id, int maxSpeed, int
contClass, List<String> itinerary) {
super(time);
this.id = id;
this.maxSpeed = maxSpeed;
this.contClass = contClass;
this.itinerary = itinerary;
}
@Override
void execute(RoadMap map) {
Vehicle v;
List<Junction> juncItinerary = new ArrayList<Junction>();
try {
for (int i = 0; i < this.itinerary.size(); i++) {
juncItinerary.add(map.getJunction(this.itinerary.get(i)));
}
v = new Vehicle(this.id, this.maxSpeed, this.contClass, juncItinerary);
try {
map.addVehicle(v);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
v.moveToNextRoad();
} catch (MaxSpeedException | ContClassException | ItineraryException e) {
e.getMessage();
}
}
@Override
public String toString() {
return "New Vehicle '"+id+"'";
}
}

View File

@ -0,0 +1,6 @@
package simulator.model;
public interface Observable<T> {
void addObserver(T o);
void removeObserver(T o);
}

View File

@ -0,0 +1,189 @@
package simulator.model;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import simulator.exceptions.ContClassException;
import simulator.exceptions.DestJuncException;
import simulator.exceptions.ItineraryException;
import simulator.exceptions.LeghtException;
import simulator.exceptions.MaxSpeedException;
import simulator.exceptions.SrcJuncException;
import simulator.exceptions.WeatherException;
import simulator.misc.SortedArrayList;
public abstract class Road extends SimulatedObject {
//Atributos:
protected Junction source; //Cruce origen
protected Junction destination; //Cruce destino
protected int lenght; //Longitud de la carretera
protected int maxSpeed; //Velocidad máxima permitida en la carretera
protected int curentSpeedLimit; //Velocidad máxima permitida actualmente
protected int contLimit; //Límite de contaminación
protected Weather weather; //Condiciones meteorológicas actuales
protected int totalCont; //Contaminación actual en la carretera
protected List<Vehicle> list; //Lista ORDENADA de vehículos que circulan por la carretera
//Constructor:
protected Road(String id, Junction srcJunc, Junction destJunc, int maxSpeed,
int contLimit, int length, Weather weather)
throws SrcJuncException, DestJuncException, MaxSpeedException,
ContClassException, LeghtException, WeatherException {
super(id);
if(destJunc != null) {
this.destination = destJunc;
this.destination.addInconmmigRoad(this);
}
else {
throw new DestJuncException();
}
if(srcJunc != null) {
this.source = srcJunc;
this.source.addOutGoingRoad(this);
}
else {
throw new SrcJuncException();
}
if(maxSpeed >= 0) {
this.maxSpeed = maxSpeed;
this.curentSpeedLimit = maxSpeed;
}
else {
throw new MaxSpeedException();
}
if(contLimit >= 0) {
this.contLimit = contLimit;
this.totalCont = 0;
}
else {
throw new ContClassException();
}
if(lenght >= 0) {
this.lenght = length;
}
else {
throw new LeghtException();
}
if(weather != null) {
this.weather = weather;
}
else {
throw new WeatherException();
}
this.list = new SortedArrayList<Vehicle>(); //new LinkedList<Vehicle>();
}
//Métodos:
protected void enter(Vehicle v) throws ItineraryException {
if(v.getLocation() == 0 && v.getCurrentSpeed() == 0) {
this.list.add(v);
}
else {
throw new ItineraryException("El vehículo no puede entrar en la carretera.");
}
}
protected void exit(Vehicle v) {
if(!this.list.isEmpty()) {
this.list.remove(v);
v.setRoad(null);
}
}
protected void setWeather(Weather w) throws WeatherException {
if(w != null) {
this.weather = w;
}
else {
throw new WeatherException();
}
}
public Weather getWeather() {
return this.weather;
}
protected void addContamination(int c) throws ContClassException {
if(c >= 0) {
this.totalCont += c;
}
else {
throw new ContClassException();
}
}
protected abstract void reduceTotalContamination();
protected abstract void updateSpeedLimit();
protected abstract int calculateVehicleSpeed(Vehicle v);
@Override
protected void advance(int time) {
//Estable el límite de velocidad de la carretera:
updateSpeedLimit();
//Reduce la contaminación total:
reduceTotalContamination();
//Recorre la lista de vehículos:
for (int i = 0; i < this.list.size(); i++) {
//Actualiza la velocidad del vehículo:
try {
this.list.get(i).setSpeed(calculateVehicleSpeed(this.list.get(i)));
} catch (MaxSpeedException e) {
e.getMessage();
}
//Llama al método advance del vehículo:
this.list.get(i).advance(time);
}
}
public int getLenght() {
return this.lenght;
}
public Junction getJDest() {
return this.destination;
}
public Junction getJSoruce() {
return this.source;
}
protected void setTotalContaminatio(int c) {
this.totalCont += c;
}
public double getTotalCO2() {
return this.totalCont;
}
public double getCO2Limit() {
return this.contLimit;
}
public int getMaxSpeed() {
return this.maxSpeed;
}
public int getCurrentSpeedLimit() {
return this.curentSpeedLimit;
}
@Override
public JSONObject report() {
JSONObject js = new JSONObject();
JSONArray vehiclesJS = new JSONArray();
js.put("id", this._id);
js.put("speedlimit", this.curentSpeedLimit);
js.put("weather", this.weather);
js.put("co2", this.totalCont);
for (int i = 0; i < this.list.size(); i++) {
//vehiclesJS.put(this.list.get(i).report());
vehiclesJS.put(this.list.get(i).getId());
}
js.put("vehicles", vehiclesJS);
return js;
}
}

View File

@ -0,0 +1,132 @@
package simulator.model;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONObject;
import simulator.exceptions.DestJuncException;
public class RoadMap {
//Atributos:
protected List<Junction> junctionList;
protected List<Road> roadList;
protected List <Vehicle> vehicleList;
protected Map<String, Junction> junctionMap; //Mapa de identificadores de cruces.
protected Map<String, Road> roadMap; //Mapa de identificadores de carreteras.
protected Map<String, Vehicle> vehicleMap; //Mapa de identificadores de vehículos.
protected RoadMap() {
this.junctionList = new ArrayList<Junction>();
this.roadList = new ArrayList<Road>();
this.vehicleList = new ArrayList<Vehicle>();
this.junctionMap = new HashMap<String, Junction>();
this.roadMap = new HashMap<String, Road>();
this.vehicleMap = new HashMap<String, Vehicle>();
}
protected void addJunction(Junction j) {
if(!this.junctionMap.containsKey(j.getId())) {
this.junctionMap.put(j.getId(), j);
this.junctionList.add(j);
}
}
protected void addRoad(Road r) throws DestJuncException {
if(!this.roadMap.containsKey(r.getId())
&& this.junctionMap.containsKey(r.getJDest().getId())
&& this.junctionMap.containsKey(r.getJSoruce().getId())) {
this.roadMap.put(r.getId(), r);
this.roadList.add(r);
}
else {
throw new DestJuncException("Los cruces que conectan a la carretera no existen en el mapa de carreteras.");
}
}
protected void addVehicle(Vehicle v) throws Exception {
int i = 0;
boolean addVehicle = true;
if(!this.vehicleMap.containsKey(v.getId())){
while(i < v.getItinerary().size()-1 && addVehicle){
if(v.getItinerary().get(i).roadTo(v.getItinerary().get(i+1)) != null) {
i++;
}
else {
addVehicle = false;
}
}
if(addVehicle) {
this.vehicleMap.put(v.getId(), v);
this.vehicleList.add(v);
}
}
else {
throw new Exception("No se puede añadir el vehículo");
}
}
public Junction getJunction(String id) {
return this.junctionMap.getOrDefault(id, null);
}
public Road getRoad(String id) {
return this.roadMap.getOrDefault(id, null);
}
public Vehicle getVehicle(String id) {
return this.vehicleMap.getOrDefault(id, null);
}
public List<Junction> getJunctions(){
return Collections.unmodifiableList(new ArrayList<>(this.junctionList));
}
public List<Road> getRoads(){
return Collections.unmodifiableList(new ArrayList<>(this.roadList));
}
public List<Vehicle> getVehicles(){
return Collections.unmodifiableList(new ArrayList<>(this.vehicleList));
}
protected void reset() {
this.junctionList.clear();
this.junctionMap.clear();
this.roadList.clear();
this.roadMap.clear();
this.vehicleList.clear();
this.vehicleMap.clear();
}
public JSONObject report() {
JSONObject js = new JSONObject();
JSONArray junctionsJS = new JSONArray();
JSONArray roadsJS = new JSONArray();
JSONArray vehiclesJS = new JSONArray();
for (int i = 0; i < this.junctionList.size(); i++) {
junctionsJS.put(this.junctionList.get(i).report());
}
js.put("junctions", junctionsJS);
for (int i = 0; i < this.roadList.size(); i++) {
roadsJS.put(this.roadList.get(i).report());
}
js.put("road", roadsJS);
for (int i = 0; i < this.vehicleList.size(); i++) {
vehiclesJS.put(this.vehicleList.get(i).report());
}
js.put("vehicles", vehiclesJS);
return js;
}
}

View File

@ -0,0 +1,32 @@
package simulator.model;
import java.util.List;
public class RoundRobinStrategy implements LightSwitchingStrategy {
private int timeSlot; //Número de ticks consecutivos durante los cuales, la carretera puede mantener el semáforo en verde.
public RoundRobinStrategy(int timeSlot) {
this.timeSlot = timeSlot;
}
public int chooseNextGreen(List<Road> roads, List<List<Vehicle>> qs, int
currGreen, int lastSwitchingTime, int currTime) {
int index = -1;
if(!roads.isEmpty()) {
if(currGreen == -1) {
index = 0;
}
else if((currTime-lastSwitchingTime) < timeSlot) {
index = currGreen;
}
else {
index = ((currGreen+1) % (roads.size()));
}
}
return index;
}
}

View File

@ -0,0 +1,25 @@
package simulator.model;
import org.json.JSONObject;
public abstract class SimulatedObject {
protected String _id;
protected SimulatedObject(String id) {
_id = id;
}
public String getId() {
return _id;
}
@Override
public String toString() {
return _id;
}
protected abstract void advance(int time);
abstract public JSONObject report();
}

View File

@ -0,0 +1,12 @@
package simulator.model;
import java.util.List;
public interface TrafficSimObserver {
void onAdvanceStart(RoadMap map, List<Event> events, int time);
void onAdvanceEnd(RoadMap map, List<Event> events, int time);
void onEventAdded(RoadMap map, List<Event> events, Event e, int time);
void onReset(RoadMap map, List<Event> events, int time);
void onRegister(RoadMap map, List<Event> events, int time);
void onError(String err);
}

View File

@ -0,0 +1,143 @@
package simulator.model;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import org.json.JSONObject;
import simulator.misc.SortedArrayList;
public class TrafficSimulator implements Observable<TrafficSimObserver> {
//Atributos:
private RoadMap mapaCarreteras; //Mapa de carreteras en el cual se almacenan todos los objetos de la simulación.
private List<Event> listaEventos; //Lista de eventos a ejectuar, ordenada por tiempo. A igualdad de tiempo, preferencia el que fue añadido antes a la lista.
private int tiempo; //Paso de la simulación. Inicialmente, vale 0.
private List<TrafficSimObserver> listaObservadores; //Lista de observadores.
//Constructor:
public TrafficSimulator() {
this.mapaCarreteras = new RoadMap();
this.listaEventos = new SortedArrayList<Event>();
this.tiempo = 0;
this.listaObservadores = new ArrayList<TrafficSimObserver>();
}
//Métodos:
public void addEvent(Event e) {
this.listaEventos.add(e);
this.onEventAdded(this.mapaCarreteras, this.listaEventos, e, this.tiempo);
}
public void advance() {
//1.Incrementa el tiempo de la simulación en 1.
this.tiempo++;
this.onAdvanceStart(this.mapaCarreteras, this.listaEventos, this.tiempo);
//2.Ejecuta todos los eventos que coincidan con el tiempo actual de la simulación y los elimina de la lista.
//Después, llama a sus correspondientes métodos "execute".
while(!this.listaEventos.isEmpty() && this.listaEventos.get(0).getTime() == this.tiempo) {
this.listaEventos.get(0).execute(this.mapaCarreteras);
this.listaEventos.remove(this.listaEventos.get(0));
}
//3.Llama al método "advance" de todos los cruces.
for (int i = 0; i < this.mapaCarreteras.getJunctions().size(); i++) {
this.mapaCarreteras.getJunctions().get(i).advance(this.tiempo);
}
//4.LLama al método "advance" de todas las carreteras.
for (int i = 0; i < this.mapaCarreteras.getRoads().size(); i++) {
this.mapaCarreteras.getRoads().get(i).advance(this.tiempo);
}
this.onAdvanceEnd(this.mapaCarreteras, this.listaEventos, this.tiempo);
}
public void reset() {
this.listaEventos.clear();
this.mapaCarreteras.reset();
this.tiempo = 0;
this.onReset(this.mapaCarreteras, this.listaEventos, this.tiempo);
}
public JSONObject report() {
JSONObject json = new JSONObject();
json.put("time", this.tiempo);
json.put("state", this.mapaCarreteras.report());
return json;
}
/*P2*/
private void onAdvanceStart(RoadMap map, List<Event> events, int time) {
for (TrafficSimObserver o : this.listaObservadores) {
o.onAdvanceStart(map, events, time);
}
}
private void onAdvanceEnd(RoadMap map, List<Event> events, int time) {
for (TrafficSimObserver o : this.listaObservadores) {
o.onAdvanceEnd(map, events, time);
}
}
private void onEventAdded(RoadMap map, List<Event> events, Event e, int time) {
if(e == null) {
this.onError("Error al añadir el evento.");
throw new IllegalArgumentException();
}
for (TrafficSimObserver o : this.listaObservadores) {
o.onEventAdded(map, events, e, time);
}
}
private void onReset(RoadMap map, List<Event> events, int time) {
for (TrafficSimObserver o : this.listaObservadores) {
o.onReset(map, events, time);
}
}
@SuppressWarnings("unused")
private void onRegister(RoadMap map, List<Event> events, int time) {}
public void onError(String err) {
System.err.println(err);
JOptionPane.showMessageDialog(new JFrame(), err);
}
@Override
public void addObserver(TrafficSimObserver o) {
if (!this.listaObservadores.contains(o)) {
this.listaObservadores.add(o);
}
o.onRegister(this.mapaCarreteras, this.listaEventos, this.tiempo);
}
@Override
public void removeObserver(TrafficSimObserver o) {
this.listaObservadores.remove(o);
}
//Añadido como parte opcional:
public void save(OutputStream output) {
PrintStream p = new PrintStream(output);
p.println("{");
p.println(" \"events\": ");
p.println("[");
p.println(this.mapaCarreteras.report());
p.println("]");
p.println("}");
}
}

View File

@ -0,0 +1,211 @@
package simulator.model;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.json.JSONObject;
import simulator.exceptions.ContClassException;
import simulator.exceptions.ItineraryException;
import simulator.exceptions.MaxSpeedException;
public class Vehicle extends SimulatedObject implements Comparable<Vehicle> {
//Atributos:
private List<Junction> itinerary; //Lista de cruces. Itinerario del vehículo.
private int actualItinerary; //Punto actual del itinerario en el que se encuentra el vehículo.
private int maxSpeed; //Velocidad máxima
private int currentSpeed; //Velocidad actual
private VehicleStatus status; //Estado del vehículo (PENDING, TRAVELING, WAITING, ARRIVED;)
private Road road; //Carretera. Null en caso de que no esté en ninguna
private int location; //Distancia recorrida (distancia entre el vehículo y el origen de la carretera, 0)
private int contClass; //CO2 emitido por el vehículo en cada tick
private int totalContamination; //CO2 emitido por el vehículo durante la trayectoria recorrida
private int totalTravelDistance; //Distancia recorrida por el vehículo
//Contructor:
public Vehicle(String id, int maxSpeed, int contClass, List<Junction> itinerary)
throws MaxSpeedException, ContClassException, ItineraryException {
super(id);
if(maxSpeed >= 0) {
this.maxSpeed = maxSpeed;
}
else {
throw new MaxSpeedException("La velocidad no puede ser negativa.");
}
if(contClass >= 0 || contClass <= 10) {
this.contClass = contClass;
}
else {
throw new ContClassException("El valor de contaminación debe estar entre 0 y 10.");
}
if(itinerary.size() >= 2) {
// this.itinerary = itinerary;
this.actualItinerary = 0;
this.itinerary = Collections.unmodifiableList(new ArrayList<>(itinerary));
}
else {
throw new ItineraryException("Itinerario no válido.");
}
this.currentSpeed = 0;
this.status = VehicleStatus.PENDING;
this.road = null;
this.location = 0;
this.totalContamination = 0;
this.totalTravelDistance = 0;
}
//Métodos:
protected void setSpeed(int s) throws MaxSpeedException {
if(s >= 0) {
if(this.maxSpeed > s) {
this.currentSpeed = s;
}
else {
this.currentSpeed = maxSpeed;
}
}
else {
throw new MaxSpeedException("La velocidad no puede ser negativa.");
}
}
protected void setContaminationClass(int c) throws ContClassException {
if(contClass >= 0 || contClass <= 10) {
this.contClass = c;
}
else {
throw new ContClassException("El valor de contaminación debe estar entre 0 y 10");
}
}
protected void advance(int time) {
if(this.status == VehicleStatus.TRAVELING) {
int oldLocation = this.location;
//Actualiza la localización del vehículo:
if((this.location + this.currentSpeed) < this.road.getLenght()) {
this.location += this.currentSpeed;
this.totalTravelDistance += this.currentSpeed;
}
else {
this.location = this.road.getLenght();
this.totalTravelDistance += this.road.getLenght();
}
//Calcula la contaminación prooducida:
this.totalContamination += (this.location - oldLocation) * this.contClass;
try {
this.road.addContamination((this.location - oldLocation) * this.contClass);
} catch (ContClassException e) {
e.getMessage();
}
//Si el vehículo ha llegado al final de la carretera, entra en la cola del cruce:
if(this.location == this.road.getLenght()) {
this.status = VehicleStatus.WAITING;
this.currentSpeed = 0;
this.road.getJDest().enter(this);
}
}
}
protected void moveToNextRoad() throws ItineraryException {
if(this.status == VehicleStatus.PENDING || this.status == VehicleStatus.WAITING) {
if(this.actualItinerary > 0) { this.road.exit(this); }
this.location = 0;
this.currentSpeed = 0;
if(this.itinerary.size()-1 == this.actualItinerary) {
this.status = VehicleStatus.ARRIVED;
}
else {
try {
this.road = this.itinerary.get(this.actualItinerary).roadTo(this.itinerary.get(this.actualItinerary+1));
if(this.road != null) { this.road.enter(this); }
this.actualItinerary++;
this.status = VehicleStatus.TRAVELING;
}
catch (ItineraryException e) {
e.getMessage();
}
}
}
else {
throw new ItineraryException("El vehículo no ha llegado al final de la carretera.");
}
}
public int getContClass() {
return this.contClass;
}
public int getTotalCont() {
return this.totalContamination;
}
public Road getRoad() {
return this.road;
}
public int getLocation() {
return this.location;
}
public int getTotalDistance() {
return this.totalTravelDistance;
}
public int getCurrentSpeed() {
return this.currentSpeed;
}
public int getMaxSpeed() {
return this.maxSpeed;
}
public List<Junction> getItinerary(){
return Collections.unmodifiableList(new ArrayList<>(itinerary));
}
public VehicleStatus getStatus() {
return this.status;
}
public void setRoad(Road r) {
this.road = r;
}
@Override
public int compareTo(Vehicle v) {
if(this.location == v.getLocation()) {
return 0;
}
else if(this.location < v.getLocation()) {
return 1;
}
else {
return -1;
}
}
//Devuelve el estado del vehículo en el siguiente formato JSON:
public JSONObject report() {
JSONObject js = new JSONObject();
js.put("id", this._id);
js.put("speed", this.currentSpeed);
js.put("distance", this.totalTravelDistance);
js.put("co2", this.totalContamination);
js.put("class", this.contClass);
js.put("status", this.status);
if(this.status != VehicleStatus.PENDING && this.status != VehicleStatus.ARRIVED){
js.put("road", this.road);
js.put("location", this.location);
}
return js;
}
}

View File

@ -0,0 +1,5 @@
package simulator.model;
public enum VehicleStatus {
PENDING, TRAVELING, WAITING, ARRIVED;
}

View File

@ -0,0 +1,5 @@
package simulator.model;
public enum Weather {
SUNNY, CLOUDY, RAINY, WINDY, STORM;
}

View File

@ -0,0 +1,162 @@
package simulator.view;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import simulator.model.RoadMap;
import simulator.model.SimulatedObject;
import simulator.model.Vehicle;
public class ChangueCO2Dialog extends JDialog {
/**
*
*/
private static final long serialVersionUID = 1L;
//Atributos:
private int _status;
private JComboBox<Vehicle> _vehicles;
private JSpinner _timeSpinner;
private JComboBox<Integer> _co2Class;
private final String _HELPMSG1 = "Selecciona un vehículo";
private final String _HELPMSG2 = "Selecciona una clase de contaminación";
//private Controller _ctrl;
private RoadMap _map;
//Construcotor:
public ChangueCO2Dialog() {
super();
initGUI();
}
public ChangueCO2Dialog(Frame parent) {
super(parent, true);
initGUI();
}
//Métodos:
private void initGUI() {
_status = 0;
setTitle("Changue CO2 Class");
setBounds(500, 500, 500, 250);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridLayout(3, 1, 0 , 15));
setContentPane(mainPanel);
JPanel labelPanel = new JPanel(new GridLayout(2, 1));
JLabel help1 = new JLabel(_HELPMSG1);
JLabel help2 = new JLabel(_HELPMSG2);
labelPanel.add(help1);
labelPanel.add(help2);
mainPanel.add(labelPanel);
JPanel viewPanel = new JPanel(new FlowLayout());
mainPanel.add(viewPanel);
JPanel buttonsPanel = new JPanel();
buttonsPanel.setAlignmentX(CENTER_ALIGNMENT);
mainPanel.add(buttonsPanel);
_vehicles = new JComboBox<Vehicle>();
_vehicles.setPreferredSize(new Dimension(100, 25));
_timeSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 10000, 1));
_timeSpinner.setToolTipText("Tiempo a partir de ahora para programar el evento");
_timeSpinner.setPreferredSize(new Dimension(80, 25));
_co2Class = new JComboBox<Integer>();
_co2Class.setPreferredSize(new Dimension(80, 25));
for (int i = 0; i < 11; i++) {
_co2Class.addItem(i);
}
viewPanel.add(new JLabel("Vehicle: "));
viewPanel.add(_vehicles);
viewPanel.add(new JLabel("CO2 Class: "));
viewPanel.add(_co2Class);
viewPanel.add(new JLabel("Ticks: "));
viewPanel.add(_timeSpinner);
JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
_status = 0;
ChangueCO2Dialog.this.setVisible(false);
}
});
buttonsPanel.add(cancelButton);
JButton okButton = new JButton("Ok");
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(_vehicles.getSelectedItem() != null) {
_status = 1;
}
else {
_status = 0;
JOptionPane.showMessageDialog(new JFrame(), "Ningún vehículo seleccionado.");
}
ChangueCO2Dialog.this.setVisible(false);
}
});
buttonsPanel.add(okButton);
}
public SimulatedObject getVehicle() {
return (SimulatedObject) this._vehicles.getSelectedItem();
}
public int getCO2Class() {
return this._co2Class.getSelectedIndex();
}
public int getTicks() {
return (int) this._timeSpinner.getValue();
}
public int open(RoadMap map) {
this._map = map;
for (int i = 0; i < _map.getVehicles().size(); i++) {
if(_map.getVehicles().get(i) != null) {
_vehicles.addItem(_map.getVehicles().get(i));
}
}
setLocation(getParent().getLocation().x + 10, getParent().getLocation().y + 10);
setVisible(true);
return _status;
}
}

View File

@ -0,0 +1,166 @@
package simulator.view;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import simulator.model.Road;
import simulator.model.RoadMap;
import simulator.model.SimulatedObject;
import simulator.model.Weather;
public class ChangueWeatherDialog extends JDialog {
/**
*
*/
private static final long serialVersionUID = 1L;
//Atributos:
private int _status;
private JComboBox<Road> _roads;
private JSpinner _timeSpinner;
private JComboBox<Weather> _weather;
private final String _HELPMSG1 = "Selecciona una carretera";
private final String _HELPMSG2 = "Selecciona un tiempo atmosférico";
//private Controller _ctrl;
private RoadMap _map;
//Construcotor:
public ChangueWeatherDialog() {
super();
initGUI();
}
public ChangueWeatherDialog(Frame parent) {
super(parent, true);
initGUI();
}
//Métodos:
private void initGUI() {
_status = 0;
setTitle("Changue Road Weather");
setBounds(500, 500, 500, 250);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridLayout(3, 1, 0 , 15));
setContentPane(mainPanel);
JPanel labelPanel = new JPanel(new GridLayout(2, 1));
JLabel help1 = new JLabel(_HELPMSG1);
JLabel help2 = new JLabel(_HELPMSG2);
labelPanel.add(help1);
labelPanel.add(help2);
mainPanel.add(labelPanel);
JPanel viewPanel = new JPanel(new FlowLayout());
mainPanel.add(viewPanel);
JPanel buttonsPanel = new JPanel();
buttonsPanel.setAlignmentX(CENTER_ALIGNMENT);
mainPanel.add(buttonsPanel);
_roads = new JComboBox<Road>();
_roads.setPreferredSize(new Dimension(100, 25));
_timeSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 10000, 1));
_timeSpinner.setToolTipText("Tiempo a partir de ahora para programar el evento");
_timeSpinner.setPreferredSize(new Dimension(80, 25));
_weather = new JComboBox<Weather>();
_weather.setPreferredSize(new Dimension(80, 25));
_weather.addItem(Weather.SUNNY);
_weather.addItem(Weather.WINDY);
_weather.addItem(Weather.CLOUDY);
_weather.addItem(Weather.RAINY);
_weather.addItem(Weather.STORM);
viewPanel.add(new JLabel("Road: "));
viewPanel.add(_roads);
viewPanel.add(new JLabel("Weather: "));
viewPanel.add(_weather);
viewPanel.add(new JLabel("Ticks: "));
viewPanel.add(_timeSpinner);
JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
_status = 0;
ChangueWeatherDialog.this.setVisible(false);
}
});
buttonsPanel.add(cancelButton);
JButton okButton = new JButton("Ok");
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(_roads.getSelectedItem() != null) {
_status = 1;
}
else {
_status = 0;
JOptionPane.showMessageDialog(new JFrame(), "Ninguna carretera seleccionada.");
}
ChangueWeatherDialog.this.setVisible(false);
}
});
buttonsPanel.add(okButton);
}
public SimulatedObject getRoad() {
return (SimulatedObject) this._roads.getSelectedItem();
}
public Weather getWeather() {
return (Weather) this._weather.getSelectedItem();
}
public int getTicks() {
return (int) this._timeSpinner.getValue();
}
public int open(RoadMap map) {
this._map = map;
for (int i = 0; i < _map.getRoads().size(); i++) {
if(_map.getRoads().get(i) != null) {
_roads.addItem(_map.getRoads().get(i));
}
}
setLocation(getParent().getLocation().x + 10, getParent().getLocation().y + 10);
setVisible(true);
return _status;
}
}

View File

@ -0,0 +1,494 @@
package simulator.view;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JToolBar;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import simulator.control.Controller;
import simulator.exceptions.UnsupportedFileException;
import simulator.misc.Pair;
import simulator.model.Event;
import simulator.model.NewSetContClassEvent;
import simulator.model.NewSetWeatherEvent;
import simulator.model.RoadMap;
import simulator.model.TrafficSimObserver;
import simulator.model.Weather;
public class ControlPanel extends JPanel implements TrafficSimObserver {
/**
*
*/
private static final long serialVersionUID = 1L;
//Atributos:
private JButton loadFile; //Abre un diálogo para seleccionar un fichero de eventos (utilizando JFileChooser).
private JButton saveFile; //Abre un diálogo para guardar el estado actual (utilizando JFileChooser).
private JButton changeVehicleContClass; //Abre una ventana de diálogo donde el usuario puede seleccionar un vehículo V, una clase de contaminación C (0-10) y un número de ticks N.
private JButton changeRoadWeather; //Abre una ventana de diálogo donde el usuario puede seleccionar una carretera R, unas condiciones atmosféricas W, y un número de ticks N
private JButton run; //Ejecuta el simulador.
private JButton stop; //Para el simulador.
private JButton restart; //Reinicia el simulador desde el archivo cargado previamente.
private JButton exit; //Sale del simulador.
private JSpinner nTicks; //Número de veces que se ejecuta la simulación.
private JLabel ticks; //Barra para mostrar el número de ticks de la simulación.
private JToolBar toolbar; //Barra de herramientas.
private JFileChooser fileChooser; //Selector de archivos.
private Controller _ctrl;
private RoadMap _map;
private int _time;
private static boolean _stopped = true;
private int _nTicks = 10;
private File file;
//Constructor:
public ControlPanel(Controller ctrl) {
super();
this._ctrl = ctrl;
this._nTicks = 0;
this.file = null;
this.InitGUI();
ctrl.addObserver(this);
}
//Métodos:
private void InitGUI() {
//Inicia el panel de control:
this.toolbar = new JToolBar();
this.setLayout(new BorderLayout());
this.add(toolbar, BorderLayout.PAGE_START);
//Añade la carga de ficheros:
this.initLoadButton();
//this.toolbar.addSeparator();
//Añade el guardado de la simulación: (no se pide en la práctica, lo añado como parte opcional)
this.initSaveButton();
this.toolbar.addSeparator();
//Añade el botón de cambio de clase de contaminación del vehículo:
this.initChangeVehicleContClassButton();
this.toolbar.addSeparator();
//Añade el botón de cambio de condiciones atmosféricas en la carretera:
this.initChangeRoadWeather();
this.toolbar.addSeparator();
//Añade el botón de incio:
this.initRunButton();
//Añade el botón de parada:
this.initStopButton();
//Añade el botón de reinicio: (no se pide en la práctica, lo añado como parte opcional)
this.initRestartButton();
this.toolbar.addSeparator();
//Añade el número de ticks de la simulación:
this.ticks = new JLabel();
this.ticks.setText("Ticks: ");
this.toolbar.add(this.ticks);
this.initTicksSpinner();
this.toolbar.addSeparator();
//Añade el botón de salir:
this.initExitButton();
}
private void initLoadButton() {
this.fileChooser = new JFileChooser();
this.fileChooser.setDialogTitle("Elige el archivo de eventos para la simulación");
this.fileChooser.setCurrentDirectory(new File("resources/examples/"));
this.loadFile = new JButton();
this.loadFile.setToolTipText("Carga el archivo de eventos de la simulación");
this.loadFile.setIcon(new ImageIcon(this.getClass().getResource("/icons/open.png")));
this.loadFile.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int choseF = fileChooser.showOpenDialog(fileChooser);
if (choseF == JFileChooser.APPROVE_OPTION) {
System.out.println("Archivo seleccionado: " + fileChooser.getSelectedFile());
JOptionPane.showMessageDialog(fileChooser, "Has seleccionado el archivo: " + fileChooser.getSelectedFile());
//File file = fileChooser.getSelectedFile();
file = fileChooser.getSelectedFile();
InputStream input;
try {
input = new FileInputStream(file);
if(input != null) {
_ctrl.reset();
try {
_ctrl.loadEvents(input);
} catch (UnsupportedFileException e2) {
onError("Algo salió mal al cargar el archivo: " + e2.getMessage());
}
}
try {
input.close();
} catch (IOException e1) {
onError("Algo salió mal al cerrar el archivo: " + e1.getMessage());
}
} catch (FileNotFoundException ex) {
onError("Algo salió mal al cargar el archivo: " + ex.getMessage());
}
}
else {
System.out.println("No se ha cargado ningún archivo.");
JOptionPane.showMessageDialog(fileChooser, "No se ha cargado ningún archivo.");
}
}
});
this.toolbar.add(this.loadFile);
}
//Añadido como parte opcional:
private void initSaveButton() {
this.fileChooser = new JFileChooser();
this.fileChooser.setDialogTitle("Guarda el estado actual de la simulación");
this.fileChooser.setCurrentDirectory(new File("resources/examples/"));
this.saveFile = new JButton();
this.saveFile.setToolTipText("Guarda en un archivo el estado actual del simulador");
this.saveFile.setIcon(new ImageIcon(this.getClass().getResource("/icons/save.png")));
this.saveFile.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int choseF = fileChooser.showSaveDialog(fileChooser);
if (choseF == JFileChooser.APPROVE_OPTION) {
System.out.println("Estado guardado: " + fileChooser.getSelectedFile());
JOptionPane.showMessageDialog(fileChooser, "Estado guardado en el archivo: " + fileChooser.getSelectedFile());
File saveFile = fileChooser.getSelectedFile();
OutputStream output;
try {
output = new FileOutputStream(saveFile + ".json");
if(output != null) {
_ctrl.save(output);
}
try {
output.close();
} catch (IOException e1) {
onError("Algo salió mal al cerrar el archivo: " + e1.getMessage());
}
} catch (FileNotFoundException ex) {
onError("Algo salió mal al guardar el archivo: " + ex.getMessage());
}
}
else {
System.out.println("No se ha guardado el archivo.");
JOptionPane.showMessageDialog(fileChooser, "No se ha guardado el archivo.");
}
}
});
this.toolbar.add(this.saveFile);
}
private void initChangeVehicleContClassButton() {
this.changeVehicleContClass = new JButton();
this.changeVehicleContClass.setToolTipText("Cambia la clase de contaminación del vehículo.");
this.changeVehicleContClass.setIcon(new ImageIcon(this.getClass().getResource("/icons/co2class.png")));
this.changeVehicleContClass.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
select_CO2Class();
}
});
this.toolbar.add(this.changeVehicleContClass);
}
protected void select_CO2Class() {
ChangueCO2Dialog dialog = new ChangueCO2Dialog ((Frame) SwingUtilities.getWindowAncestor(this));
int status = dialog.open(_map);
if (status == 0) {
System.out.println("Evento de cambio de contaminación de vehículo, cancelado.");
//JOptionPane.showMessageDialog(new JFrame(), "Cancelado");
}
else {
List<Pair<String, Integer>> cs = new ArrayList<>();
cs.add(new Pair<String, Integer>((dialog.getVehicle()).getId(), dialog.getCO2Class()));
try {
_ctrl.addEvent(new NewSetContClassEvent(_time + dialog.getTicks(), cs));
System.out.println("Nuevo evento de cambio de contaminación de vehículo añadido.");
} catch (Exception ex) {
onError("Algo salió mal: " + ex.getLocalizedMessage());
}
}
}
private void initChangeRoadWeather() {
this.changeRoadWeather = new JButton();
this.changeRoadWeather.setToolTipText("Cambia el tiempo atmosférico de la carretera.");
this.changeRoadWeather.setIcon(new ImageIcon(this.getClass().getResource("/icons/weather.png")));
this.changeRoadWeather.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
select_Weather();
}
});
this.toolbar.add(this.changeRoadWeather);
}
protected void select_Weather() {
ChangueWeatherDialog dialog = new ChangueWeatherDialog ((Frame) SwingUtilities.getWindowAncestor(this));
int status = dialog.open(_map);
if (status == 0) {
System.out.println("Evento de cambio de tiempo atmosférico, cancelado.");
//JOptionPane.showMessageDialog(new JFrame(), "Cancelado");
}
else {
List<Pair<String, Weather>> ws = new ArrayList<>();
ws.add(new Pair<String, Weather>((dialog.getRoad()).getId(), dialog.getWeather()));
try {
_ctrl.addEvent(new NewSetWeatherEvent(_time + dialog.getTicks(), ws));
System.out.println("Nuevo evento de cambio de tiempo atmosfético añadido.");
} catch (Exception ex) {
onError("Algo salió mal: " + ex.getLocalizedMessage());
}
}
}
private void initRunButton() {
this.run = new JButton();
this.run.setToolTipText("Ejecuta el simulador.");
this.run.setIcon(new ImageIcon(this.getClass().getResource("/icons/run.png")));
this.run.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
_stopped = false;
enableToolBar(false);
run_sim(_nTicks);
}
});
this.toolbar.add(this.run);
}
private void initStopButton() {
this.stop = new JButton();
this.stop.setToolTipText("Para la simulación.");
this.stop.setIcon(new ImageIcon(this.getClass().getResource("/icons/stop.png")));
this.stop.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
stop();
}
});
this.toolbar.add(this.stop);
}
//Añadido como parte opcional:
private void initRestartButton() {
this.restart = new JButton();
this.restart.setToolTipText("Reinicia la simulación.");
this.restart.setIcon(new ImageIcon(this.getClass().getResource("/icons/reset.png")));
this.restart.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(file != null) {
InputStream input = null;
try {
input = new FileInputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
_ctrl.reset();
try {
_ctrl.loadEvents(input);
} catch (UnsupportedFileException e2) {
onError("Algo salió mal al cargar el archivo: " + e2.getMessage());
}
System.out.println("Reiniciado el simulador con el archivo: " + file);
JOptionPane.showMessageDialog(fileChooser, "Se ha reiniciado el simulador.");
try {
input.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}else {
onError("Error al reiniciar el simulador: No se ha cargado ningún archivo.");
}
}
});
this.toolbar.add(this.restart);
}
private void initExitButton() {
this.exit = new JButton();
this.exit.setToolTipText("Sale del simulador.");
this.exit.setIcon(new ImageIcon(this.getClass().getResource("/icons/exit.png")));
this.exit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int opt = JOptionPane.showConfirmDialog(null, "¿Estás seguro que quieres salir?", "SALIR", JOptionPane.YES_NO_OPTION);
if (opt == JOptionPane.YES_OPTION) {
System.out.println("Fin de la simulación.");
System.exit(0);
}
}
});
this.toolbar.add(Box.createHorizontalGlue());
this.toolbar.add(this.exit);
}
private void initTicksSpinner() {
SpinnerNumberModel model = new SpinnerNumberModel(1, 0, 10000, 1);
this.nTicks = new JSpinner(model);
this.nTicks.setValue(0);
this.nTicks.setMinimumSize(new Dimension(70, 20));
this.nTicks.setMaximumSize(new Dimension(200, 20));
this.nTicks.setPreferredSize(new Dimension(70, 20));
this.nTicks.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
_nTicks = Integer.valueOf(nTicks.getValue().toString());
}
});
this.toolbar.add(this.nTicks);
}
private void run_sim(int n) {
if (n > 0 && !_stopped) {
try {
this._ctrl.run(1);
} catch (Exception e) {
// TODO show error message
e.getCause();
//e.getMessage("Error al ejecutar el simulador.");
_stopped = true;
return;
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
run_sim(n - 1);
}
});
}
else {
enableToolBar(true);
//this.toolbar.setEnabled(true);
_stopped = true;
}
}
private void stop() {
_stopped = true;
}
private void enableToolBar(boolean set) {
this.loadFile.setEnabled(set);
this.saveFile.setEnabled(set);
this.changeVehicleContClass.setEnabled(set);
this.changeRoadWeather.setEnabled(set);
this.run.setEnabled(set);
this.restart.setEnabled(set);
this.exit.setEnabled(set);
}
@Override
public void onAdvanceStart(RoadMap map, List<Event> events, int time) {
this._map = map;
this._time = time;
}
@Override
public void onAdvanceEnd(RoadMap map, List<Event> events, int time) {
this._map = map;
this._time = time;
}
@Override
public void onEventAdded(RoadMap map, List<Event> events, Event e, int time) {
this._map = map;
this._time = time;
}
@Override
public void onReset(RoadMap map, List<Event> events, int time) {
this._map = map;
this._time = time;
}
@Override
public void onRegister(RoadMap map, List<Event> events, int time) {
this._map = map;
this._time = time;
}
@Override
public void onError(String err) {
System.err.println(err);
JOptionPane.showMessageDialog(new JFrame(), err);
}
}

View File

@ -0,0 +1,142 @@
package simulator.view;
import java.util.ArrayList;
import java.util.List;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import simulator.control.Controller;
import simulator.model.Event;
import simulator.model.RoadMap;
import simulator.model.TrafficSimObserver;
public class EventsTableModel extends AbstractTableModel implements TableModel, TrafficSimObserver {
/**
*
*/
private static final long serialVersionUID = 1L;
private List<Event> _events;
private String[] _colNames = {"Time", "Desc."};
public EventsTableModel(Controller ctrl) {
this._events = new ArrayList<Event>();
ctrl.addObserver(this);
}
public void update() {
fireTableDataChanged();
}
public void setEventsList(List<Event> events) {
this._events = events;
this.update();
}
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
@Override
public String getColumnName(int col) {
return _colNames[col];
}
@Override
public int getColumnCount() {
return _colNames.length;
}
@Override
public int getRowCount() {
return _events == null ? 0 : _events.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object s = null;
switch (columnIndex) {
case 0:
s = _events.get(rowIndex).getTime();
//s = _events.get(rowIndex);
break;
case 1:
s = _events.get(rowIndex).toString();
break;
}
return s;
}
@Override
public void onAdvanceStart(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setEventsList(events);
}
});
}
@Override
public void onAdvanceEnd(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setEventsList(events);
}
});
}
@Override
public void onEventAdded(RoadMap map, List<Event> events, Event e, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setEventsList(events);
}
});
}
@Override
public void onReset(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setEventsList(events);
}
});
}
@Override
public void onRegister(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setEventsList(events);
}
});
}
@Override
public void onError(String err) {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,150 @@
package simulator.view;
import java.util.ArrayList;
import java.util.List;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import simulator.control.Controller;
import simulator.model.Event;
import simulator.model.Junction;
import simulator.model.RoadMap;
import simulator.model.TrafficSimObserver;
public class JunctionsTableModel extends AbstractTableModel implements TableModel, TrafficSimObserver {
/**
*
*/
private static final long serialVersionUID = 1L;
private List<Junction> _junctions;
private String[] _colNames = {"Id", "Green", "Queues"};
public JunctionsTableModel(Controller ctrl) {
this._junctions = new ArrayList<Junction>();
ctrl.addObserver(this);
}
public void update() {
fireTableDataChanged();
}
public void setJunctionsList(List<Junction> junctions) {
this._junctions = junctions;
this.update();
}
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
@Override
public String getColumnName(int col) {
return _colNames[col];
}
@Override
public int getColumnCount() {
return _colNames.length;
}
@Override
public int getRowCount() {
return _junctions == null ? 0 : _junctions.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object s = null;
switch (columnIndex) {
case 0:
s = _junctions.get(rowIndex).getId();
break;
case 1:
if(_junctions.get(rowIndex).getGreenLightIndex() == -1) {
s = "NONE";
}
else {
s = _junctions.get(rowIndex).getInRoads().get(_junctions.get(rowIndex).getGreenLightIndex());
}
break;
case 2:
s = _junctions.get(rowIndex).getQueues();
break;
}
return s;
}
@Override
public void onAdvanceStart(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setJunctionsList(map.getJunctions());
}
});
}
@Override
public void onAdvanceEnd(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setJunctionsList(map.getJunctions());
}
});
}
@Override
public void onEventAdded(RoadMap map, List<Event> events, Event e, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setJunctionsList(map.getJunctions());
}
});
}
@Override
public void onReset(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setJunctionsList(map.getJunctions());
}
});
}
@Override
public void onRegister(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setJunctionsList(map.getJunctions());
}
});
}
@Override
public void onError(String err) {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,106 @@
package simulator.view;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.TitledBorder;
import simulator.control.Controller;
public class MainWindow extends JFrame {
/**
* Serial ID:
*/
private static final long serialVersionUID = 1L;
//Atributos:
private Controller _ctrl;
//Constructor:
public MainWindow(Controller ctrl) {
super("Traffic Simulator");
_ctrl = ctrl;
initGUI();
}
//Métodos:
private void initGUI() {
JPanel mainPanel = new JPanel(new BorderLayout());
this.setContentPane(mainPanel);
mainPanel.add(new ControlPanel(_ctrl), BorderLayout.PAGE_START);
mainPanel.add(new StatusBar(_ctrl), BorderLayout.PAGE_END);
JPanel viewsPanel = new JPanel(new GridLayout(1, 2));
mainPanel.add(viewsPanel, BorderLayout.CENTER);
JPanel tablesPanel = new JPanel();
tablesPanel.setLayout(new BoxLayout(tablesPanel, BoxLayout.Y_AXIS));
viewsPanel.add(tablesPanel);
JPanel mapsPanel = new JPanel();
mapsPanel.setLayout(new BoxLayout(mapsPanel, BoxLayout.Y_AXIS));
viewsPanel.add(mapsPanel);
// tables
JPanel eventsView = createViewPanel(new JTable(new EventsTableModel(_ctrl)), "Events");
eventsView.setPreferredSize(new Dimension(500, 200));
eventsView.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black, 2), "Events",
TitledBorder.LEFT, TitledBorder.TOP));
tablesPanel.add(eventsView);
JPanel vehiclesView = createViewPanel(new JTable(new VehiclesTableModel(_ctrl)), "Vehicles");
vehiclesView.setPreferredSize(new Dimension(500, 200));
vehiclesView.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black, 2), "Vehicles",
TitledBorder.LEFT, TitledBorder.TOP));
tablesPanel.add(vehiclesView);
JPanel roadsView = createViewPanel(new JTable(new RoadsTableModel(_ctrl)), "Roads");
roadsView.setPreferredSize(new Dimension(500, 200));
roadsView.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black, 2), "Roads",
TitledBorder.LEFT, TitledBorder.TOP));
tablesPanel.add(roadsView);
JPanel junctionsView = createViewPanel(new JTable(new JunctionsTableModel(_ctrl)), "Junctions");
junctionsView.setPreferredSize(new Dimension(500, 200));
junctionsView.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black, 2), "Junctions",
TitledBorder.LEFT, TitledBorder.TOP));
tablesPanel.add(junctionsView);
// maps
JPanel mapView = createViewPanel(new MapComponent(_ctrl), "Map");
mapView.setPreferredSize(new Dimension(500, 400));
mapView.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black, 2), "Map",
TitledBorder.LEFT, TitledBorder.TOP));
mapsPanel.add(mapView);
JPanel roadMapView = createViewPanel(new MapByRoadComponent(_ctrl), "Map by Road");
roadMapView.setPreferredSize(new Dimension(500, 400));
roadMapView.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black, 2), "Map by Road",
TitledBorder.LEFT, TitledBorder.TOP));
mapsPanel.add(roadMapView);
//
this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); /*Para desactivar el cierre de la aplicación desde la barra de herramientas*/
//this.setDefaultCloseOperation(HIDE_ON_CLOSE); /*Para activar el cierre de la aplicación desde la barra de herramientas*/
this.pack();
this.setVisible(true);
}
private JPanel createViewPanel(JComponent c, String title) {
JPanel p = new JPanel( new BorderLayout() );
// TODO add a framed border to p with title
p.add(new JScrollPane(c));
return p;
}
}

View File

@ -0,0 +1,337 @@
package simulator.view;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import simulator.control.Controller;
import simulator.model.Event;
import simulator.model.Junction;
import simulator.model.Road;
import simulator.model.RoadMap;
import simulator.model.TrafficSimObserver;
import simulator.model.VehicleStatus;
public class MapByRoadComponent extends JComponent implements TrafficSimObserver {
/**
*
*/
private static final long serialVersionUID = 1L;
//private static final int _JRADIUS = 10;
private static final Color _BG_COLOR = Color.WHITE;
private static final Color _JUNCTION_SOURCE_COLOR = Color.BLUE;
//private static final Color _JUNCTION_LABEL_COLOR = new Color(200, 100, 0);
private static final Color _GREEN_LIGHT_COLOR = Color.GREEN;
private static final Color _RED_LIGHT_COLOR = Color.RED;
private RoadMap _map;
private Image _car;
private Image _sunny;
private Image _cloudy;
private Image _rainy;
private Image _windy;
private Image _storm;
private Image _cont0;
private Image _cont1;
private Image _cont2;
private Image _cont3;
private Image _cont4;
private Image _cont5;
MapByRoadComponent(Controller ctrl) {
setPreferredSize (new Dimension (300, 200));
initGUI();
ctrl.addObserver(this);
}
private void initGUI() {
_car = loadImage("car.png");
_sunny = loadImage("sun.png");
_cloudy = loadImage("cloud.png");
_rainy = loadImage("rain.png");
_windy = loadImage("wind.png");
_storm = loadImage("storm.png");
_cont0 = loadImage("cont_0.png");
_cont1 = loadImage("cont_1.png");
_cont2 = loadImage("cont_2.png");
_cont3 = loadImage("cont_3.png");
_cont4 = loadImage("cont_4.png");
_cont5 = loadImage("cont_5.png");
}
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
Graphics2D g = (Graphics2D) graphics;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// clear with a background color
g.setColor(_BG_COLOR);
g.clearRect(0, 0, getWidth(), getHeight());
if (_map == null || _map.getJunctions().size() == 0) {
g.setColor(Color.red);
g.drawString("No map yet!", getWidth() / 2 - 50, getHeight() / 2);
} else {
updatePrefferedSize();
drawMap(g);
}
}
private void drawMap(Graphics g) {
drawRoads(g);
drawVehicles(g);
//drawJunctions(g);
}
private void drawRoads(Graphics g) {
for (int i = 0; i < _map.getRoads().size(); i++) {
// the road goes from (x1,y1) to (x2,y2)
int x1 = _map.getRoads().get(i).getJSoruce().getX();
int y1 = _map.getRoads().get(i).getJSoruce().getY();
int x2 = _map.getRoads().get(i).getJDest().getX();
int y2 = _map.getRoads().get(i).getJDest().getY();
// choose a color for the arrow depending on the traffic light of the road
Color arrowColor = _RED_LIGHT_COLOR;
int idx = _map.getRoads().get(i).getJDest().getGreenLightIndex();
if (idx != -1 && _map.getRoads().get(i).equals(_map.getRoads().get(i).getJDest().getInRoads().get(idx))) {
arrowColor = _GREEN_LIGHT_COLOR;
}
// choose a color for the road depending on the total contamination, the darker
// the
// more contaminated (wrt its co2 limit)
int roadColorValue = 200 - (int) (200.0 * Math.min(1.0, (double) _map.getRoads().get(i).getTotalCO2() / (1.0 + (double) _map.getRoads().get(i).getCO2Limit())));
Color roadColor = new Color(roadColorValue, roadColorValue, roadColorValue);
// draw line from (x1,y1) to (x2,y2) with arrow of color arrowColor and line of
// color roadColor. The size of the arrow is 15px length and 5 px width
drawLine(g, x1, y1, x2, y2, 15, 5, roadColor, arrowColor, i);
}
}
private void drawVehicles(Graphics g) {
for (int i = 0; i < this._map.getVehicles().size(); i++) {
if (this._map.getVehicles().get(i).getStatus() != VehicleStatus.ARRIVED) {
// The calculation below compute the coordinate (vX,vY) of the vehicle on the
// corresponding road. It is calculated relativly to the length of the road, and
// the location on the vehicle.
Road r = this._map.getVehicles().get(i).getRoad();
int numRoad = Integer.parseInt(r.getId().substring(1));
int x1 = 50;
int y1 = 50;
int x2 = getWidth()-100;
int y2 = 50;
double roadLength = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
double alpha = Math.atan(((double) Math.abs(x1 - x2)) / ((double) Math.abs(y1 - y2)));
double relLoc = roadLength * ((double) this._map.getVehicles().get(i).getLocation()) / ((double) r.getLenght());
@SuppressWarnings("unused")
double x = Math.sin(alpha) * relLoc;
double y = Math.cos(alpha) * relLoc;
//int xDir = x1 < x2 ? 1 : -1;
int yDir = y1 < y2 ? 1 : -1;
int vX = (int) (x = x1 + (int) ((x2 - x1) * ((double) this._map.getVehicles().get(i).getLocation() / (double) r.getLenght())));
int vY = (y1 + yDir * ((int) y)) * numRoad;
// Choose a color for the vehcile's label and background, depending on its
// contamination class
int vLabelColor = (int) (25.0 * (10.0 - (double) this._map.getVehicles().get(i).getContClass()));
g.setColor(new Color(0, vLabelColor, 0));
// draw an image of a car (with circle as background) and it identifier
g.fillOval(vX - 1, vY - 6, 14, 14);
g.drawImage(_car, vX, vY - 6, 16, 16, this);
g.drawString(this._map.getVehicles().get(i).getId(), vX, vY - 6);
}
}
}
/*
private void drawJunctions(Graphics g) {
for (int i = 0; i < _map.getJunctions().size(); i++) {
// (x,y) are the coordinates of the junction
int x = 50;
int y = (i+1)*50;
// draw a circle with center at (x,y) with radius _JRADIUS
g.setColor(_JUNCTION_SOURCE_COLOR);
g.fillOval(x - _JRADIUS / 2, y - _JRADIUS / 2, _JRADIUS, _JRADIUS);
// draw the junction's identifier at (x,y)
g.setColor(_JUNCTION_LABEL_COLOR);
g.drawString(_map.getJunctions().get(i).getId(), x, y);
}
}
*/
// this method is used to update the preffered and actual size of the component,
// so when we draw outside the visible area the scrollbars show up
private void updatePrefferedSize() {
int maxW = 200;
int maxH = 200;
for (Junction j : _map.getJunctions()) {
maxW = Math.max(maxW, j.getX());
maxH = Math.max(maxH, j.getY());
}
maxW += 20;
maxH += 20;
//setPreferredSize(new Dimension(maxW, maxH));
//setSize(new Dimension(maxW, maxH));
if (maxW > getWidth() || maxH > getHeight()) {
setPreferredSize(new Dimension(maxW, maxH));
setSize(new Dimension(maxW, maxH));
}
}
// This method draws a line from (x1,y1) to (x2,y2) with an arrow.
// The arrow is of height h and width w.
// The last two arguments are the colors of the arrow and the line
private void drawLine(//
Graphics g, //
int x1, int y1, //
int x2, int y2, //
int w, int h, //
Color lineColor, Color arrowColor, int i) {
g.setColor(Color.BLACK);
g.drawString(_map.getRoads().get(i).getId(), 30, (i+1)*50);
/*
int dx = x2 - x1, dy = y2 - y1;
double D = Math.sqrt(dx * dx + dy * dy);
double xm = D - w, xn = xm, ym = h, yn = -h, x;
double sin = dy / D, cos = dx / D;
x = xm * cos - ym * sin + x1;
ym = xm * sin + ym * cos + y1;
xm = x;
x = xn * cos - yn * sin + x1;
yn = xn * sin + yn * cos + y1;
xn = x;
int[] xpoints = { x2, (int) xm, (int) xn };
int[] ypoints = { y2, (int) ym, (int) yn };
*/
g.setColor(lineColor);
//g.drawLine(x1, y1, x2, y2);
g.drawLine(50, (i+1)*50, getWidth()-100, (i+1)*50);
g.setColor(arrowColor);
//g.fillPolygon(xpoints, ypoints, 3);
g.setColor(_JUNCTION_SOURCE_COLOR);
g.fillOval(50, (i+1)*48, 9, 9);
int idx = _map.getRoads().get(i).getJDest().getGreenLightIndex();
if (idx != -1 && _map.getRoads().get(i).equals(_map.getRoads().get(i).getJDest().getInRoads().get(idx))) {
g.setColor(_GREEN_LIGHT_COLOR);
}
else {
g.setColor(_RED_LIGHT_COLOR);
}
g.fillOval(getWidth()-100, (i+1)*48, 9, 9);
switch (_map.getRoads().get(i).getWeather()) {
case SUNNY:
g.drawImage(_sunny, getWidth()-90, (i+1)*45, 32, 32, this);
break;
case CLOUDY:
g.drawImage(_cloudy, getWidth()-90, (i+1)*45, 32, 32, this);
break;
case RAINY:
g.drawImage(_rainy, getWidth()-90, (i+1)*45, 32, 32, this);
break;
case WINDY:
g.drawImage(_windy, getWidth()-90, (i+1)*45, 32, 32, this);
break;
case STORM:
g.drawImage(_storm, getWidth()-90, (i+1)*45, 32, 32, this);
break;
}
switch ((int) Math.floor(Math.min((double)_map.getRoads().get(i).getTotalCO2()/(1.0 + (double)_map.getRoads().get(i).getCO2Limit()),1.0) / 0.19)) {
case 0:
g.drawImage(_cont0, getWidth()-50, (i+1)*45, 32, 32, this);
break;
case 1:
g.drawImage(_cont1, getWidth()-50, (i+1)*45, 32, 32, this);
break;
case 2:
g.drawImage(_cont2, getWidth()-50, (i+1)*45, 32, 32, this);
break;
case 3:
g.drawImage(_cont3, getWidth()-50, (i+1)*45, 32, 32, this);
break;
case 4:
g.drawImage(_cont4, getWidth()-50, (i+1)*45, 32, 32, this);
break;
case 5:
g.drawImage(_cont5, getWidth()-50, (i+1)*45, 32, 32, this);
break;
}
}
// loads an image from a file
private Image loadImage(String img) {
Image i = null;
try {
return ImageIO.read(new File("resources/icons/" + img));
} catch (IOException e) {
}
return i;
}
public void update(RoadMap map) {
_map = map;
repaint();
}
@Override
public void onAdvanceStart(RoadMap map, List<Event> events, int time) {
}
@Override
public void onAdvanceEnd(RoadMap map, List<Event> events, int time) {
update(map);
}
@Override
public void onEventAdded(RoadMap map, List<Event> events, Event e, int time) {
update(map);
}
@Override
public void onReset(RoadMap map, List<Event> events, int time) {
update(map);
}
@Override
public void onRegister(RoadMap map, List<Event> events, int time) {
update(map);
}
@Override
public void onError(String err) {
}
}

View File

@ -0,0 +1,251 @@
package simulator.view;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import simulator.control.Controller;
import simulator.model.Event;
import simulator.model.Junction;
import simulator.model.Road;
import simulator.model.RoadMap;
import simulator.model.TrafficSimObserver;
import simulator.model.Vehicle;
import simulator.model.VehicleStatus;
public class MapComponent extends JPanel implements TrafficSimObserver {
private static final long serialVersionUID = 1L;
private static final int _JRADIUS = 10;
private static final Color _BG_COLOR = Color.WHITE;
private static final Color _JUNCTION_COLOR = Color.BLUE;
private static final Color _JUNCTION_LABEL_COLOR = new Color(200, 100, 0);
private static final Color _GREEN_LIGHT_COLOR = Color.GREEN;
private static final Color _RED_LIGHT_COLOR = Color.RED;
private RoadMap _map;
private Image _car;
MapComponent(Controller ctrl) {
initGUI();
ctrl.addObserver(this);
}
private void initGUI() {
_car = loadImage("car_front.png");
}
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
Graphics2D g = (Graphics2D) graphics;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// clear with a background color
g.setColor(_BG_COLOR);
g.clearRect(0, 0, getWidth(), getHeight());
if (_map == null || _map.getJunctions().size() == 0) {
g.setColor(Color.red);
g.drawString("No map yet!", getWidth() / 2 - 50, getHeight() / 2);
} else {
updatePrefferedSize();
drawMap(g);
}
}
private void drawMap(Graphics g) {
drawRoads(g);
drawVehicles(g);
drawJunctions(g);
}
private void drawRoads(Graphics g) {
for (Road r : _map.getRoads()) {
// the road goes from (x1,y1) to (x2,y2)
int x1 = r.getJSoruce().getX();
int y1 = r.getJSoruce().getY();
int x2 = r.getJDest().getX();
int y2 = r.getJDest().getY();
// choose a color for the arrow depending on the traffic light of the road
Color arrowColor = _RED_LIGHT_COLOR;
int idx = r.getJDest().getGreenLightIndex();
if (idx != -1 && r.equals(r.getJDest().getInRoads().get(idx))) {
arrowColor = _GREEN_LIGHT_COLOR;
}
// choose a color for the road depending on the total contamination, the darker
// the
// more contaminated (wrt its co2 limit)
int roadColorValue = 200 - (int) (200.0 * Math.min(1.0, (double) r.getTotalCO2() / (1.0 + (double) r.getCO2Limit())));
Color roadColor = new Color(roadColorValue, roadColorValue, roadColorValue);
// draw line from (x1,y1) to (x2,y2) with arrow of color arrowColor and line of
// color roadColor. The size of the arrow is 15px length and 5 px width
drawLineWithArrow(g, x1, y1, x2, y2, 15, 5, roadColor, arrowColor);
}
}
private void drawVehicles(Graphics g) {
for (Vehicle v : _map.getVehicles()) {
if (v.getStatus() != VehicleStatus.ARRIVED) {
// The calculation below compute the coordinate (vX,vY) of the vehicle on the
// corresponding road. It is calculated relativly to the length of the road, and
// the location on the vehicle.
Road r = v.getRoad();
int x1 = r.getJSoruce().getX();
int y1 = r.getJSoruce().getY();
int x2 = r.getJDest().getX();
int y2 = r.getJDest().getY();
double roadLength = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
double alpha = Math.atan(((double) Math.abs(x1 - x2)) / ((double) Math.abs(y1 - y2)));
double relLoc = roadLength * ((double) v.getLocation()) / ((double) r.getLenght());
double x = Math.sin(alpha) * relLoc;
double y = Math.cos(alpha) * relLoc;
int xDir = x1 < x2 ? 1 : -1;
int yDir = y1 < y2 ? 1 : -1;
int vX = x1 + xDir * ((int) x);
int vY = y1 + yDir * ((int) y);
// Choose a color for the vehcile's label and background, depending on its
// contamination class
int vLabelColor = (int) (25.0 * (10.0 - (double) v.getContClass()));
g.setColor(new Color(0, vLabelColor, 0));
// draw an image of a car (with circle as background) and it identifier
g.fillOval(vX - 1, vY - 6, 14, 14);
g.drawImage(_car, vX, vY - 6, 12, 12, this);
g.drawString(v.getId(), vX, vY - 6);
}
}
}
private void drawJunctions(Graphics g) {
for (Junction j : _map.getJunctions()) {
// (x,y) are the coordinates of the junction
int x = j.getX();
int y = j.getY();
// draw a circle with center at (x,y) with radius _JRADIUS
g.setColor(_JUNCTION_COLOR);
g.fillOval(x - _JRADIUS / 2, y - _JRADIUS / 2, _JRADIUS, _JRADIUS);
// draw the junction's identifier at (x,y)
g.setColor(_JUNCTION_LABEL_COLOR);
g.drawString(j.getId(), x, y);
}
}
// this method is used to update the preffered and actual size of the component,
// so when we draw outside the visible area the scrollbars show up
private void updatePrefferedSize() {
int maxW = 200;
int maxH = 200;
for (Junction j : _map.getJunctions()) {
maxW = Math.max(maxW, j.getX());
maxH = Math.max(maxH, j.getY());
}
maxW += 20;
maxH += 20;
//setPreferredSize(new Dimension(maxW, maxH));
//setSize(new Dimension(maxW, maxH));
if (maxW > getWidth() || maxH > getHeight()) {
setPreferredSize(new Dimension(maxW, maxH));
setSize(new Dimension(maxW, maxH));
}
}
// This method draws a line from (x1,y1) to (x2,y2) with an arrow.
// The arrow is of height h and width w.
// The last two arguments are the colors of the arrow and the line
private void drawLineWithArrow(//
Graphics g, //
int x1, int y1, //
int x2, int y2, //
int w, int h, //
Color lineColor, Color arrowColor) {
int dx = x2 - x1, dy = y2 - y1;
double D = Math.sqrt(dx * dx + dy * dy);
double xm = D - w, xn = xm, ym = h, yn = -h, x;
double sin = dy / D, cos = dx / D;
x = xm * cos - ym * sin + x1;
ym = xm * sin + ym * cos + y1;
xm = x;
x = xn * cos - yn * sin + x1;
yn = xn * sin + yn * cos + y1;
xn = x;
int[] xpoints = { x2, (int) xm, (int) xn };
int[] ypoints = { y2, (int) ym, (int) yn };
g.setColor(lineColor);
g.drawLine(x1, y1, x2, y2);
g.setColor(arrowColor);
g.fillPolygon(xpoints, ypoints, 3);
}
// loads an image from a file
private Image loadImage(String img) {
Image i = null;
try {
return ImageIO.read(new File("resources/icons/" + img));
} catch (IOException e) {
}
return i;
}
public void update(RoadMap map) {
_map = map;
repaint();
}
@Override
public void onAdvanceStart(RoadMap map, List<Event> events, int time) {
}
@Override
public void onAdvanceEnd(RoadMap map, List<Event> events, int time) {
update(map);
}
@Override
public void onEventAdded(RoadMap map, List<Event> events, Event e, int time) {
update(map);
}
@Override
public void onReset(RoadMap map, List<Event> events, int time) {
update(map);
}
@Override
public void onRegister(RoadMap map, List<Event> events, int time) {
update(map);
}
@Override
public void onError(String err) {
}
}

View File

@ -0,0 +1,157 @@
package simulator.view;
import java.util.ArrayList;
import java.util.List;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import simulator.control.Controller;
import simulator.model.Event;
import simulator.model.Road;
import simulator.model.RoadMap;
import simulator.model.TrafficSimObserver;
public class RoadsTableModel extends AbstractTableModel implements TableModel, TrafficSimObserver {
/**
*
*/
private static final long serialVersionUID = 1L;
private List<Road> _roads;
private String[] _colNames = {"Id", "Lenght", "Weather", "Max Speed", "Speed Limit", "Total CO2", "CO2 Limit"};
public RoadsTableModel(Controller ctrl) {
this._roads = new ArrayList<Road>();
ctrl.addObserver(this);
}
public void update() {
fireTableDataChanged();
}
public void setRoadsList(List<Road> roads) {
this._roads = roads;
this.update();
}
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
@Override
public String getColumnName(int col) {
return _colNames[col];
}
@Override
public int getColumnCount() {
return _colNames.length;
}
@Override
public int getRowCount() {
return this._roads == null ? 0 : this._roads.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object s = null;
switch (columnIndex) {
case 0:
s = _roads.get(rowIndex).getId();
break;
case 1:
s = _roads.get(rowIndex).getLenght();
break;
case 2:
s = _roads.get(rowIndex).getWeather();
break;
case 3:
s = _roads.get(rowIndex).getMaxSpeed();
break;
case 4:
s = _roads.get(rowIndex).getCurrentSpeedLimit();
break;
case 5:
s = (int) _roads.get(rowIndex).getTotalCO2();
break;
case 6:
s = (int) _roads.get(rowIndex).getCO2Limit();
break;
}
return s;
}
@Override
public void onAdvanceStart(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setRoadsList(map.getRoads());
}
});
}
@Override
public void onAdvanceEnd(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setRoadsList(map.getRoads());
}
});
}
@Override
public void onEventAdded(RoadMap map, List<Event> events, Event e, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setRoadsList(map.getRoads());
}
});
}
@Override
public void onReset(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setRoadsList(map.getRoads());
}
});
}
@Override
public void onRegister(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setRoadsList(map.getRoads());
}
});
}
@Override
public void onError(String err) {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,108 @@
package simulator.view;
import java.awt.FlowLayout;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToolBar.Separator;
import simulator.control.Controller;
import simulator.model.Event;
import simulator.model.RoadMap;
import simulator.model.TrafficSimObserver;
public class StatusBar extends JPanel implements TrafficSimObserver {
/**
*
*/
private static final long serialVersionUID = 1L;
//Atributos:
private JLabel time;
private JLabel actualTime;
private JLabel event;
private JLabel lastEventAdded;
private JLabel calendar;
private final static Calendar _calendario = new GregorianCalendar();
private final static int _hour = _calendario.get(Calendar.HOUR_OF_DAY);
private final static int _minutes = _calendario.get(Calendar.MINUTE);
private List<Event> _events;
//Constructor:
public StatusBar(Controller ctrl) {
this._events = new ArrayList<Event>();
this.InitGUI();
ctrl.addObserver(this);
}
private void InitGUI() {
this.setLayout(new FlowLayout(FlowLayout.LEFT));
this.setBorder(BorderFactory.createBevelBorder(1));
this.time = new JLabel("Time: ");
this.actualTime = new JLabel();
this.event = new JLabel("Event Added: ");
if(this._events.size() > 0) {
this.lastEventAdded = new JLabel(this._events.get(this._events.size()-1).toString());
}
else {
this.lastEventAdded = new JLabel();
}
this.calendar = new JLabel("Local time: " + _hour + " : " + _minutes); //Aunque no se pide en la práctica, añado la hora de forma opcional.
this.add(this.calendar);
this.add(new Separator());
this.add(this.time);
this.add(this.actualTime);
this.add(new Separator());
this.add(this.event);
this.add(this.lastEventAdded);
}
//Métodos:
@Override
public void onAdvanceStart(RoadMap map, List<Event> events, int time) {
this._events = events;
this.actualTime.setText(String.valueOf(time));
}
@Override
public void onAdvanceEnd(RoadMap map, List<Event> events, int time) {
this._events = events;
this.actualTime.setText(String.valueOf(time));
}
@Override
public void onEventAdded(RoadMap map, List<Event> events, Event e, int time) {
this._events = events;
this.lastEventAdded.setText(String.valueOf(e));
}
@Override
public void onReset(RoadMap map, List<Event> events, int time) {
this._events = events;
this.actualTime.setText(String.valueOf(0));
}
@Override
public void onRegister(RoadMap map, List<Event> events, int time) {
this._events = events;
this.actualTime.setText(String.valueOf(time));
}
@Override
public void onError(String err) {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,161 @@
package simulator.view;
import java.util.ArrayList;
import java.util.List;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import simulator.control.Controller;
import simulator.model.Event;
import simulator.model.RoadMap;
import simulator.model.TrafficSimObserver;
import simulator.model.Vehicle;
public class VehiclesTableModel extends AbstractTableModel implements TableModel, TrafficSimObserver {
/**
*
*/
private static final long serialVersionUID = 1L;
//private Controller _ctrl;
private List<Vehicle> _vehicles;
private String[] _colNames = {"Id", "Location", "Itinerary", "CO2 Class", "Max Speed", "Speed", "Total CO2", "Distace"};
public VehiclesTableModel(Controller ctrl) {
this._vehicles = new ArrayList<Vehicle>();
ctrl.addObserver(this);
}
public void update() {
fireTableDataChanged();
}
public void setVehicleList(List<Vehicle> vehicles) {
this._vehicles = vehicles;
this.update();
}
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
@Override
public String getColumnName(int col) {
return _colNames[col];
}
@Override
public int getColumnCount() {
return _colNames.length;
}
@Override
public int getRowCount() {
return _vehicles == null ? 0 : _vehicles.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object s = null;
switch (columnIndex) {
case 0:
s = _vehicles.get(rowIndex).getId();
break;
case 1:
s = _vehicles.get(rowIndex).getRoad() + ":"
+ _vehicles.get(rowIndex).getLocation();
break;
case 2:
s = _vehicles.get(rowIndex).getItinerary();
break;
case 3:
s = _vehicles.get(rowIndex).getContClass();
break;
case 4:
s = _vehicles.get(rowIndex).getMaxSpeed();
break;
case 5:
s = _vehicles.get(rowIndex).getCurrentSpeed();
break;
case 6:
s = (int) _vehicles.get(rowIndex).getTotalCont();
break;
case 7:
s = _vehicles.get(rowIndex).getTotalDistance();
break;
}
return s;
}
@Override
public void onAdvanceStart(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setVehicleList(map.getVehicles());
}
});
}
@Override
public void onAdvanceEnd(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setVehicleList(map.getVehicles());
}
});
}
@Override
public void onEventAdded(RoadMap map, List<Event> events, Event e, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setVehicleList(map.getVehicles());
}
});
}
@Override
public void onReset(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setVehicleList(map.getVehicles());
}
});
}
@Override
public void onRegister(RoadMap map, List<Event> events, int time) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setVehicleList(map.getVehicles());
}
});
}
@Override
public void onError(String err) {
// TODO Auto-generated method stub
}
}