summaryrefslogtreecommitdiff
path: root/src/main/java/simulator
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-06-06 08:02:52 +0300
committerPaul Buetow <paul@buetow.org>2025-06-06 08:02:52 +0300
commit1d99762c7965d351510cfb5e08eac25e48d96038 (patch)
treef469493e911878ab9055ccf0494211bf9015922d /src/main/java/simulator
parent4d35597bd92607c4d194686e20b125044506c79a (diff)
Modernize project structure, update Maven config, move sources, add logging config, update README and .gitignore
Diffstat (limited to 'src/main/java/simulator')
-rw-r--r--src/main/java/simulator/VSCreateTask.java179
-rw-r--r--src/main/java/simulator/VSLogging.java201
-rw-r--r--src/main/java/simulator/VSMain.java70
-rw-r--r--src/main/java/simulator/VSMenuItemStates.java109
-rw-r--r--src/main/java/simulator/VSSimulator.java1536
-rw-r--r--src/main/java/simulator/VSSimulatorFrame.java628
-rw-r--r--src/main/java/simulator/VSSimulatorVisualization.java1814
7 files changed, 4537 insertions, 0 deletions
diff --git a/src/main/java/simulator/VSCreateTask.java b/src/main/java/simulator/VSCreateTask.java
new file mode 100644
index 0000000..9a6426b
--- /dev/null
+++ b/src/main/java/simulator/VSCreateTask.java
@@ -0,0 +1,179 @@
+package simulator;
+
+import core.VSInternalProcess;
+import core.VSTask;
+import events.VSAbstractEvent;
+import events.VSRegisteredEvents;
+import events.internal.VSProtocolEvent;
+
+/**
+ * The class VSCreateTask, an object of this class represents how new
+ * VSTask objects are to be created using JComboBox selections of the
+ * GUI editor..
+ *
+ * @author Paul C. Buetow
+ */
+public class VSCreateTask {
+ /** The event classname. */
+ private String eventClassname;
+
+ /** The create task menu string. */
+ private String menuText;
+
+ /** The protocol classname. */
+ private String protocolClassname;
+
+ /** The shortname. */
+ private String shortname;
+
+ /** The task is a protocol activation. */
+ private boolean isProtocolActivation;
+
+ /** The task is a protocol deactivation. */
+ private boolean isProtocolDeactivation;
+
+ /** The task is a client protocol. */
+ private boolean isClientProtocol;
+
+ /** True, if the task is a client request. false, if the task is a
+ * server request
+ */
+ private boolean isRequest;
+
+ /**
+ * Instantiates a new VSCreateTask object.
+ *
+ * @param menuText the menu text
+ * @param eventClassname the event classname
+ */
+ public VSCreateTask(String menuText, String eventClassname) {
+ this.menuText = menuText;
+ this.eventClassname = eventClassname;
+ }
+
+ /**
+ * Instantiates a new VSCreateTask dummy object.
+ *
+ * @param menuText the menu text
+ */
+ public VSCreateTask(String menuText) {
+ this.menuText = menuText;
+ this.eventClassname = null;
+ }
+
+ /**
+ * Sets if it is a protocol activation task.
+ *
+ * @param isProtocolActivation true, if it is a protocol activation
+ * task.
+ */
+ public void isProtocolActivation(boolean isProtocolActivation) {
+ this.isProtocolActivation = isProtocolActivation;
+
+ if (isProtocolActivation)
+ isProtocolDeactivation(false);
+ }
+
+ /**
+ * Sets if it is a protocol deactivation task.
+ *
+ * @param isProtocolDeactivation true, if it is a protocol deactivation
+ * task.
+ */
+ public void isProtocolDeactivation(boolean isProtocolDeactivation) {
+ this.isProtocolDeactivation = isProtocolDeactivation;
+
+ if (isProtocolDeactivation)
+ isProtocolActivation(false);
+ }
+
+ /**
+ * Sets if it is a client protocol.
+ *
+ * @param isClientProtocol the is client protocol
+ */
+ public void isClientProtocol(boolean isClientProtocol) {
+ this.isClientProtocol = isClientProtocol;
+ }
+
+ /**
+ * Sets if it is a client request.
+ *
+ * @param isRequest the is client request
+ */
+ public void isRequest(boolean isRequest) {
+ this.isRequest = isRequest;
+ }
+
+ /**
+ * Checks if it is a dummy object..
+ *
+ * @return true, if dummy
+ */
+ public boolean isDummy() {
+ return eventClassname == null;
+ }
+
+ /**
+ * Sets the protocol classname.
+ *
+ * @param protocolClassname the protocol classname
+ */
+ public void setProtocolClassname(String protocolClassname) {
+ this.protocolClassname = protocolClassname;
+ }
+
+ /**
+ * Sets the shortname.
+ *
+ * @param shortname the shortname
+ */
+ public void setShortname(String shortname) {
+ this.shortname = shortname;
+ }
+
+ /**
+ * Gets the create tasks menu text.
+ *
+ * @return The text
+ */
+ public String getMenuText() {
+ return menuText;
+ }
+
+ /**
+ * Creates the task.
+ *
+ * @param process the process
+ * @param time the time
+ * @param localTimedTask the local timed task
+ *
+ * @return the new task
+ */
+ public VSTask createTask(VSInternalProcess process, long time,
+ boolean localTimedTask) {
+ VSAbstractEvent event = null;
+
+ if (isRequest) {
+ event = process.getProtocolObject(eventClassname);
+
+ } else {
+ event = VSRegisteredEvents.createEventInstanceByClassname(
+ eventClassname, process);
+ }
+
+ event.init(process);
+ if (shortname != null)
+ event.setShortname(shortname);
+
+ if (isProtocolActivation || isProtocolDeactivation) {
+ VSProtocolEvent protocolEvent = (VSProtocolEvent) event;
+ protocolEvent.setProtocolClassname(protocolClassname);
+ protocolEvent.isProtocolActivation(isProtocolActivation);
+ protocolEvent.isClientProtocol(isClientProtocol);
+ }
+
+ return new VSTask(time, process, event, localTimedTask);
+ }
+}
+
diff --git a/src/main/java/simulator/VSLogging.java b/src/main/java/simulator/VSLogging.java
new file mode 100644
index 0000000..66cb563
--- /dev/null
+++ b/src/main/java/simulator/VSLogging.java
@@ -0,0 +1,201 @@
+package simulator;
+
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.swing.JTextArea;
+
+import utils.VSTools;
+
+/**
+ * The class VSLogging, an object of this class is responsible for the loging
+ * of text messages into the simulator's loging window.
+ *
+ * @author Paul C. Buetow
+ */
+public class VSLogging {
+ /** The loging area. */
+ private JTextArea logingArea;
+
+ /** The filter text. */
+ private String filterText;
+
+ /** The pause lines. Used for cacheing the loging if the loging is
+ * deactivated for a while
+ */
+ private ArrayList<StringBuffer> pauseLines;
+
+ /** The loging lines. */
+ private ArrayList<StringBuffer> logingLines;
+
+ /** The simulator canvas. */
+ private VSSimulatorVisualization simulatorVisualization;
+
+ /** The loging messages are filtered. */
+ private boolean isFiltered;
+
+ /** The loging is paused. */
+ private boolean isPaused;
+
+ /** The filter pattern. */
+ private Pattern filterPattern;
+
+ /**
+ * Instantiates a new VSLogging object.
+ */
+ public VSLogging() {
+ logingArea = new JTextArea(0, 0);
+ logingArea.setEditable(false);
+ logingArea.setLineWrap(true);
+ logingArea.setWrapStyleWord(true);
+ logingLines = new ArrayList<StringBuffer>();
+ pauseLines = new ArrayList<StringBuffer>();
+ filterText = "";
+ }
+
+ /**
+ * Sets the simulator canvas.
+ *
+ * @param sv the simulator canvas
+ */
+ public void setSimulatorCanvas(VSSimulatorVisualization sv) {
+ this.simulatorVisualization = sv;
+ }
+
+ /**
+ * Gets the loging area.
+ *
+ * @return the loging area
+ */
+ public JTextArea getLoggingArea() {
+ return logingArea;
+ }
+
+ /**
+ * Loggs a message using the global time.
+ *
+ * @param message the message
+ */
+ public void log(String message) {
+ if (simulatorVisualization == null)
+ log(message, 0);
+ else
+ log(message, simulatorVisualization.getTime());
+ }
+
+ /**
+ * Loggs a message using the specified time.
+ *
+ * @param message the message
+ * @param time the time
+ */
+ public synchronized void log(String message, long time) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(VSTools.getTimeString(time));
+ buffer.append(": ");
+ buffer.append(message);
+
+ if (isPaused)
+ pauseLines.add(buffer);
+ else
+ logFiltered(buffer);
+ }
+
+ /**
+ * Sets if the loging is paused.
+ *
+ * @param isPaused true, if the loging is paused
+ */
+ public synchronized void isPaused(boolean isPaused) {
+ this.isPaused = isPaused;
+
+ if (!isPaused) {
+ for (StringBuffer buffer : pauseLines)
+ logFiltered(buffer);
+
+ pauseLines.clear();
+ }
+ }
+
+ /**
+ * If the loging is filtered, it's using the pattern matching.
+ *
+ * @param buffer the loging buffer to filter
+ */
+ private void logFiltered(StringBuffer buffer) {
+ logingLines.add(buffer);
+ if (!isFiltered) {
+ logingArea.append(buffer.toString()+"\n");
+ logingArea.setCaretPosition(
+ logingArea.getDocument().getLength());
+
+ } else if (filterPattern != null &&
+ filterPattern.matcher(buffer).find()) {
+ logingArea.append(buffer.toString()+"\n");
+ logingArea.setCaretPosition(
+ logingArea.getDocument().getLength());
+ }
+ }
+
+ /**
+ * Checks if the loging is filtered.
+ *
+ * @param isFiltered true, if the loging is filtered
+ */
+ public synchronized void isFiltered(boolean isFiltered) {
+ this.isFiltered = isFiltered;
+
+ if (!isFiltered)
+ setFilterText("");
+ else
+ filter();
+ }
+
+ /**
+ * Sets the filter text.
+ *
+ * @param filterText the new filter text
+ */
+ public synchronized void setFilterText(String filterText) {
+ this.filterText = filterText;
+ filter();
+ }
+
+ /**
+ * Clears the loging.
+ */
+ public synchronized void clear() {
+ logingLines.clear();
+ pauseLines.clear();
+ logingArea.setText("");
+ }
+
+ /**
+ * Filters the loging.
+ */
+ private void filter() {
+ try {
+ filterPattern = Pattern.compile(filterText);
+ StringBuffer buffer = new StringBuffer();
+
+ for (StringBuffer line : logingLines) {
+ if (isFiltered) {
+ Matcher matcher = filterPattern.matcher(line);
+ if (matcher.find()) {
+ buffer.append(line);
+ buffer.append("\n");
+ }
+ } else {
+ buffer.append(line);
+ buffer.append("\n");
+ }
+ }
+ logingArea.setText(buffer.toString());
+
+ } catch (Exception e) {
+ filterPattern = null;
+ logingArea.setText("");
+ }
+ }
+}
diff --git a/src/main/java/simulator/VSMain.java b/src/main/java/simulator/VSMain.java
new file mode 100644
index 0000000..34a21b7
--- /dev/null
+++ b/src/main/java/simulator/VSMain.java
@@ -0,0 +1,70 @@
+package simulator;
+
+import java.awt.Component;
+import java.util.Locale;
+
+import javax.swing.UIManager;
+
+import events.VSRegisteredEvents;
+import prefs.VSDefaultPrefs;
+import prefs.VSPrefs;
+
+/**
+ * The class VSMain. This class contains the static main method. The simulator
+ * starts here!
+ *
+ * @author Paul C. Buetow
+ */
+public class VSMain {
+ /** The global preferences */
+ public static VSPrefs prefs;
+
+ /**
+ * Instantiates a new VSMain object.
+ *
+ * @param prefs the prefs
+ */
+ public VSMain(VSPrefs prefs) {
+ init(prefs, null);
+ }
+
+ /**
+ * Instantiates a new VSMain object
+ *
+ * @param prefs the prefs
+ * @param relativeTo the component to open the window relative to
+ */
+ public VSMain(VSPrefs prefs, Component relativeTo) {
+ init(prefs, relativeTo);
+ }
+
+ /**
+ * Inits the VSMain object.
+ *
+ * @param prefs the prefs
+ * @param relativeTo the component to open the window relative to
+ */
+ private void init(VSPrefs prefs, Component relativeTo) {
+ //VSSimulatorFrame simulatorFrame =
+ VSMain.prefs = prefs;
+ new VSSimulatorFrame(prefs, relativeTo);
+ }
+
+ /**
+ * The main method.
+ *
+ * @param args the arguments
+ */
+ public static void main(String[] args) {
+ try {
+ UIManager.setLookAndFeel(
+ UIManager.getCrossPlatformLookAndFeelClassName());
+ } catch (Exception e) { }
+
+ Locale.setDefault(Locale.GERMAN);
+ javax.swing.JPopupMenu.setDefaultLightWeightPopupEnabled(false);
+ VSPrefs prefs = VSDefaultPrefs.init();
+ VSRegisteredEvents.init(prefs);
+ new VSMain(prefs);
+ }
+}
diff --git a/src/main/java/simulator/VSMenuItemStates.java b/src/main/java/simulator/VSMenuItemStates.java
new file mode 100644
index 0000000..941dbf5
--- /dev/null
+++ b/src/main/java/simulator/VSMenuItemStates.java
@@ -0,0 +1,109 @@
+package simulator;
+
+/**
+ * The class VSMenuItemStates. Used by the VSSimulator to update the
+ * "simulator" bar of the VSSimulatorFrame.
+ *
+ * @author Paul C. Buetow
+ */
+public class VSMenuItemStates {
+ /** The pause state. */
+ private volatile boolean pause;
+
+ /** The replay state. */
+ private volatile boolean replay;
+
+ /** The reset state. */
+ private volatile boolean reset;
+
+ /** The start state. */
+ private volatile boolean start;
+
+ /**
+ * Instantiates a new VSMenuItemStates object.
+ *
+ * @param pause the pause state
+ * @param replay the replay state
+ * @param reset the reset state
+ * @param start the start state
+ */
+ public VSMenuItemStates(boolean pause, boolean replay, boolean reset,
+ boolean start) {
+ this.pause = pause;
+ this.replay = replay;
+ this.reset = reset;
+ this.start = start;
+ }
+
+ /**
+ * Sets the pause state.
+ *
+ * @param pause the new pause state
+ */
+ public void setPause(boolean pause) {
+ this.pause = pause;
+ }
+
+ /**
+ * Sets the replay state.
+ *
+ * @param replay the new replay state
+ */
+ public void setReplay(boolean replay) {
+ this.replay = replay;
+ }
+
+ /**
+ * Sets the reset state.
+ *
+ * @param reset the new reset state
+ */
+ public void setReset(boolean reset) {
+ this.reset = reset;
+ }
+
+ /**
+ * Sets the start state.
+ *
+ * @param start the new start state
+ */
+ public void setStart(boolean start) {
+ this.start = start;
+ }
+
+ /**
+ * Gets the pause state.
+ *
+ * @return the pause state
+ */
+ public boolean getPause() {
+ return pause;
+ }
+
+ /**
+ * Gets the replay state.
+ *
+ * @return the replay state
+ */
+ public boolean getReplay() {
+ return replay;
+ }
+
+ /**
+ * Gets the reset state.
+ *
+ * @return the reset state
+ */
+ public boolean getReset() {
+ return reset;
+ }
+
+ /**
+ * Gets the start state.
+ *
+ * @return the start state
+ */
+ public boolean getStart() {
+ return start;
+ }
+}
diff --git a/src/main/java/simulator/VSSimulator.java b/src/main/java/simulator/VSSimulator.java
new file mode 100644
index 0000000..4965a71
--- /dev/null
+++ b/src/main/java/simulator/VSSimulator.java
@@ -0,0 +1,1536 @@
+package simulator;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GridBagLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Vector;
+
+import javax.swing.AbstractButton;
+import javax.swing.AbstractCellEditor;
+import javax.swing.BoxLayout;
+import javax.swing.ButtonModel;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingUtilities;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableColumn;
+
+import core.VSInternalProcess;
+import core.VSTask;
+import core.VSTaskManager;
+import events.VSRegisteredEvents;
+import exceptions.VSNegativeNumberException;
+import prefs.VSPrefs;
+import prefs.editors.VSProcessEditor;
+import serialize.VSSerializable;
+import serialize.VSSerialize;
+
+/**
+ * The class VSSimulator, an object of this class represents a whole simulator.
+ * It may be, that several parallel simulators exist. They are independent
+ * fron each other.
+ *
+ * @author Paul C. Buetow
+ */
+public class VSSimulator extends JPanel implements VSSerializable {
+ /** The serial version uid */
+ private static final long serialVersionUID = 1L;
+
+ /** The global text fields. */
+ private ArrayList<String> globalTextFields;
+
+ /** The local text fields. */
+ private ArrayList<String> localTextFields;
+
+ /** The create tasks array list. */
+ private ArrayList<VSCreateTask> createTasks;
+
+ /** The filter active check box. */
+ private JCheckBox filterActiveCheckBox;
+
+ /** The lamport active check box. */
+ private JCheckBox lamportActiveCheckBox;
+
+ /** The vector time active check box. */
+ private JCheckBox vectorTimeActiveCheckBox;
+
+ /** The global pid combo box. */
+ private JComboBox<String> globalPIDComboBox;
+
+ /** The local pid combo box. */
+ private JComboBox<String> localPIDComboBox;
+
+ /** The processes combo box. */
+ private JComboBox<String> processesComboBox;
+
+ /** The local add panel. */
+ private JPanel localAddPanel;
+
+ /** The local panel. */
+ private JPanel localPanel;
+
+ /** The loging panel. */
+ private JPanel logingPanel;
+
+ /** The split pane1. */
+ private JSplitPane splitPane1;
+
+ /** The split pane h. */
+ private JSplitPane splitPaneH;
+
+ /** The split pane v. */
+ private JSplitPane splitPaneV;
+
+ /** The tabbed pane. */
+ private JTabbedPane tabbedPane;
+
+ /** The loging area. */
+ private JTextArea logingArea;
+
+ /** The filter text field. */
+ private JTextField filterTextField;
+
+ /** The global text field. */
+ private JTextField globalTextField;
+
+ /** The local text field. */
+ private JTextField localTextField;
+
+ /** The thread. */
+ private Thread thread;
+
+ /** The loging. */
+ private VSLogging loging;
+
+ /** The menu item states. */
+ private VSMenuItemStates menuItemStates;
+
+ /** The prefs. */
+ private VSPrefs prefs;
+
+ /** The simulator canvas. */
+ private VSSimulatorVisualization simulatorVisualization;
+
+ /** The simulator frame. */
+ private VSSimulatorFrame simulatorFrame;
+
+ /** The task manager. */
+ private VSTaskManager taskManager;
+
+ /** The task manager global model. */
+ private VSTaskManagerTableModel taskManagerGlobalModel;
+
+ /** The task manager local model. */
+ private VSTaskManagerTableModel taskManagerLocalModel;
+
+ /** The task manager global editor. */
+ private VSTaskManagerCellEditor taskManagerGlobalEditor;
+
+ /** The task manager local editor. */
+ private VSTaskManagerCellEditor taskManagerLocalEditor;
+
+ /** The last selected process num. */
+ private int lastSelectedProcessNum;
+
+ /** The last expert state. */
+ private boolean lastExpertState;
+
+ /** The simulator counter. */
+ private static int simulatorCounter;
+
+ /** The simulator num. */
+ private static volatile int simulatorNum;
+
+ /**
+ * The class VSTaskManagerTableModel, an object of this class handles
+ * the task manager's JTable.
+ */
+ private class VSTaskManagerTableModel extends AbstractTableModel
+ implements MouseListener {
+ /** the serial version uid */
+ private static final long serialVersionUID = 1l;
+
+ /** The Constant LOCAL. */
+ public static final boolean LOCAL = true;
+
+ /** The Constant GLOBAL. */
+ public static final boolean GLOBAL = false;
+
+ /** The Constant ALL_PROCESSES. */
+ // public static final boolean ALL_PROCESSES = true;
+
+ /** The Constant ONE_PROCESS. */
+ public static final boolean ONE_PROCESS = false;
+
+ /** The tasks. */
+ private ArrayList<VSTask> tasks;
+
+ /** The column names. */
+ private String columnNames[];
+
+ /** The num columns. */
+ private int numColumns;
+
+ /** The table. */
+ //private JTable table;
+
+ /** The editor. */
+ //private VSTaskManagerCellEditor editor;
+
+ /**
+ * Instantiates a new VSTaskManagerTableModel object
+ *
+ * @param process the process
+ * @param localTask true, if this table manages the local task. false,
+ * if this table manages the global tasks.
+ */
+ public VSTaskManagerTableModel(VSInternalProcess process,
+ boolean localTask) {
+ tasks = new ArrayList<VSTask>();
+ set(process, localTask, ONE_PROCESS);
+ columnNames = new String[3];
+ columnNames[0]= prefs.getString("lang.time") + " (ms)";
+ columnNames[1] = prefs.getString("lang.process.id");
+ columnNames[2] = prefs.getString("lang.event");
+ numColumns = 3;
+ }
+
+ /**
+ * Sets the table.
+ *
+ * @param table the table
+ */
+ public void setTable(JTable table) {
+ /* Maybe needed for future usage */
+ //this.table = table;
+ }
+
+ /**
+ * Sets the editor.
+ *
+ * @param editor the editor
+ */
+ public void setEditor(VSTaskManagerCellEditor editor) {
+ /* Maybe needed for future usage */
+ //this.editor = editor;
+ }
+
+ /**
+ * Sets new values.
+ *
+ * @param process the process
+ * @param localTasks true, if this table manages the local tasks. false
+ * if this table manages the global tasks.
+ * @param allProcesses true, if this table shows tasks of all processes.
+ * false, if this table only shows tasks of the specified process.
+ */
+ public void set(VSInternalProcess process, boolean localTasks,
+ boolean allProcesses) {
+
+ if (allProcesses) {
+ this.tasks = localTasks
+ ? taskManager.getLocalTasks()
+ : taskManager.getGlobalTasks();
+ } else {
+ this.tasks = localTasks
+ ? taskManager.getProcessLocalTasks(process)
+ : taskManager.getProcessGlobalTasks(process);
+ }
+
+ Collections.sort(tasks);
+ fireTableDataChanged();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.AbstractTableModel#getColumnName(int)
+ */
+ public String getColumnName(int col) {
+ return columnNames[col];
+ }
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.TableModel#getRowCount()
+ */
+ public int getRowCount() {
+ return tasks == null ? 0 : tasks.size();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.TableModel#getColumnCount()
+ */
+ public int getColumnCount() {
+ return numColumns;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.TableModel#getValueAt(int, int)
+ */
+ public Object getValueAt(int row, int col) {
+ VSTask task = tasks.get(row);
+
+ switch (col) {
+ case 0:
+ return task.getTaskTime();
+ case 1:
+ return task.getProcess().getProcessID();
+ }
+
+ return task.getEvent().getShortname();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.AbstractTableModel#isCellEditable(int, int)
+ */
+ public boolean isCellEditable(int row, int col) {
+ if (col == 2)
+ return false;
+
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.AbstractTableModel#setValueAt(
+ * java.lang.Object, int, int)
+ */
+ public void setValueAt(Object value, int row, int col) {
+ }
+
+ /**
+ * Adds the task.
+ *
+ * @param task the task
+ */
+ public void addTask(VSTask task) {
+ tasks.add(task);
+ Collections.sort(tasks);
+ fireTableDataChanged();
+ }
+
+ /**
+ * Removes the task at a specified row.
+ *
+ * @param row the row
+ * @return The removed task
+ */
+ public VSTask removeTaskAtRow(int row) {
+ VSTask task = tasks.get(row);
+ tasks.remove(task);
+ taskManager.removeTask(task);
+ fireTableDataChanged();
+ return task;
+ }
+
+ /**
+ * Checks if a specific row exists
+ *
+ * @param row the row
+ * @return True, if the row exists. False, if not
+ */
+ public boolean rowExists(int row) {
+ if (row < 0)
+ return false;
+
+ if (tasks.size() <= row)
+ return false;
+
+ return true;
+ }
+
+ /**
+ * Gets the index of a specific task
+ *
+ * @param task The task
+ * @return The index of the task
+ */
+ public int getIndexOf(VSTask task) {
+ return tasks.indexOf(task);
+ }
+
+ /**
+ * Copies the tasks at a specified rows.
+ *
+ * @param rows the rows
+ */
+ private void copyTasksAtRows(int rows[]) {
+ ArrayList<VSTask> copiedTasks = new ArrayList<VSTask>();
+
+ for (int row : rows)
+ /* Use the copy constructor */
+ copiedTasks.add(new VSTask(tasks.get(row)));
+
+ for (VSTask task : copiedTasks) {
+ taskManager.addTask(task, VSTaskManager.PROGRAMMED);
+ addTask(task);
+ }
+
+ fireTableDataChanged();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.MouseListener#mouseClicked(
+ * java.awt.event.MouseEvent)
+ */
+ public void mouseClicked(MouseEvent me) {
+ final JTable source = (JTable) me.getSource();
+ //final int row = source.rowAtPoint(me.getPoint());
+ //final int col = source.columnAtPoint(me.getPoint());
+
+ if (SwingUtilities.isRightMouseButton(me)) {
+ ActionListener actionListener = new ActionListener() {
+ public void actionPerformed(ActionEvent ae) {
+ String command = ae.getActionCommand();
+ int rows[] = source.getSelectedRows();
+
+ if (command.equals(prefs.getString("lang.remove"))) {
+ for (int i = rows.length - 1; i >= 0; --i)
+ removeTaskAtRow(rows[i]);
+
+ } else if (command.equals(
+ prefs.getString("lang.copy"))) {
+ copyTasksAtRows(rows);
+ }
+ }
+ };
+
+ JPopupMenu popup = new JPopupMenu();
+ JMenuItem item = new JMenuItem(prefs.getString("lang.remove"));
+ item.addActionListener(actionListener);
+ popup.add(item);
+
+ item = new JMenuItem(prefs.getString("lang.copy"));
+ item.addActionListener(actionListener);
+ popup.add(item);
+
+ popup.show(me.getComponent(), me.getX(), me.getY());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.MouseListener#mouseEntered(
+ * java.awt.event.MouseEvent)
+ */
+ public void mouseEntered(MouseEvent me) { }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.MouseListener#mouseExited(
+ * java.awt.event.MouseEvent)
+ */
+ public void mouseExited(MouseEvent me) { }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.MouseListener#mousePressed(
+ * java.awt.event.MouseEvent)
+ */
+ public void mousePressed(MouseEvent me) { }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.MouseListener#mouseReleased(
+ * java.awt.event.MouseEvent)
+ */
+ public void mouseReleased(MouseEvent me) { }
+ }
+
+ /**
+ * The class VSTaskManagerCellEditor, an object of this class handles
+ * the task manager's JTable editor
+ */
+ private class VSTaskManagerCellEditor extends AbstractCellEditor
+ implements TableCellEditor {
+ /** the serial version uid */
+ private static final long serialVersionUID = 1L;
+
+ /** The JTable model */
+ private VSTaskManagerTableModel model;
+
+ /**
+ * Instantiates a new VSTaskManagerCellEditor object.
+ *
+ * @param model the model
+ */
+ public VSTaskManagerCellEditor(VSTaskManagerTableModel model) {
+ this.model = model;
+ model.setEditor(this);
+ }
+
+ /**
+ * Stops editing
+ */
+ public void stopEditing() {
+ fireEditingStopped();
+ }
+
+ /**
+ /* (non-Javadoc)
+ * @see javax.swing.table.TableCellEditor#getTableCellEditorComponent(
+ * javax.swing.JTable, java.lang.Object, boolean, int, int)
+ */
+ public Component getTableCellEditorComponent(final JTable table,
+ Object object,
+ boolean isSelected,
+ final int row,
+ final int col) {
+ switch (col) {
+ case 0:
+ Long val = (Long) model.getValueAt(row, col);
+ final JTextField valField = new JTextField(val.toString());
+ valField.setBackground(Color.WHITE);
+ valField.setBorder(null);
+ valField.addActionListener(new ActionListener() {
+ private boolean isRed = false;
+ public void actionPerformed(ActionEvent ae) {
+ try {
+ Long val = Long.valueOf(valField.getText());
+ if (val.longValue() < 0)
+ throw new VSNegativeNumberException();
+ VSTask task = mo