Traffic Simulator
Traffic simulator with GUI.
10
TrafficSimulator/README.md
Normal 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
|
73
TrafficSimulator/src/extra/dialog/DialogWindowExample.java
Normal 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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
18
TrafficSimulator/src/extra/dialog/Dish.java
Normal 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;
|
||||
}
|
||||
}
|
115
TrafficSimulator/src/extra/dialog/MyDialogWindow.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
177
TrafficSimulator/src/extra/json/UsageExample.java
Normal 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();
|
||||
|
||||
}
|
||||
|
||||
}
|
24
TrafficSimulator/src/extra/jtable/EventEx.java
Normal 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;
|
||||
|
||||
}
|
||||
|
||||
}
|
87
TrafficSimulator/src/extra/jtable/EventsTableModel.java
Normal 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;
|
||||
}
|
||||
}
|
150
TrafficSimulator/src/extra/jtable/JTableExamples.java
Normal 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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
98
TrafficSimulator/src/extra/testing/TestExamples.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
BIN
TrafficSimulator/src/icons/car.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
TrafficSimulator/src/icons/car_front.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
TrafficSimulator/src/icons/cloud.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
TrafficSimulator/src/icons/co2class.png
Normal file
After Width: | Height: | Size: 998 B |
BIN
TrafficSimulator/src/icons/cont_0.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
TrafficSimulator/src/icons/cont_1.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
TrafficSimulator/src/icons/cont_2.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
TrafficSimulator/src/icons/cont_3.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
TrafficSimulator/src/icons/cont_4.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
TrafficSimulator/src/icons/cont_5.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
TrafficSimulator/src/icons/exit.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
TrafficSimulator/src/icons/open.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
TrafficSimulator/src/icons/rain.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
TrafficSimulator/src/icons/reset.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
TrafficSimulator/src/icons/run.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
TrafficSimulator/src/icons/save.png
Normal file
After Width: | Height: | Size: 877 B |
BIN
TrafficSimulator/src/icons/stop.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
TrafficSimulator/src/icons/storm.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
TrafficSimulator/src/icons/sun.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
TrafficSimulator/src/icons/weather.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
TrafficSimulator/src/icons/wind.png
Normal file
After Width: | Height: | Size: 1020 B |
95
TrafficSimulator/src/simulator/control/Controller.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
27
TrafficSimulator/src/simulator/factories/Builder.java
Normal 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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
7
TrafficSimulator/src/simulator/factories/Factory.java
Normal file
@ -0,0 +1,7 @@
|
||||
package simulator.factories;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
public interface Factory<T> {
|
||||
public T createInstance(JSONObject info);
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
249
TrafficSimulator/src/simulator/launcher/Main.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
20
TrafficSimulator/src/simulator/misc/Pair.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
70
TrafficSimulator/src/simulator/misc/SortedArrayList.java
Normal 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");
|
||||
}
|
||||
|
||||
}
|
42
TrafficSimulator/src/simulator/model/CityRoad.java
Normal 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));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package simulator.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface DequeuingStrategy {
|
||||
List<Vehicle> dequeue(List<Vehicle> q);
|
||||
}
|
29
TrafficSimulator/src/simulator/model/Event.java
Normal 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();
|
||||
|
||||
}
|
62
TrafficSimulator/src/simulator/model/InterCityRoad.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
157
TrafficSimulator/src/simulator/model/Junction.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
23
TrafficSimulator/src/simulator/model/MoveAllStrategy.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
21
TrafficSimulator/src/simulator/model/MoveFirstStrategy.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
33
TrafficSimulator/src/simulator/model/NewCityRoadEvent.java
Normal 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+"'";
|
||||
}
|
||||
|
||||
}
|
@ -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+"'";
|
||||
}
|
||||
|
||||
}
|
32
TrafficSimulator/src/simulator/model/NewJunctionEvent.java
Normal 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+"'";
|
||||
}
|
||||
|
||||
}
|
24
TrafficSimulator/src/simulator/model/NewRoadEvent.java
Normal 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);
|
||||
|
||||
}
|
@ -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 + "]";
|
||||
}
|
||||
|
||||
}
|
58
TrafficSimulator/src/simulator/model/NewSetWeatherEvent.java
Normal 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 + "]";
|
||||
}
|
||||
|
||||
}
|
52
TrafficSimulator/src/simulator/model/NewVehicleEvent.java
Normal 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+"'";
|
||||
}
|
||||
|
||||
}
|
6
TrafficSimulator/src/simulator/model/Observable.java
Normal file
@ -0,0 +1,6 @@
|
||||
package simulator.model;
|
||||
|
||||
public interface Observable<T> {
|
||||
void addObserver(T o);
|
||||
void removeObserver(T o);
|
||||
}
|
189
TrafficSimulator/src/simulator/model/Road.java
Normal 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;
|
||||
}
|
||||
}
|
132
TrafficSimulator/src/simulator/model/RoadMap.java
Normal 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;
|
||||
}
|
||||
}
|
32
TrafficSimulator/src/simulator/model/RoundRobinStrategy.java
Normal 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;
|
||||
|
||||
}
|
||||
|
||||
}
|
25
TrafficSimulator/src/simulator/model/SimulatedObject.java
Normal 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();
|
||||
}
|
12
TrafficSimulator/src/simulator/model/TrafficSimObserver.java
Normal 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);
|
||||
}
|
143
TrafficSimulator/src/simulator/model/TrafficSimulator.java
Normal 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("}");
|
||||
|
||||
}
|
||||
|
||||
}
|
211
TrafficSimulator/src/simulator/model/Vehicle.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
5
TrafficSimulator/src/simulator/model/VehicleStatus.java
Normal file
@ -0,0 +1,5 @@
|
||||
package simulator.model;
|
||||
|
||||
public enum VehicleStatus {
|
||||
PENDING, TRAVELING, WAITING, ARRIVED;
|
||||
}
|
5
TrafficSimulator/src/simulator/model/Weather.java
Normal file
@ -0,0 +1,5 @@
|
||||
package simulator.model;
|
||||
|
||||
public enum Weather {
|
||||
SUNNY, CLOUDY, RAINY, WINDY, STORM;
|
||||
}
|
162
TrafficSimulator/src/simulator/view/ChangueCO2Dialog.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
166
TrafficSimulator/src/simulator/view/ChangueWeatherDialog.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
494
TrafficSimulator/src/simulator/view/ControlPanel.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
142
TrafficSimulator/src/simulator/view/EventsTableModel.java
Normal 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
|
||||
|
||||
}
|
||||
|
||||
}
|
150
TrafficSimulator/src/simulator/view/JunctionsTableModel.java
Normal 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
|
||||
|
||||
}
|
||||
}
|
106
TrafficSimulator/src/simulator/view/MainWindow.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
337
TrafficSimulator/src/simulator/view/MapByRoadComponent.java
Normal 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) {
|
||||
}
|
||||
|
||||
}
|
251
TrafficSimulator/src/simulator/view/MapComponent.java
Normal 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) {
|
||||
}
|
||||
|
||||
}
|
157
TrafficSimulator/src/simulator/view/RoadsTableModel.java
Normal 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
|
||||
|
||||
}
|
||||
|
||||
}
|
108
TrafficSimulator/src/simulator/view/StatusBar.java
Normal 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
|
||||
|
||||
}
|
||||
|
||||
}
|
161
TrafficSimulator/src/simulator/view/VehiclesTableModel.java
Normal 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
|
||||
|
||||
}
|
||||
}
|