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: * * * * @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; }