Author: [log in to unmask]
Date: Mon Mar 2 18:43:16 2015
New Revision: 2228
Log:
Forgot these in last commit. HPSJAVA-442
Added:
java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/LogTable.java
java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MenuBar.java
java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringActionListener.java
java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringApplication.java
java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java
java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java
java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/PlotPanel.java
java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SessionState.java
java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SystemStatusTable.java
java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/util/EtSystemUtil.java
Added: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/LogTable.java
=============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/LogTable.java (added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/LogTable.java Mon Mar 2 18:43:16 2015
@@ -0,0 +1,37 @@
+package org.hps.monitoring.application;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.logging.LogRecord;
+
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableModel;
+
+/**
+ * This is a simple Swing component to model the log table.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class LogTable extends JTable {
+
+ private DefaultTableModel model;
+ static final String[] logTableColumns = { "Date", "Level", "Message" };
+
+ private final SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM-dd-yyyy HH:mm:ss.SSS");
+
+ LogTable() {
+ String data[][] = new String[0][0];
+ model = new DefaultTableModel(data, logTableColumns);
+ this.setModel(model);
+ setEnabled(false);
+ setAutoCreateRowSorter(true);
+ }
+
+ void clear() {
+ model.setRowCount(0);
+ }
+
+ void insert(LogRecord record) {
+ Object[] row = new Object[] { dateFormat.format(new Date(record.getMillis())), record.getLevel(), record.getMessage() };
+ model.insertRow(getRowCount(), row);
+ }
+}
Added: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MenuBar.java
=============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MenuBar.java (added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MenuBar.java Mon Mar 2 18:43:16 2015
@@ -0,0 +1,148 @@
+package org.hps.monitoring.application;
+
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+
+import static org.hps.monitoring.application.Commands.*;
+
+public class MenuBar extends JMenuBar {
+
+ private JMenuItem savePlotsItem;
+ private JMenuItem logItem;
+ private JMenuItem terminalItem;
+ private JMenuItem saveLayoutItem;
+
+ MenuBar(ActionListener listener) {
+
+ JMenu applicationMenu = new JMenu("Application");
+ applicationMenu.setMnemonic(KeyEvent.VK_A);
+ add(applicationMenu);
+
+ JMenuItem loadConfigItem = new JMenuItem("Load Settings ...");
+ //loadConfigItem.addActionListener(listener);
+ loadConfigItem.setMnemonic(KeyEvent.VK_C);
+ loadConfigItem.setActionCommand(SELECT_CONFIG_FILE);
+ loadConfigItem.setToolTipText("Load application settings from a properties file");
+ applicationMenu.add(loadConfigItem);
+
+ JMenuItem saveConfigItem = new JMenuItem("Save Settings ...");
+ //saveConfigItem.addActionListener(listener);
+ saveConfigItem.setMnemonic(KeyEvent.VK_S);
+ saveConfigItem.setActionCommand(SAVE_CONFIG_FILE);
+ saveConfigItem.setToolTipText("Save settings to a properties file");
+ applicationMenu.add(saveConfigItem);
+
+ JMenuItem settingsItem = new JMenuItem("Show Settings ...");
+ settingsItem.setMnemonic(KeyEvent.VK_P);
+ settingsItem.setActionCommand(SHOW_SETTINGS);
+ //settingsItem.addActionListener(listener);
+ settingsItem.setToolTipText("Show application settings menu");
+ applicationMenu.add(settingsItem);
+
+ applicationMenu.addSeparator();
+
+ saveLayoutItem = new JCheckBoxMenuItem("Save GUI Layout");
+ saveLayoutItem.setActionCommand(SAVE_LAYOUT);
+ //saveLayoutItem.addActionListener(listener);
+ saveLayoutItem.setToolTipText("Include current GUI layout when saving settings.");
+ //if (configurationModel.hasPropertyKey(ConfigurationModel.SAVE_LAYOUT_PROPERTY)) {
+ // saveLayoutItem.setSelected(configurationModel.getSaveLayout());
+ //}
+ //saveLayoutItem.addPropertyChangeListener(this);
+
+ applicationMenu.add(saveLayoutItem);
+
+ JMenuItem restoreLayoutItem = new JMenuItem("Restore Default GUI Layout");
+ restoreLayoutItem.setActionCommand(RESTORE_DEFAULT_GUI_LAYOUT);
+ //restoreLayoutItem.addActionListener(listener);
+ restoreLayoutItem.setToolTipText("Restore the GUI windows to their default positions and sizes");
+ applicationMenu.add(restoreLayoutItem);
+
+ applicationMenu.addSeparator();
+
+ JMenuItem exitItem = new JMenuItem("Exit");
+ exitItem.setMnemonic(KeyEvent.VK_X);
+ exitItem.setActionCommand(EXIT);
+ //exitItem.addActionListener(listener);
+ exitItem.setToolTipText("Exit from the application");
+ applicationMenu.add(exitItem);
+
+ JMenu plotsMenu = new JMenu("Plots");
+ plotsMenu.setMnemonic(KeyEvent.VK_O);
+ add(plotsMenu);
+
+ JMenuItem aidaAutoSaveItem = new JMenuItem("Set AIDA Auto Save File ...");
+ aidaAutoSaveItem.setMnemonic(KeyEvent.VK_A);
+ aidaAutoSaveItem.setActionCommand(AIDA_AUTO_SAVE);
+ //aidaAutoSaveItem.addActionListener(listener);
+ aidaAutoSaveItem.setToolTipText("Select name of file to auto save AIDA plots at end of job.");
+ plotsMenu.add(aidaAutoSaveItem);
+
+ savePlotsItem = new JMenuItem("Save Plots to AIDA File...");
+ savePlotsItem.setMnemonic(KeyEvent.VK_P);
+ savePlotsItem.setActionCommand(SAVE_PLOTS);
+ //savePlotsItem.addActionListener(listener);
+ savePlotsItem.setEnabled(false);
+ savePlotsItem.setToolTipText("Save plots from default AIDA tree to an output file.");
+ plotsMenu.add(savePlotsItem);
+
+ JMenuItem resetPlotsItem = new JMenuItem("Reset Plots");
+ resetPlotsItem.setMnemonic(KeyEvent.VK_R);
+ resetPlotsItem.setActionCommand(RESET_PLOTS);
+ //resetPlotsItem.addActionListener(listener);
+ resetPlotsItem.setEnabled(true);
+ resetPlotsItem.setToolTipText("Reset all AIDA plots in the default tree.");
+ plotsMenu.add(resetPlotsItem);
+
+ JMenu logMenu = new JMenu("Log");
+ logMenu.setMnemonic(KeyEvent.VK_L);
+ add(logMenu);
+
+ logItem = new JMenuItem("Redirect to File ...");
+ logItem.setMnemonic(KeyEvent.VK_F);
+ logItem.setActionCommand(CHOOSE_LOG_FILE);
+ //logItem.addActionListener(this);
+ logItem.setEnabled(true);
+ logItem.setToolTipText("Redirect std out and err to a file.");
+ logMenu.add(logItem);
+
+ terminalItem = new JMenuItem("Redirect to Terminal");
+ terminalItem.setMnemonic(KeyEvent.VK_T);
+ terminalItem.setActionCommand(LOG_TO_TERMINAL);
+ //terminalItem.addActionListener(this);
+ terminalItem.setEnabled(false);
+ terminalItem.setToolTipText("Redirect std out and err back to the terminal.");
+ logMenu.add(terminalItem);
+
+ JMenuItem saveLogItem = new JMenuItem("Save Log Table to File ...");
+ saveLogItem.setMnemonic(KeyEvent.VK_S);
+ saveLogItem.setActionCommand(SAVE_LOG_TABLE);
+ //saveLogItem.addActionListener(this);
+ saveLogItem.setToolTipText("Save the log records to a tab delimited text file.");
+ logMenu.add(saveLogItem);
+
+ JMenuItem clearLogItem = new JMenuItem("Clear Log Table");
+ //clearLogItem.addActionListener(this);
+ clearLogItem.setMnemonic(KeyEvent.VK_C);
+ clearLogItem.setActionCommand(CLEAR_LOG_TABLE);
+ clearLogItem.setToolTipText("Clear the log table of all messages.");
+ logMenu.add(clearLogItem);
+
+ JMenu utilMenu = new JMenu("Util");
+ plotsMenu.setMnemonic(KeyEvent.VK_U);
+ add(utilMenu);
+
+ JMenuItem screenshotItem = new JMenuItem("Take a Screenshot ...");
+ screenshotItem.setMnemonic(KeyEvent.VK_N);
+ screenshotItem.setActionCommand(SCREENSHOT);
+ //screenshotItem.addActionListener(this);
+ screenshotItem.setToolTipText("Save a screenshot to file");
+ utilMenu.add(screenshotItem);
+ }
+
+}
Added: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringActionListener.java
=============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringActionListener.java (added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringActionListener.java Mon Mar 2 18:43:16 2015
@@ -0,0 +1,115 @@
+package org.hps.monitoring.application;
+
+import static org.hps.monitoring.application.Commands.*;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.logging.Logger;
+
+public class MonitoringActionListener implements ActionListener {
+
+ MonitoringApplication app;
+ Logger logger;
+
+ MonitoringActionListener(MonitoringApplication app) {
+ this.app = app;
+ this.logger = MonitoringApplication.logger;
+ }
+
+ /**
+ * The action handler method for the application.
+ * @param e The event to handle.
+ */
+ public void actionPerformed(ActionEvent e) {
+
+ // System.out.println("MonitoringApplication. actionPerformed: " + e.getActionCommand());
+
+ String cmd = e.getActionCommand();
+ if (CONNECT.equals(cmd)) {
+ // Run the start session method on a seperate thread.
+ new Thread() {
+ public void run() {
+ app.startSession();
+ }
+ }.start();
+ } else if (DISCONNECT.equals(cmd)) {
+ // Run the stop session method on a seperate thread.
+ new Thread() {
+ public void run() {
+ //stopSession();
+ }
+ }.start();
+ } else if (SAVE_PLOTS.equals(cmd)) {
+ //savePlots();
+ } else if (CHOOSE_LOG_FILE.equals(cmd)) {
+ //chooseLogFile();
+ } else if (LOG_TO_TERMINAL.equals(cmd)) {
+ //logToTerminal();
+ } else if (SCREENSHOT.equals(cmd)) {
+ //chooseScreenshot();
+ } else if (EXIT.equals(cmd)) {
+ //exit();
+ } else if (SAVE_LOG_TABLE.equals(cmd)) {
+ //saveLogTableToFile();
+ } else if (CLEAR_LOG_TABLE.equals(cmd)) {
+ //clearLogTable();
+ } else if (PAUSE.equals(cmd)) {
+ //pauseEventProcessing();
+ } else if (NEXT.equals(cmd)) {
+ //nextEvent();
+ } else if (RESUME.equals(cmd)) {
+ //resumeEventProcessing();
+ } else if (LOG_LEVEL_CHANGED.equals(cmd)) {
+ //setLogLevel();
+ } else if (AIDA_AUTO_SAVE.equals(cmd)) {
+ //getJobSettingsPanel().chooseAidaAutoSaveFile();
+ } else if (SHOW_SETTINGS.equals(cmd)) {
+ //showSettingsDialog();
+ } else if (SELECT_CONFIG_FILE.equals(cmd)) {
+ //chooseConfigurationFile();
+ } else if (SAVE_CONFIG_FILE.equals(cmd)) {
+ //updateLayoutConfiguration(); /* Save current GUI layout settings first, if needed. */
+ //saveConfigurationFile();
+ } else if (LOAD_DEFAULT_CONFIG_FILE.equals(cmd)) {
+ //loadDefaultConfigFile();
+ } else if (SAVE_LAYOUT.equals(cmd)) {
+ //setSaveLayout();
+ } else if (RESTORE_DEFAULT_GUI_LAYOUT.equals(cmd)) {
+ //restoreDefaultLayout();
+ } else if (VALIDATE_DATA_FILE.equals(cmd)) {
+ //if (fileValidationThread == null) {
+ // new FileValidationThread().start();
+ //}
+ } else if (RESET_PLOTS.equals(cmd)) {
+ //resetAidaTree();
+ }
+ }
+
+ private void disconnect() {
+ disconnect(ConnectionStatus.DISCONNECTING);
+ }
+
+ /**
+ * Disconnect from the current ET session with a particular status.
+ * @param status The connection status.
+ */
+ private void disconnect(ConnectionStatus status) {
+
+ logger.fine("Disconnecting the current session.");
+
+ // Cleanup the ET connection.
+ //cleanupEtConnection();
+
+ // Update state of GUI to disconnected.
+ //setDisconnectedGuiState();
+
+ // Finally, change application state to fully disconnected.
+ //setConnectionStatus(ConnectionStatus.DISCONNECTED);
+
+ // Set the application status from the caller if an error occurred.
+ //if (status == ConnectionStatus.ERROR)
+ // setConnectionStatus(status);
+
+ //log(Level.INFO, "Disconnected from the session.");
+ }
+}
Added: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringApplication.java
=============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringApplication.java (added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringApplication.java Mon Mar 2 18:43:16 2015
@@ -0,0 +1,435 @@
+package org.hps.monitoring.application;
+
+import java.awt.event.ActionEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.hps.conditions.database.DatabaseConditionsManager;
+import org.hps.job.JobManager;
+import org.hps.monitoring.application.RunPanel.RunModelUpdater;
+import org.hps.monitoring.application.model.Configuration;
+import org.hps.monitoring.application.model.ConfigurationModel;
+import org.hps.monitoring.application.model.RunModel;
+import org.hps.monitoring.application.util.ErrorHandler;
+import org.hps.monitoring.application.util.EtSystemUtil;
+import org.hps.monitoring.subsys.SystemStatusRegistry;
+import org.hps.monitoring.subsys.et.EtSystemMonitor;
+import org.hps.monitoring.subsys.et.EtSystemStripCharts;
+import org.hps.record.LCSimEventBuilder;
+import org.hps.record.composite.CompositeLoop;
+import org.hps.record.composite.CompositeLoopConfiguration;
+import org.hps.record.composite.EventProcessingThread;
+import org.hps.record.enums.DataSourceType;
+import org.hps.record.evio.EvioDetectorConditionsProcessor;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.conditions.ConditionsReader;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+public class MonitoringApplication implements PropertyChangeListener {
+
+ static Logger logger;
+ Handler logHandler;
+
+ ErrorHandler errorHandler;
+
+ MonitoringActionListener actions;
+ MonitoringApplicationFrame frame;
+ SettingsDialog settingsDialog = new SettingsDialog();
+
+ RunModel runModel = new RunModel();
+ ConfigurationModel configurationModel = new ConfigurationModel();
+
+ SessionState sessionState;
+
+ // The default configuration resource.
+ private static final String DEFAULT_CONFIG_RESOURCE = "/org/hps/monitoring/config/default_config.prop";
+
+ // The application's global Configuration settings.
+ private Configuration configuration;
+
+ class LogHandler extends Handler {
+
+ /**
+ * This method inserts a record into the log table.
+ */
+ public void publish(LogRecord record) {
+ frame.logTable.insert(record);
+ }
+
+ public void close() throws SecurityException {
+ }
+
+ public void flush() {
+ }
+ }
+
+ MonitoringApplication(Configuration configuration) {
+
+ // Setup the error handler.
+ this.errorHandler = new ErrorHandler(frame, logger);
+
+ // Set the configuration.
+ if (configuration != null) {
+ // User specified configuration.
+ this.configuration = configuration;
+ } else {
+ // Use the default configuration resource.
+ this.configuration = new Configuration(DEFAULT_CONFIG_RESOURCE);
+ }
+
+ // Setup the action listener.
+ actions = new MonitoringActionListener(this);
+
+ // Setup the main GUI component.
+ frame = new MonitoringApplicationFrame(actions);
+ frame.setRunModel(runModel);
+
+ // Setup the logger.
+ setupLogger();
+
+ // Setup the settings dialog box.
+ settingsDialog.addActionListener(actions);
+ settingsDialog.setConfigurationModel(configurationModel);
+
+ // Add this class as a listener on the configuration model.
+ configurationModel.addPropertyChangeListener(this);
+
+ // Load the configuration.
+ loadConfiguration();
+ }
+
+ private void setupLogger() {
+ logger = Logger.getLogger(MonitoringApplication.class.getSimpleName());
+ logHandler = new LogHandler();
+ logger.setUseParentHandlers(false);
+ logger.addHandler(logHandler);
+ logger.setLevel(Level.ALL);
+ }
+
+ public static MonitoringApplication create(Configuration configuration) {
+ return new MonitoringApplication(configuration);
+ }
+
+ public static MonitoringApplication create() {
+ return create(new Configuration(DEFAULT_CONFIG_RESOURCE));
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ // TODO Auto-generated method stub
+ }
+
+ void loadConfiguration() {
+
+ // Set the Configuration on the ConfigurationModel which will trigger all the PropertyChangelListeners.
+ configurationModel.setConfiguration(configuration);
+
+ // Log that a new configuration was loaded.
+ if (configuration.getFile() != null)
+ logger.config("Loaded configuration from file: " + configuration.getFile().getPath());
+ else
+ logger.config("Loaded configuration from resource: " + configuration.getResourcePath());
+ }
+
+ /**
+ * Start a new monitoring session. This method is executed in a separate thread from the EDT
+ * within {@link #actionPerformed(ActionEvent)} so GUI updates are not blocked while the session
+ * is being setup.
+ */
+ void startSession() {
+
+ logger.fine("Starting a new monitoring session.");
+
+ // Show a modal window that will block the GUI until connected or an error occurs.
+ //JDialog dialog = DialogUtil.showStatusDialog(this, "Info", "Starting new session ...");
+
+ try {
+
+ sessionState = new SessionState();
+
+ // Reset the plot panel and global AIDA state.
+ resetPlots();
+
+ // The system status registry is cleared here before any event processors
+ // which might create a SystemStatus are added to the event processing chain
+ // e.g. an LCSim Driver, etc.
+ SystemStatusRegistry.getSystemStatusRegistery().clear();
+
+ // Setup the LCSim JobControlManager and event builder.
+ setupLCSim();
+
+ // Connect to the ET system.
+ connect();
+
+ // Setup the EventProcessingChain object using the EtConnection.
+ setupCompositeLoop();
+
+ // Start the event processing thread.
+ startEventProcessingThread();
+
+ // Setup the system status monitor table.
+ //setupSystemStatusMonitor();
+
+ // Start thread which will trigger a disconnect if the event processing finishes.
+ //startSessionWatchdogThread();
+
+ logger.info("successfully started the monitoring session");
+
+ } catch (Exception e) {
+
+ logger.severe("error occurred while setting up the session");
+
+ // Log the error that occurred.
+ errorHandler.setError(e).log().printStackTrace();
+
+ // Disconnect from the session.
+ //disconnect(ConnectionStatus.ERROR);
+
+ } finally {
+ // Close modal window.
+ //dialog.dispatchEvent(new WindowEvent(dialog, WindowEvent.WINDOW_CLOSING));
+ }
+ }
+
+ /**
+ * Connect to the ET system using the current connection settings.
+ */
+ private void connect() throws IOException {
+
+ // Make sure applicable menu items are enabled or disabled.
+ // This applies whether or not using an ET server or file source.
+ //setConnectedGuiState();
+
+ // Setup the network connection if using an ET server.
+ if (usingEtServer()) {
+
+ setConnectionStatus(ConnectionStatus.CONNECTION_REQUESTED);
+
+ // Create a connection to the ET server.
+ try {
+ createEtConnection();
+ } catch (Exception e) {
+ throw new IOException(e);
+ }
+ } else {
+ // This is when a direct file source is used and ET is not needed.
+ setConnectionStatus(ConnectionStatus.CONNECTED);
+ }
+ }
+
+ boolean usingEtServer() {
+ return configurationModel.getDataSourceType().equals(DataSourceType.ET_SERVER);
+ }
+
+ /**
+ * Create a connection to an ET system using current parameters from the GUI. If successful, the
+ * application's ConnectionStatus is changed to CONNECTED.
+ */
+ private void createEtConnection() {
+
+ // Setup connection to ET system.
+ sessionState.connection = EtSystemUtil.createEtConnection(configurationModel);
+
+ if (sessionState.connection != null) {
+
+ // Set status to connected as there is now a live ET connection.
+ setConnectionStatus(ConnectionStatus.CONNECTED);
+
+ logger.info("successfully connected to ET system");
+
+ } else {
+ // Some error occurred and the connection was not created.
+ setConnectionStatus(ConnectionStatus.ERROR);
+
+ errorHandler.setError(new RuntimeException("Failed to create ET connection.")).log().printStackTrace().raiseException();
+ }
+ }
+
+ /**
+ * Set the connection status.
+ * @param status The connection status.
+ */
+ void setConnectionStatus(ConnectionStatus status) {
+ // FIXME
+ //frame.connectionStatusPanel.setConnectionStatus(status);
+ logger.info("connection status changed to: " + status.name());
+ logHandler.flush();
+ }
+
+ void resetPlots() {
+
+ // Clear the static AIDA tree in case plots are hanging around from previous sessions.
+ AIDA.defaultInstance().clearAll();
+
+ // Reset plots.
+ frame.plotPanel.reset();
+ }
+
+ /**
+ * Setup the LCSim job manager and the event builder.
+ */
+ void setupLCSim() {
+
+ logger.info("setting up LCSim");
+
+ // Get steering resource or file as a String parameter.
+ String steering = null;
+ SteeringType steeringType = configurationModel.getSteeringType();
+ if (steeringType.equals(SteeringType.FILE))
+ try {
+ steering = configurationModel.getSteeringFile().getCanonicalPath();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ else
+ steering = configurationModel.getSteeringResource();
+
+ logger.config("Set steering to " + steering + " with type " + (steeringType == SteeringType.RESOURCE ? "RESOURCE" : "FILE"));
+
+ try {
+ // Create and the job manager. The conditions manager is instantiated from this call but not configured.
+ sessionState.jobManager = new JobManager();
+
+ if (configurationModel.hasValidProperty(ConfigurationModel.DETECTOR_ALIAS_PROPERTY)) {
+ // Set a detector alias.
+ ConditionsReader.addAlias(configurationModel.getDetectorName(), "file://" + configurationModel.getDetectorAlias());
+ logger.config("using detector alias " + configurationModel.getDetectorAlias());
+ }
+
+ // Setup the event builder to translate from EVIO to LCIO.
+ // This must happen before Driver setup so the builder's listeners are activated first!
+ createEventBuilder();
+
+ // Configure the job manager for the XML steering.
+ sessionState.jobManager.setPerformDryRun(true);
+ if (steeringType == SteeringType.RESOURCE) {
+ setupSteeringResource(steering);
+ } else if (steeringType.equals(SteeringType.FILE)) {
+ setupSteeringFile(steering);
+ }
+
+ // Is there a user specified run number from the JobPanel?
+ if (configurationModel.hasValidProperty(ConfigurationModel.USER_RUN_NUMBER_PROPERTY)) {
+ int userRunNumber = configurationModel.getUserRunNumber();
+ String detectorName = configurationModel.getDetectorName();
+ DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
+ logger.config("setting user run number " + userRunNumber + " with detector " + detectorName);
+ conditionsManager.setDetector(configurationModel.getDetectorName(), userRunNumber);
+ if (configurationModel.hasPropertyKey(ConfigurationModel.FREEZE_CONDITIONS_PROPERTY)) {
+ // Freeze the conditions system to ignore run numbers from the events.
+ logger.config("user configured to freeze conditions system from monitoring app");
+ conditionsManager.freeze();
+ } else {
+ // Allow run numbers to be picked up from the events.
+ logger.config("user run number specified but conditions system is NOT frozen");
+ conditionsManager.unfreeze();
+ }
+ }
+
+ logger.info("LCSim setup was successful.");
+
+ } catch (Throwable t) {
+ // Catch all errors and rethrow them as RuntimeExceptions.
+ errorHandler.setError(t).setMessage("Error setting up LCSim.").printStackTrace().raiseException();
+ }
+ }
+
+ void setupSteeringFile(String steering) {
+ logger.config("setting up steering file: " + steering);
+ sessionState.jobManager.setup(new File(steering));
+ }
+
+ void setupSteeringResource(String steering) throws IOException {
+ logger.config("setting up steering resource: " + steering);
+ InputStream is = this.getClass().getClassLoader().getResourceAsStream(steering);
+ if (is == null)
+ throw new IOException("Steering resource is not accessible or does not exist.");
+ sessionState.jobManager.setup(is);
+ is.close();
+ }
+
+ /**
+ * Create the event builder for converting EVIO events to LCSim.
+ */
+ void createEventBuilder() {
+
+ // Get the class for the event builder.
+ String eventBuilderClassName = configurationModel.getEventBuilderClassName();
+
+ logger.config("initializing event builder: " + eventBuilderClassName);
+
+ try {
+ // Create a new instance of the builder class.
+ sessionState.eventBuilder = (LCSimEventBuilder) Class.forName(eventBuilderClassName).newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to create LCSimEventBuilder.", e);
+ }
+
+ // Add the builder as a listener so it is notified when conditions change.
+ ConditionsManager.defaultInstance().addConditionsListener(sessionState.eventBuilder);
+
+ logger.config("successfully initialized event builder: " + eventBuilderClassName);
+ }
+
+ void setupCompositeLoop() {
+
+ CompositeLoopConfiguration loopConfig = new CompositeLoopConfiguration()
+ .setStopOnEndRun(configurationModel.getDisconnectOnEndRun())
+ .setStopOnErrors(configurationModel.getDisconnectOnError())
+ .setDataSourceType(configurationModel.getDataSourceType())
+ .setProcessingStage(configurationModel.getProcessingStage())
+ .setEtConnection(sessionState.connection)
+ .setFilePath(configurationModel.getDataSourcePath())
+ .setLCSimEventBuilder(sessionState.eventBuilder)
+ .setDetectorName(configurationModel.getDetectorName());
+
+ if (configurationModel.hasValidProperty(ConfigurationModel.MAX_EVENTS_PROPERTY)) {
+ long maxEvents = configurationModel.getMaxEvents();
+ if (maxEvents > 0L) {
+ logger.config("processing will stop after max events: " + maxEvents);
+ loopConfig.setMaxRecords(maxEvents);
+ }
+ }
+
+ // Add all Drivers from the JobManager.
+ for (Driver driver : sessionState.jobManager.getDriverExecList()) {
+ loopConfig.add(driver);
+ }
+
+ // Using ET server?
+ if (usingEtServer()) {
+
+ // ET system monitor.
+ loopConfig.add(new EtSystemMonitor());
+
+ // ET system strip charts.
+ loopConfig.add(new EtSystemStripCharts());
+ }
+
+ // RunPanel updater.
+ loopConfig.add(frame.runPanel.new RunModelUpdater());
+
+ // Setup for conditions activation via EVIO events.
+ loopConfig.add(new EvioDetectorConditionsProcessor(configurationModel.getDetectorName()));
+
+ // Create the CompositeLoop with the configuration.
+ sessionState.loop = new CompositeLoop(loopConfig);
+ }
+
+ void startEventProcessingThread() {
+
+ // Create the processing thread.
+ sessionState.processingThread = new EventProcessingThread(sessionState.loop);
+
+ // Start the processing thread.
+ sessionState.processingThread.start();
+ }
+}
Added: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java
=============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java (added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java Mon Mar 2 18:43:16 2015
@@ -0,0 +1,123 @@
+package org.hps.monitoring.application;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GraphicsConfiguration;
+import java.awt.Rectangle;
+import java.awt.event.ActionListener;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTabbedPane;
+
+import org.hps.monitoring.application.model.RunModel;
+
+/**
+ *
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+class MonitoringApplicationFrame extends JFrame {
+
+ RunPanel runPanel;
+ PlotPanel plotPanel;
+ PlotInfoPanel plotInfoPanel;
+ LogTable logTable;
+
+ GraphicsConfiguration graphics = this.getGraphicsConfiguration();
+ Rectangle bounds = graphics.getBounds();
+
+ /**
+ *
+ * @param listener
+ */
+ public MonitoringApplicationFrame(ActionListener listener) {
+
+ // Create the content panel.
+ JPanel contentPanel = new JPanel();
+ contentPanel.setLayout(new BorderLayout());
+ contentPanel.setPreferredSize(scaleBounds(1.0, 1.0));
+ setContentPane(contentPanel);
+
+ // Create the top panel.
+ JPanel topPanel = new JPanel();
+ topPanel.setPreferredSize(scaleBounds(1.0, 0.1));
+
+ // Create the left panel.
+ JPanel leftPanel = new JPanel();
+ leftPanel.setLayout(new BorderLayout());
+ leftPanel.setPreferredSize(scaleBounds(0.3, 1.0));
+
+ // Create the run dashboard.
+ runPanel = new RunPanel();
+
+ // Create the tabbed pane for content in bottom of left panel such as log table and system monitor.
+ JTabbedPane tableTabbedPane = new JTabbedPane();
+
+ // Create the log table and add it to the tabs.
+ logTable = new LogTable();
+ tableTabbedPane.addTab("Log", new JScrollPane(logTable));
+
+ // Create the system monitor.
+ SystemStatusTable systemStatusTable = new SystemStatusTable();
+ tableTabbedPane.addTab("System Status Monitor", new JScrollPane(systemStatusTable));
+
+ // Vertical split pane in left panel.
+ JSplitPane leftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, runPanel, tableTabbedPane);
+ leftPanel.add(leftSplitPane, BorderLayout.CENTER);
+
+ // Create the right panel.
+ JPanel rightPanel = new JPanel();
+ rightPanel.setLayout(new BorderLayout());
+
+ // Create the plot info panel.
+ plotInfoPanel = new PlotInfoPanel();
+
+ // Create the plot panel.
+ plotPanel = new PlotPanel();
+ plotPanel.setPreferredSize(scaleBounds(0.7, 0.8));
+
+ // Create the right panel vertical split pane for displaying plots and their information and statistics.
+ JSplitPane rightSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, plotPanel, plotInfoPanel);
+ rightSplitPane.setPreferredSize(scaleBounds(0.7, 1.0));
+ rightSplitPane.setResizeWeight(0.9);
+ rightPanel.add(rightSplitPane, BorderLayout.CENTER);
+
+ // Create the main horizontal split pane for dividing the left and right panels.
+ JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel);
+ contentPanel.add(mainSplitPane, BorderLayout.CENTER);
+
+ // Create the menu bar.
+ setJMenuBar(new MenuBar(listener));
+
+ // Setup the frame now that all components have been added.
+ pack();
+ setExtendedState(JFrame.MAXIMIZED_BOTH);
+ setVisible(true);
+ }
+
+ /**
+ * Scale the screen bounds of the <code>JFrame</code> by the given proportions.
+ * @param scaleX The X scaling (must be between 0 and 1).
+ * @param scaleY The Y scaling (must be between 0 and 1).
+ * @return
+ */
+ Dimension scaleBounds(double scaleX, double scaleY) {
+ if (scaleX < 0 || scaleX > 1) {
+ throw new IllegalArgumentException("scaleX must be > 0 and <= 1.");
+ }
+ if (scaleY < 0 || scaleY > 1) {
+ throw new IllegalArgumentException("scaleX must be > 0 and <= 1.");
+ }
+ return new Dimension((int)(bounds.getX() * scaleX), (int)(bounds.getY() * scaleX));
+ }
+
+ /**
+ *
+ * @param runModel
+ */
+ void setRunModel(RunModel runModel) {
+ runPanel.setModel(runModel);
+ }
+}
Added: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java
=============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java (added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java Mon Mar 2 18:43:16 2015
@@ -0,0 +1,405 @@
+package org.hps.monitoring.application;
+
+import hep.aida.IAxis;
+import hep.aida.IBaseHistogram;
+import hep.aida.ICloud1D;
+import hep.aida.ICloud2D;
+import hep.aida.IDataPointSet;
+import hep.aida.IFunction;
+import hep.aida.IHistogram1D;
+import hep.aida.IHistogram2D;
+import hep.aida.jfree.plotter.PlotterRegion;
+import hep.aida.ref.event.AIDAListener;
+import hep.aida.ref.event.AIDAObservable;
+import hep.aida.ref.function.FunctionChangedEvent;
+import hep.aida.ref.function.FunctionDispatcher;
+import hep.aida.ref.function.FunctionListener;
+
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.EventObject;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import javax.swing.BorderFactory;
+import javax.swing.JComboBox;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.plaf.basic.BasicComboBoxRenderer;
+import javax.swing.table.DefaultTableModel;
+
+/**
+ * <p>
+ * This is a GUI component for showing the statistics and other information about an AIDA plot
+ * when it is clicked on in the monitoring app.
+ * <p>
+ * The information is updated dynamically via the <code>AIDAObserver</code> API on the AIDA object.
+ */
+public class PlotInfoPanel extends JPanel implements AIDAListener, ActionListener, FunctionListener {
+
+ JComboBox<Object> plotComboBox;
+ JTable infoTable = new JTable();
+ DefaultTableModel model;
+ PlotterRegion currentRegion;
+ Object currentObject;
+ static final int INSET_SIZE = 5;
+ static final int BORDER_SIZE = 10;
+
+ static final String[] COLUMN_NAMES = { "Field", "Value" };
+
+ static final String PLOT_SELECTED = "PlotSelected";
+
+ Timer timer = new Timer();
+
+ /**
+ * Class constructor, which will setup the GUI components.
+ */
+ @SuppressWarnings("unchecked")
+ PlotInfoPanel() {
+
+ setLayout(new GridBagLayout());
+ setBorder(BorderFactory.createEmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
+
+ GridBagConstraints c;
+
+ plotComboBox = new JComboBox<Object>();
+ plotComboBox.setActionCommand(PLOT_SELECTED);
+ plotComboBox.setRenderer(new BasicComboBoxRenderer() {
+ @SuppressWarnings("rawtypes")
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ if (value != null) {
+ String title = getObjectTitle(value);
+ setText(value.getClass().getSimpleName() + " - " + title);
+ } else {
+ setText("Click on a plot region ...");
+ }
+ return this;
+ }
+ });
+ plotComboBox.addActionListener(this);
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 0;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.insets = new Insets(0, 0, INSET_SIZE, 0);
+ add(plotComboBox, c);
+
+ String data[][] = new String[0][0];
+ model = new DefaultTableModel(data, COLUMN_NAMES);
+ infoTable.setModel(model);
+
+ // FIXME: Are these adequate column size settings? Could prob be bigger...
+ infoTable.getColumn("Field").setMinWidth(25);
+ infoTable.getColumn("Value").setMinWidth(20);
+
+ c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 1;
+ c.fill = GridBagConstraints.BOTH;
+ add(infoTable, c);
+ }
+
+ /**
+ * This method will be called when the backing AIDA object is updated and a state change is
+ * fired via the <code>AIDAObservable</code> API. The table is updated to reflect the new state
+ * of the object.
+ * @param evt The EventObject pointing to the backing AIDA object.
+ */
+ @Override
+ public void stateChanged(final EventObject evt) {
+
+ // Make a timer task for running the update.
+ TimerTask task = new TimerTask() {
+ public void run() {
+
+ // Is the state change from the current AIDAObservable?
+ if (evt.getSource() != currentObject) {
+ // Assume this means that a different AIDAObservable was selected in the GUI.
+ return;
+ }
+
+ // Update the table values on the Swing EDT.
+ runUpdateTable();
+
+ // Set the observable to valid so subsequent state changes are received.
+ ((AIDAObservable) currentObject).setValid((AIDAListener) PlotInfoPanel.this);
+ }
+ };
+
+ /*
+ * Schedule the task to run in ~0.5 seconds. If the Runnable runs immediately, somehow the
+ * observable state gets permanently set to invalid and additional state changes will not be
+ * received!
+ */
+ timer.schedule(task, 500);
+ }
+
+ /**
+ * Implementation of <code>actionPerformed</code> to handle the selection of a new object from
+ * the combo box.
+ */
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ // Is there a new item selected in the combo box?
+ if (PLOT_SELECTED.equals(e.getActionCommand())) {
+ if (plotComboBox.getSelectedItem() != null) {
+ // Set the current object from the combo box value, to update the GUI state.
+ setCurrentObject(plotComboBox.getSelectedItem());
+ }
+ }
+ }
+
+ /**
+ * Get the title of an AIDA object. Unfortunately there is no base type with this information,
+ * so it is gotten manually from each possible type.
+ * @param object The AIDA object.
+ * @return The title of the object from its title method or value of its toString method, if
+ * none exists.
+ */
+ String getObjectTitle(Object object) {
+ if (object instanceof IBaseHistogram) {
+ return ((IBaseHistogram) object).title();
+ } else if (object instanceof IDataPointSet) {
+ return ((IDataPointSet) object).title();
+ } else if (object instanceof IFunction) {
+ return ((IFunction) object).title();
+ } else {
+ return object.toString();
+ }
+ }
+
+ /**
+ * Set the current plotter region, which will rebuild the GUI accordingly.
+ * @param region The current plotter region.
+ */
+ synchronized void setCurrentRegion(PlotterRegion region) {
+ if (region != currentRegion) {
+ currentRegion = region;
+ //if (currentRegion.title() != null)
+ // setTitle(currentRegion.title());
+ updateComboBox();
+ setCurrentObject(plotComboBox.getSelectedItem());
+ setupContentPane();
+ }
+ }
+
+ /**
+ * Configure the frame's content panel from current component settings.
+ */
+ void setupContentPane() {
+ plotComboBox.setSize(plotComboBox.getPreferredSize());
+ infoTable.setSize(infoTable.getPreferredSize());
+ setVisible(true);
+ }
+
+ /**
+ * Update the info table from the state of the current AIDA object.
+ */
+ void updateTable() {
+ model.setRowCount(0);
+ model.setColumnIdentifiers(COLUMN_NAMES);
+ if (currentObject instanceof IHistogram1D) {
+ addRows((IHistogram1D) currentObject);
+ } else if (currentObject instanceof IHistogram2D) {
+ addRows((IHistogram2D) currentObject);
+ } else if (currentObject instanceof ICloud2D) {
+ addRows((ICloud2D) currentObject);
+ } else if (currentObject instanceof ICloud1D) {
+ if (((ICloud1D) currentObject).isConverted()) {
+ addRows(((ICloud1D) currentObject).histogram());
+ }
+ } else if (currentObject instanceof IFunction) {
+ addRows((IFunction) currentObject);
+ }
+ }
+
+ /**
+ * Run the {@link #updateTable()} method on the Swing EDT.
+ */
+ void runUpdateTable() {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ updateTable();
+ }
+ });
+ }
+
+ /**
+ * Update the combo box contents with the plots from the current region.
+ */
+ void updateComboBox() {
+ plotComboBox.removeAllItems();
+ List<Object> objects = currentRegion.getPlottedObjects();
+ for (Object object : objects) {
+ if (isValidObject(object)) {
+ plotComboBox.addItem(object);
+ }
+ }
+ }
+
+ boolean isValidObject(Object object) {
+ if (object == null)
+ return false;
+ if (object instanceof IBaseHistogram || object instanceof IFunction || object instanceof IDataPointSet) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Add rows to the info table from the state of a 1D histogram.
+ * @param histogram The AIDA object.
+ */
+ void addRows(IHistogram1D histogram) {
+ addRow("title", histogram.title());
+ addRow("bins", histogram.axis().bins());
+ addRow("entries", histogram.entries());
+ addRow("mean", String.format("%.10f%n", histogram.mean()));
+ addRow("rms", String.format("%.10f%n", histogram.rms()));
+ addRow("sum bin heights", histogram.sumBinHeights());
+ addRow("max bin height", histogram.maxBinHeight());
+ addRow("overflow entries", histogram.binEntries(IAxis.OVERFLOW_BIN));
+ addRow("underflow entries", histogram.binEntries(IAxis.UNDERFLOW_BIN));
+ }
+
+ /**
+ * Add rows to the info table from the state of a 2D histogram.
+ * @param histogram The AIDA object.
+ */
+ void addRows(IHistogram2D histogram) {
+ addRow("title", histogram.title());
+ addRow("x bins", histogram.xAxis().bins());
+ addRow("y bins", histogram.yAxis().bins());
+ addRow("entries", histogram.entries());
+ addRow("x mean", String.format("%.10f%n", histogram.meanX()));
+ addRow("y mean", String.format("%.10f%n", histogram.meanY()));
+ addRow("x rms", String.format("%.10f%n", histogram.rmsX()));
+ addRow("y rms", String.format("%.10f%n", histogram.rmsY()));
+ addRow("sum bin heights", histogram.sumBinHeights());
+ addRow("max bin height", histogram.maxBinHeight());
+ addRow("x overflow entries", histogram.binEntriesX(IAxis.OVERFLOW_BIN));
+ addRow("y overflow entries", histogram.binEntriesY(IAxis.OVERFLOW_BIN));
+ addRow("x underflow entries", histogram.binEntriesX(IAxis.UNDERFLOW_BIN));
+ addRow("y underflow entries", histogram.binEntriesY(IAxis.UNDERFLOW_BIN));
+ }
+
+ /**
+ * Add rows to the info table from the state of a 2D cloud.
+ * @param cloud The AIDA object.
+ */
+ void addRows(ICloud2D cloud) {
+ addRow("title", cloud.title());
+ addRow("entries", cloud.entries());
+ addRow("max entries", cloud.maxEntries());
+ addRow("x lower edge", cloud.lowerEdgeX());
+ addRow("x upper edge", cloud.upperEdgeX());
+ addRow("y lower edge", cloud.lowerEdgeY());
+ addRow("y upper edge", cloud.upperEdgeY());
+ addRow("x mean", String.format("%.10f%n", cloud.meanX()));
+ addRow("y mean", String.format("%.10f%n", cloud.meanY()));
+ addRow("x rms", String.format("%.10f%n", cloud.rmsX()));
+ addRow("y rms", String.format("%.10f%n", cloud.rmsY()));
+ }
+
+ /**
+ * Add rows to the info table from the state of a 2D cloud.
+ * @param cloud The AIDA object.
+ */
+ void addRows(IFunction function) {
+ addRow("title", function.title());
+
+ // Add generically the values of all function parameters.
+ for (String parameter : function.parameterNames()) {
+ addRow(parameter, function.parameter(parameter));
+ }
+ }
+
+ /**
+ * Add a row to the info table.
+ * @param field The field name.
+ * @param value The field value.
+ */
+ void addRow(String field, Object value) {
+ model.insertRow(infoTable.getRowCount(), new Object[] { field, value });
+ }
+
+ /**
+ * Set the current AIDA object that backs this GUI, i.e. an IHistogram1D etc.
+ * @param object The backing AIDA object.
+ */
+ synchronized void setCurrentObject(Object object) {
+
+ if (object == null)
+ throw new IllegalArgumentException("The object arg is null!");
+
+ if (object == currentObject)
+ return;
+
+ // Remove the AIDAListener from the previous object.
+ removeListener();
+
+ // Set the current object reference.
+ currentObject = object;
+
+ // Update the table immediately with information from the current object.
+ // We need to wait for this the first time, so we know the preferred size
+ // of the table GUI component when resizing the content pane.
+ updateTable();
+
+ // Add an AIDAListener to the AIDA object via the AIDAObservable API.
+ addListener();
+ }
+
+ /**
+ * Remove this as a listener on the current AIDA object.
+ */
+ void removeListener() {
+ if (currentObject != null) {
+ if (currentObject instanceof AIDAObservable && !(currentObject instanceof IFunction)) {
+ // Remove this object as an listener on the AIDA observable.
+ ((AIDAObservable) currentObject).removeListener(this);
+ } else if (currentObject instanceof FunctionDispatcher) {
+ // Remove this object as function listener.
+ ((FunctionDispatcher)currentObject).removeFunctionListener(this);
+ }
+ }
+ }
+
+ /**
+ * Add this object as an <code>AIDAListener</code> on the current <code>AIDAObservable</code>.
+ */
+ void addListener() {
+ if (currentObject instanceof AIDAObservable && !(currentObject instanceof FunctionDispatcher)) {
+ // Setup a listener on the current AIDA object.
+ AIDAObservable observable = (AIDAObservable) currentObject;
+ observable.addListener(this);
+ observable.setValid(this);
+ observable.setConnected(true);
+ } else if (currentObject instanceof IFunction) {
+ if (currentObject instanceof FunctionDispatcher) {
+ ((FunctionDispatcher)currentObject).addFunctionListener(this);
+ }
+ }
+ }
+
+ /**
+ * Callback for updating from changed to <code>IFunction</code> object.
+ * @param event The change event (unused in this method).
+ */
+ @Override
+ public void functionChanged(FunctionChangedEvent event) {
+ try {
+ runUpdateTable();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
Added: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/PlotPanel.java
=============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/PlotPanel.java (added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/PlotPanel.java Mon Mar 2 18:43:16 2015
@@ -0,0 +1,24 @@
+package org.hps.monitoring.application;
+
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+
+/**
+ * This is the panel containing the monitoring plots.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class PlotPanel extends JPanel {
+ private JTabbedPane plotPane;
+
+ public PlotPanel() {
+ plotPane = new JTabbedPane();
+ }
+
+ JTabbedPane getPlotPane() {
+ return plotPane;
+ }
+
+ void reset() {
+ plotPane.removeAll();
+ }
+}
Added: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SessionState.java
=============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SessionState.java (added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SessionState.java Mon Mar 2 18:43:16 2015
@@ -0,0 +1,16 @@
+package org.hps.monitoring.application;
+
+import org.hps.job.JobManager;
+import org.hps.record.LCSimEventBuilder;
+import org.hps.record.composite.CompositeLoop;
+import org.hps.record.composite.EventProcessingThread;
+import org.hps.record.et.EtConnection;
+
+class SessionState {
+ JobManager jobManager;
+ LCSimEventBuilder eventBuilder;
+ CompositeLoop loop;
+ EventProcessingThread processingThread;
+ Thread sessionWatchdogThread;
+ EtConnection connection;
+}
Added: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SystemStatusTable.java
=============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SystemStatusTable.java (added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SystemStatusTable.java Mon Mar 2 18:43:16 2015
@@ -0,0 +1,148 @@
+package org.hps.monitoring.application;
+
+import static org.hps.monitoring.application.model.SystemStatusTableModel.ACTIVE_COL;
+import static org.hps.monitoring.application.model.SystemStatusTableModel.CLEARABLE_COL;
+import static org.hps.monitoring.application.model.SystemStatusTableModel.LAST_CHANGED_COL;
+import static org.hps.monitoring.application.model.SystemStatusTableModel.RESET_COL;
+import static org.hps.monitoring.application.model.SystemStatusTableModel.STATUS_COL;
+import static org.hps.monitoring.application.model.SystemStatusTableModel.SYSTEM_COL;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableCellRenderer;
+
+import org.hps.monitoring.application.model.SystemStatusTableModel;
+import org.hps.monitoring.subsys.StatusCode;
+
+/**
+ * A GUI window for showing changes to {@link org.hps.monitoring.subsys.SystemStatus} objects using
+ * a <code>JTable</code>.
+ */
+class SystemStatusTable extends JTable {
+
+ SystemStatusTable() {
+
+ setModel(new SystemStatusTableModel());
+
+ // Rendering of system status cells using different background colors.
+ getColumnModel().getColumn(SystemStatusTableModel.STATUS_COL).setCellRenderer(new DefaultTableCellRenderer() {
+
+ @Override
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
+
+ // Cells are by default rendered as a JLabel.
+ JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
+
+ // Color code the cell by its status.
+ StatusCode statusCode = StatusCode.valueOf((String) value);
+ if (statusCode.ordinal() >= StatusCode.ERROR.ordinal()) {
+ // Any type of error is red.
+ label.setBackground(Color.RED);
+ } else if (statusCode.equals(StatusCode.WARNING)) {
+ // Warnings are yellow.
+ label.setBackground(Color.YELLOW);
+ } else if (statusCode.equals(StatusCode.OKAY)) {
+ // Okay is green.
+ label.setBackground(Color.GREEN);
+ } else if (statusCode.equals(StatusCode.OFFLINE)) {
+ // Offline is orange.
+ label.setBackground(Color.ORANGE);
+ } else if (statusCode.equals(StatusCode.UNKNOWN)) {
+ // Unknown is gray.
+ label.setBackground(Color.GRAY);
+ } else if (statusCode.equals(StatusCode.CLEARED)) {
+ // Cleared is light gray.
+ label.setBackground(Color.LIGHT_GRAY);
+ } else {
+ // Default is white, though this shouldn't happen!
+ label.setBackground(Color.WHITE);
+ }
+ return label;
+ }
+ });
+
+ // Date formatting for last changed.
+ getColumnModel().getColumn(LAST_CHANGED_COL).setCellRenderer(new DefaultTableCellRenderer() {
+
+ final SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM-dd-yyyy HH:mm:ss.SSS");
+
+ @Override
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ if (value instanceof Date) {
+ value = dateFormat.format(value);
+ }
+ return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+ }
+ });
+
+ // Button for clearing system statuses.
+ getColumnModel().getColumn(RESET_COL).setCellRenderer(new ButtonRenderer("Clear"));
+ addMouseListener(new JTableButtonMouseListener(this));
+ getColumn("Clearable").setWidth(0);
+ getColumn("Clearable").setMinWidth(0);
+ getColumn("Clearable").setMaxWidth(0);
+
+ // Column widths.
+ getColumnModel().getColumn(ACTIVE_COL).setPreferredWidth(8);
+ getColumnModel().getColumn(STATUS_COL).setPreferredWidth(10);
+ getColumnModel().getColumn(SYSTEM_COL).setPreferredWidth(10);
+ // TODO: Add default width setting for every column.
+
+ setAutoCreateRowSorter(true);
+ }
+
+ public SystemStatusTableModel getTableModel() {
+ return (SystemStatusTableModel) getModel();
+ }
+
+ /**
+ * Renders a button if the status is clearable.
+ */
+ private class ButtonRenderer extends JButton implements TableCellRenderer {
+
+ public ButtonRenderer(String label) {
+ this.setText(label);
+ }
+
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ boolean clearable = (Boolean) table.getModel().getValueAt(row, CLEARABLE_COL);
+ if (clearable)
+ return this;
+ else
+ return null;
+ }
+ }
+
+ /**
+ * Fires a mouse click event when the clear button is pressed, which in turn will activate the
+ * action event for the button. The <code>ActionListener</code> then sets the
+ * <code>StatusCode</code> to <code>CLEARED</code>.
+ */
+ private static class JTableButtonMouseListener extends MouseAdapter {
+ private final JTable table;
+
+ public JTableButtonMouseListener(JTable table) {
+ this.table = table;
+ }
+
+ public void mouseClicked(MouseEvent e) {
+ int column = table.getColumnModel().getColumnIndexAtX(e.getX());
+ int row = e.getY() / table.getRowHeight();
+ if (row < table.getRowCount() && row >= 0 && column < table.getColumnCount() && column >= 0) {
+ Object value = table.getValueAt(row, column);
+ if (value instanceof JButton) {
+ ((JButton) value).doClick();
+ }
+ }
+ }
+ }
+}
Added: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/util/EtSystemUtil.java
=============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/util/EtSystemUtil.java (added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/util/EtSystemUtil.java Mon Mar 2 18:43:16 2015
@@ -0,0 +1,24 @@
+package org.hps.monitoring.application.util;
+
+import org.hps.monitoring.application.model.ConfigurationModel;
+import org.hps.record.et.EtConnection;
+
+public class EtSystemUtil {
+
+ private EtSystemUtil() {
+ }
+
+ public static EtConnection createEtConnection(ConfigurationModel config) {
+ return EtConnection.createConnection(config.getEtName(),
+ config.getHost(),
+ config.getPort(),
+ config.getBlocking(),
+ config.getQueueSize(),
+ config.getPrescale(),
+ config.getStationName(),
+ config.getStationPosition(),
+ config.getWaitMode(),
+ config.getWaitTime(),
+ config.getChunkSize());
+ }
+}
|