package tmcsim.cadsimulator.viewer;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import tmcsim.common.CADEnums.PARAMICS_STATUS;
import tmcsim.common.CADEnums.SCRIPT_STATUS;
/**
* SimulationStatusPanel is a GUI object used for displaying information
* for the current simulation. This information includes:
*
*
* - Current simulation time.
* - Current simulation status.
* - Number of remote CAD Clients connected.
* - Status of Simulation Manager connection.
* - Status of Paramics connection.
* - Paramics Network Loaded
* - Information log messages.
* - Error log messages
*
*
* @author Matthew Cechini
* @version
*/
@SuppressWarnings("serial")
public class SimulationStatusPanel extends JPanel {
/**
* Logging Handler to listen for Information and Error
* messages logged for the CAD Simulator. Received LogRecords
* are displayed in the info or error message Text Area.
*
* @author Matthew Cechini
*/
private class SimulatorErrorHandler extends Handler {
public void close() throws SecurityException { }
public void flush() { }
public void publish(LogRecord rec) {
StringBuffer msgBuffer = new StringBuffer();
msgBuffer.append(rec.getSourceClassName() + "." +
rec.getSourceMethodName() + " = " +
rec.getMessage());
if(rec.getLevel() == Level.INFO)
infoMessagesTA.setText(infoMessagesTA.getText() +
msgBuffer.toString() + "\n");
else
errorMessagesTA.setText(errorMessagesTA.getText() +
msgBuffer.toString() + "\n");
}
}
/** Count of how many CAD clients have connected. */
private int numClientsConnected = 0;
/** Logging ErrorHandler. */
private SimulatorErrorHandler errorHandler;
/**
* Constructor. Initialize GUI Objects. Register the logging handler
* to listen for log records from all loggers that exist in the
* "tmcsim.cadsimulator" package structure.
*/
public SimulationStatusPanel() {
initTimeAndStatus();
initAdditionalInfo();
initMessagesPanes();
errorHandler = new SimulatorErrorHandler();
Logger.getLogger("tmcsim.cadsimulator").addHandler(errorHandler);
CADSimulatorViewerBox = Box.createVerticalBox();
CADSimulatorViewerBox.add(simulationTimeAndStatusBox);
CADSimulatorViewerBox.add(additionalInfoBox);
CADSimulatorViewerBox.add(infoMessagesPane);
CADSimulatorViewerBox.add(errorMessagesPane);
add(CADSimulatorViewerBox);
}
/**
* Method is called when a CAD Client disconnects from the CAD Simulator.
* The displayed number of connected clients is incremented by one.
*/
public void connectClient() {
numClientsConnected++;
termConnectedTF.setText(String.valueOf(numClientsConnected));
}
/**
* Method is called when a CAD Client disconnects from the CAD Simulator.
* The displayed number of connected clients is decremented by one.
*/
public void disconnectClient() {
if(numClientsConnected > 0)
numClientsConnected--;
termConnectedTF.setText(String.valueOf(numClientsConnected));
}
/**
* Method is called when Simulation Manager connects or disconnects.
*
* @param connection True if simulation manager is connected, false if not.
*/
public void setSimManagerStatus(boolean connection) {
if(connection)
managerConnectedTF.setText("Yes");
else
managerConnectedTF.setText("No");
}
/**
* Method called to convert current simulation time (parameter long value) to
* a string of format H:MM:SS. Time is then updated on GUI.
*
* @param seconds Long value of current time
*/
public void setTime(long seconds) {
String time = new String();
long timeSegment;
timeSegment = seconds / 3600;
time += String.valueOf(timeSegment) + ":";
seconds = seconds % 3600;
timeSegment = seconds / 60;
if(timeSegment < 10)
time += "0";
time += String.valueOf(timeSegment) + ":";
seconds = seconds % 60;
timeSegment = seconds;
if(timeSegment < 10)
time += "0";
time += String.valueOf(timeSegment);
simulationClockLabel.setText(time);
}
/**
* This method is called within the CADSimulator whenever an error occurs. The message
* is then displayed to the user in the "Error Messages" portion of the CAD Simulator Viewer.
* Invoke method with null parameter to clear messages.
*
* @param errorMessage String message that will be displayed
*/
protected void displayError(String errorMessage) {
if(errorMessage == null)
errorMessagesTA.setText("");
else
errorMessagesTA.append(errorMessage + "\n");
}
/**
* Method is called to display the current status of the simulation.
*
* @param newStatus Current status of simulation. The following table describes
* each possible status and what is displayed. Each status code is found
* as a public static int in the Coordinator Class.
*
*
*
*
* Status
|
* Actions Taken
|
*
*
* NO_SCRIPT
|
* Set the simulation status text to a black "No Script".
|
*
*
* SCRIPT_STOPPED_NOT_STARTED
|
* Set the simulation status text to a red "Ready".
|
*
*
* SCRIPT_PAUSED_STARTED
|
* Set the simulation status text to a red "Paused".
|
*
*
* SCRIPT_RUNNING
|
* Set the simulation status text to a green "Running".
|
*
*
* ATMS_SYNCHRONIZATION
|
* Set the simulation status text to an orange "Synchronizing".
|
*
*
*
*/
public void setScriptStatus(SCRIPT_STATUS newStatus) {
switch(newStatus) {
case NO_SCRIPT:
simulationStatusText.setText("No Script");
simulationStatusText.setForeground(Color.BLACK);
break;
case SCRIPT_STOPPED_NOT_STARTED:
simulationStatusText.setText("Ready");
simulationStatusText.setForeground(Color.RED);
break;
case SCRIPT_PAUSED_STARTED:
simulationStatusText.setText("Paused");
simulationStatusText.setForeground(Color.RED);
break;
case SCRIPT_RUNNING:
simulationStatusText.setText("Running");
simulationStatusText.setForeground(Color.GREEN);
break;
case ATMS_SYNCHRONIZATION:
simulationStatusText.setText("Synchronizing");
simulationStatusText.setForeground(Color.ORANGE);
break;
}
}
/**
* Method is called when a connection to paramics is made or dropped.
*
* @param newStatus The status denoting whether a connection has been
* made or dropped.
*/
public void setParamicsStatus(PARAMICS_STATUS newStatus) {
switch(newStatus) {
case CONNECTED:
paramicsConnectedTF.setText("Yes");
break;
case DISCONNECTED:
paramicsConnectedTF.setText("No");
break;
}
}
/**
* Method is called when a paramics network is loaded.
*
* @param networkID Unique ID for Paramics network that has been loaded.
*/
public void setParamicsNetworkLoaded(String networkID) {
networkLoadedTF.setText(networkID);
}
/** Initialize Time and Status GUI Components */
private void initTimeAndStatus() {
simulationTime = new JPanel();
simulationClock = new JPanel();
simulationStatus = new JLabel("Simulation Status");
simulationStatusText = new JLabel("No Script");
simulationTime.setLayout(new BorderLayout());
simulationClock.setPreferredSize(new Dimension(100, 60));
simulationTimeAndStatusBox = new Box(BoxLayout.X_AXIS);
simulationStatusBox = new Box(BoxLayout.Y_AXIS);
simulationTimeBox = new Box(BoxLayout.Y_AXIS);
simulationClockBox = new Box(BoxLayout.X_AXIS);
simulationStatus.setAlignmentX(Box.CENTER_ALIGNMENT);
simulationStatusText.setAlignmentX(Box.CENTER_ALIGNMENT);
simulationStatusText.setName("simulationStatusText");
TitledBorder title = BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), "Status");
title.setTitleJustification(TitledBorder.LEFT);
simulationStatusBox.setBorder(title);
simulationStatusBox.setMaximumSize(new Dimension(140, 60));
simulationStatusBox.setAlignmentX(Box.CENTER_ALIGNMENT);
simulationStatusBox.add(Box.createHorizontalStrut(120));
simulationStatusBox.add(Box.createVerticalGlue());
simulationStatusBox.add(simulationStatusText);
simulationStatusBox.add(Box.createVerticalGlue());
simulationClockLabel = new JLabel("0:00:00");
simulationClockLabel.setFont(new Font("Geneva", Font.BOLD, 70));
simulationClockLabel.setForeground(Color.BLACK);
simulationClockLabel.setBackground(Color.BLACK);
simulationClockBox.setForeground(Color.BLACK);
simulationClockBox.setBackground(Color.BLACK);
simulationClockBox.add(simulationClockLabel);
simulationClockBox.setAlignmentX(Box.CENTER_ALIGNMENT);
simulationTimeBox.add(simulationClockBox);
simulationTimeAndStatusBox.add(Box.createHorizontalStrut(20));
simulationTimeAndStatusBox.add(simulationTimeBox);
simulationTimeAndStatusBox.add(Box.createHorizontalStrut(20));
simulationTimeAndStatusBox.add(simulationStatusBox);
simulationTimeAndStatusBox.add(Box.createHorizontalStrut(20));
}
/** Initialize Additional Info Label GUI Components */
private void initAdditionalInfo() {
terminalsConnectedLabel = new JLabel("Connected CAD Terminals: ");
termConnectedTF = new JTextField(" " + String.valueOf(numClientsConnected));
termConnectedTF.setEditable(false);
termConnectedTF.setName("termConnectedTF");
termConnectedBox = new Box(BoxLayout.X_AXIS);
termConnectedBox.add(terminalsConnectedLabel);
termConnectedBox.add(Box.createHorizontalGlue());
termConnectedBox.add(termConnectedTF);
managerConnectedLabel = new JLabel("Simulation Manager Connected: ");
managerConnectedTF = new JTextField(" No");
managerConnectedTF.setEditable(false);
managerConnectedTF.setName("managerConnectedTF");
managerConnectedBox = new Box(BoxLayout.X_AXIS);
managerConnectedBox.add(managerConnectedLabel);
managerConnectedBox.add(Box.createHorizontalGlue());
managerConnectedBox.add(managerConnectedTF);
paramicsConnectedLabel = new JLabel("Connected to Paramics: ");
paramicsConnectedTF = new JTextField(" No");
paramicsConnectedTF.setEditable(false);
paramicsConnectedBox = new Box(BoxLayout.X_AXIS);
paramicsConnectedBox.add(paramicsConnectedLabel);
paramicsConnectedBox.add(Box.createHorizontalGlue());
paramicsConnectedBox.add(paramicsConnectedTF);
networkLoadedLabel = new JLabel("Network Loaded: ");
networkLoadedTF = new JTextField("None");
networkLoadedTF.setEditable(false);
networkLoadedBox = new Box(BoxLayout.X_AXIS);
networkLoadedBox.add(networkLoadedLabel);
networkLoadedBox.add(Box.createHorizontalGlue());
networkLoadedBox.add(networkLoadedTF);
additionalInfoBox = new Box(BoxLayout.Y_AXIS);
additionalInfoBox.setMinimumSize(new Dimension(300, 150));
additionalInfoBox.add(Box.createVerticalStrut(10));
additionalInfoBox.add(termConnectedBox);
additionalInfoBox.add(Box.createVerticalStrut(10));
additionalInfoBox.add(managerConnectedBox);
additionalInfoBox.add(Box.createVerticalStrut(10));
additionalInfoBox.add(paramicsConnectedBox);
additionalInfoBox.add(Box.createVerticalStrut(10));
additionalInfoBox.add(networkLoadedBox);
additionalInfoBox.add(Box.createVerticalStrut(20));
}
/** Initialize Info & Error Messages GUI Components */
private void initMessagesPanes() {
infoMessagesTA = new JTextArea(6, 30);
infoMessagesTA.setEditable(false);
infoMessagesPane = new JScrollPane(errorMessagesTA);
infoMessagesPane.setPreferredSize(new Dimension(300, 100));
infoMessagesPane.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), "Info Messages"));
errorMessagesTA = new JTextArea(6, 30);
errorMessagesTA.setForeground(Color.RED);
errorMessagesTA.setEditable(false);
errorMessagesPane = new JScrollPane(errorMessagesTA);
errorMessagesPane.setPreferredSize(new Dimension(300, 150));
errorMessagesPane.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), "Error Messages"));
}
private Box additionalInfoBox;
private Box termConnectedBox;
private Box managerConnectedBox;
private Box paramicsConnectedBox;
private Box networkLoadedBox;
private Box CADSimulatorViewerBox;
private Box simulationTimeAndStatusBox;
private Box simulationStatusBox;
private Box simulationTimeBox;
private Box simulationClockBox;
private JLabel managerConnectedLabel;
private JLabel paramicsConnectedLabel;
private JLabel simulationStatus;
private JLabel simulationClockLabel;
private JLabel simulationStatusText;
private JLabel terminalsConnectedLabel;
private JLabel networkLoadedLabel;
private JPanel simulationTime;
private JPanel simulationClock;
private JTextField managerConnectedTF;
private JTextField paramicsConnectedTF;
private JTextField termConnectedTF;
private JTextField networkLoadedTF;
private JScrollPane infoMessagesPane;
private JScrollPane errorMessagesPane;
private JTextArea infoMessagesTA;
private JTextArea errorMessagesTA;
}