Author: [log in to unmask] Date: Thu Mar 5 22:53:56 2015 New Revision: 2294 Log: Work in progress on monitoring-app branch. Added: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/Main.java - copied, changed from r2271, java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/Main.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java - copied, changed from r2271, java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/ConnectionStatus.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/SteeringType.java - copied, changed from r2271, java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SteeringType.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/package-info.java - copied, changed from r2271, java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/package-info.java Removed: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/Main.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/ConnectionStatus.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringApplicationActionListener.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SteeringType.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/package-info.java Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/AddActionListener.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/Commands.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/DataSourceComboBox.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/EventProcessing.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java 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/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/RunPanel.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/SettingsDialog.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SettingsPanel.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/model/ConfigurationModel.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/HasConfigurationModel.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/SystemStatusTableModel.java java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/util/ErrorHandler.java java/branches/monitoring-app-HPSJAVA-442/src/main/resources/org/hps/monitoring/config/default_config.prop Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/AddActionListener.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/AddActionListener.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/AddActionListener.java Thu Mar 5 22:53:56 2015 @@ -2,7 +2,7 @@ import java.awt.event.ActionListener; -public interface AddActionListener { +interface AddActionListener { void addActionListener(ActionListener listener); } Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/Commands.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/Commands.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/Commands.java Thu Mar 5 22:53:56 2015 @@ -4,16 +4,29 @@ * These strings are used to identify ActionEvents in the MonitoringApplication. A few commands * handled only by sub-components are not listed here. */ -public final class Commands { +final class Commands { static final String SETTINGS_LOAD = "settingsLoad"; static final String SETTINGS_LOAD_DEFAULT = "settingsLoadDefault"; static final String SETTINGS_SAVE = "settingsSave"; static final String SETTINGS_SHOW = "settingsShow"; - static final String OPEN_FILE = "openFile"; + + static final String FILE_OPEN = "openFile"; + static final String FILE_CLOSE = "closeFile"; + + static final String WINDOW_MAXIMIZE = "maximizeWindow"; + static final String WINDOW_MINIMIZE = "minimizeWindow"; + static final String WINDOW_DEFAULTS = "restoreDefaultWindow"; static final String DATA_SOURCE_CHANGED = "dataSourceChanged"; + static final String CONNECT = "connect"; + static final String NEXT = "next"; + static final String PAUSE = "pause"; + static final String RESUME = "resume"; + + static final String EXIT = "exit"; + //////////////////////////////////////////// static final String BLOCKING_CHANGED = "blockingChanged"; @@ -21,7 +34,6 @@ static final String CHOOSE_LOG_FILE = "chooseLogFile"; static final String CHOOSE_STEERING_FILE = "chooseSteeringFile"; - static final String CONNECT = "connect"; static final String CLEAR_LOG_TABLE = "clearLogTable"; static final String DATA_SOURCE_TYPE_CHANGED = "dataSourceTypeChanged"; static final String DETECTOR_NAME_CHANGED = "detectorNameChanged"; @@ -30,21 +42,17 @@ static final String DISCONNECT_ON_ERROR_CHANGED = "disconnectOnErrorChanged"; static final String DISCONNECT_ON_END_RUN_CHANGED = "disconnectOnEndRunChanged"; static final String EVENT_BUILDER_CHANGED = "eventBuilderChanged"; - static final String EXIT = "exit"; static final String FREEZE_CONDITIONS_CHANGED = "freezeConditionsChanged"; static final String LOG_LEVEL_CHANGED = "logLevelChanged"; static final String LOG_TO_FILE = "logToFile"; static final String LOG_TO_FILE_CHANGED = "logToFileChanged"; static final String LOG_TO_TERMINAL = "logToTerminal"; - static final String NEXT = "next"; - static final String PAUSE = "pause"; + static final String PROCESSING_STAGE_CHANGED = "processingStageChanged"; static final String PLOTS_CLEAR = "resetPlots"; static final String RESTORE_DEFAULT_GUI_LAYOUT = "restoreDefaultGuiLayout"; - static final String RESUME = "resume"; - static final String SAVE_LAYOUT = "saveLayout"; static final String SAVE_LOG_TABLE = "saveLogTable"; static final String PLOTS_SAVE = "savePlots"; static final String SCREENSHOT = "screenshot"; Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java Thu Mar 5 22:53:56 2015 @@ -15,6 +15,7 @@ import javax.swing.JPanel; import javax.swing.JTextField; +import org.hps.monitoring.application.model.ConnectionStatus; import org.hps.monitoring.application.model.ConnectionStatusModel; /** Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/DataSourceComboBox.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/DataSourceComboBox.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/DataSourceComboBox.java Thu Mar 5 22:53:56 2015 @@ -5,94 +5,134 @@ import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.io.File; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import org.hps.monitoring.application.DataSourceComboBox.DataSourceItem; import org.hps.monitoring.application.model.ConfigurationModel; +import org.hps.monitoring.application.model.ConnectionStatus; import org.hps.monitoring.application.model.ConnectionStatusModel; import org.hps.record.enums.DataSourceType; /** + * <p> + * This is a combo box that shows and can be used to select the current data source + * such as an LCIO file, EVIO file or ET ring. + * <p> + * The way this works is kind of funky because it is not directly connected to an + * event loop, so it must catch changes to the configuration and update its + * items accordingly. * * @author Jeremy McCormick <[log in to unmask]> - * */ -public class DataSourceComboBox extends JComboBox<DataSourceItem> implements PropertyChangeListener, ActionListener { +class DataSourceComboBox extends JComboBox<DataSourceItem> implements PropertyChangeListener, ActionListener { ConnectionStatusModel connectionModel; ConfigurationModel configurationModel; - - DataSourceComboBox( - ConfigurationModel configurationModel, - ConnectionStatusModel connectionModel, - ActionListener listener) { - addActionListener(listener); - setActionCommand(Commands.DATA_SOURCE_CHANGED); - setPreferredSize(new Dimension(400, this.getPreferredSize().height)); - setEditable(false); - connectionModel.addPropertyChangeListener(this); - configurationModel.addPropertyChangeListener(this); - this.configurationModel = configurationModel; - } - - public void addItem(DataSourceItem item) { - // Do not add duplicates. - if (!contains(item)) { - super.addItem(item); - } - } - - boolean contains(DataSourceItem item) { - return ((DefaultComboBoxModel<DataSourceItem>)getModel()).getIndexOf(item) != -1; - } - + static class DataSourceItem { - + String name; DataSourceType type; - + DataSourceItem(String name, DataSourceType type) { this.type = type; this.name = name; } - + public String toString() { return name; - } - + } + public boolean equals(Object object) { if (!(object instanceof DataSourceItem)) { return false; } DataSourceItem otherItem = (DataSourceItem) object; - if (this.name == otherItem.name && this.type == otherItem.type) return true; + if (this.name == otherItem.name && this.type == otherItem.type) + return true; return false; } } + + DataSourceComboBox(ConfigurationModel configurationModel, ConnectionStatusModel connectionModel) { + addActionListener(this); + setActionCommand(Commands.DATA_SOURCE_CHANGED); + setPreferredSize(new Dimension(400, this.getPreferredSize().height)); + setEditable(false); + connectionModel.addPropertyChangeListener(this); + this.configurationModel = configurationModel; + } + + void initialize() { + + // Add the default ET item. + addItem(new DataSourceItem(configurationModel.getEtPath(), DataSourceType.ET_SERVER)); + + // Add a file source if one has been provided. + if (configurationModel.getDataSourcePath() != null) { + addItem(new DataSourceItem(configurationModel.getDataSourcePath(), getDataSourceType(configurationModel.getDataSourcePath()))); + } + + // Set the initially selected item. + setSelectedItem(); + + // Don't add as the property listener until after initialization. + configurationModel.addPropertyChangeListener(this); + } + + void setSelectedItem() { + DataSourceItem item = findItem(configurationModel.getDataSourcePath(), configurationModel.getDataSourceType()); + if (item != null) { + setSelectedItem(item); + } + } - /** - * - */ + boolean contains(DataSourceItem item) { + return ((DefaultComboBoxModel<DataSourceItem>) getModel()).getIndexOf(item) != -1; + } + @Override public void propertyChange(PropertyChangeEvent evt) { - if (evt.getPropertyName().equals(ConnectionStatusModel.CONNECTION_STATUS_PROPERTY)) { - ConnectionStatus status = (ConnectionStatus) evt.getNewValue(); - if (status.equals(ConnectionStatus.DISCONNECTED)) { - setEnabled(true); - } else { - setEnabled(false); - } - } else if (evt.getPropertyName().equals(ConfigurationModel.DATA_SOURCE_PATH_PROPERTY)) { - System.out.println("data source path property changed"); - addDataSourceItem(); - } - } + if (evt.getPropertyName().equals(ConnectionStatusModel.CONNECTION_STATUS_PROPERTY)) { + ConnectionStatus status = (ConnectionStatus) evt.getNewValue(); + if (status.equals(ConnectionStatus.DISCONNECTED)) { + setEnabled(true); + } else { + setEnabled(false); + } + } else if (evt.getPropertyName().equals(ConfigurationModel.DATA_SOURCE_PATH_PROPERTY)) { + String path = configurationModel.getDataSourcePath(); + DataSourceType type = getDataSourceType(path); + addDataSourceItem(path, type); + setSelectedItem(); + } else if (evt.getPropertyName().equals(ConfigurationModel.DATA_SOURCE_TYPE_PROPERTY)) { + setSelectedItem(); + } else if (evt.getPropertyName().equals(ConfigurationModel.HOST_PROPERTY)) { + updateEtItem(); + } else if (evt.getPropertyName().equals(ConfigurationModel.ET_NAME_PROPERTY)) { + updateEtItem(); + } else if (evt.getPropertyName().equals(ConfigurationModel.PORT_PROPERTY)) { + updateEtItem(); + } + } + static DataSourceType getDataSourceType(String path) { + if (path.endsWith(".slcio")) { + return DataSourceType.LCIO_FILE; + } else if (new File(path).getName().contains(".evio")) { + return DataSourceType.EVIO_FILE; + } else { + return DataSourceType.ET_SERVER; + } + } + public void actionPerformed(ActionEvent evt) { if (evt.getActionCommand().equals(Commands.DATA_SOURCE_CHANGED)) { try { + // Update the model with data source settings. configurationModel.removePropertyChangeListener(this); DataSourceItem item = (DataSourceItem) getSelectedItem(); configurationModel.setDataSourceType(item.type); @@ -104,51 +144,47 @@ } } } - - void addDataSourceItem() { - - DataSourceType type = configurationModel.getDataSourceType(); - String path = configurationModel.getDataSourcePath(); - - // Remove an existing ET item in case the settings have changed. - if (hasEtItem()) { - removeEtItem(); + + public void addItem(DataSourceItem item) { + // Do not add invalid looking items. + if (item.name == null || item.name.length() == 0) { + return; } - - // Always make sure there is an ET server available as a data source. - addItem(new DataSourceItem(getEtName(), DataSourceType.ET_SERVER)); - - // Add a data source for a file. - if (!type.equals(DataSourceType.ET_SERVER)) { - DataSourceItem newItem = new DataSourceItem(path, type); - if (!contains(newItem)) { - addItem(newItem); - setSelectedItem(newItem); - } - } + // Do not add duplicates. + if (!contains(item)) { + super.addItem(item); + } + } + + DataSourceItem findItem(String path, DataSourceType type) { + for (int i = 0; i < this.getItemCount(); i++) { + DataSourceItem item = this.getItemAt(i); + if (item.type == type && item.name == path) { + return item; + } + } + return null; } - void removeEtItem() { - for (int i=0; i<this.getItemCount(); i++) { + DataSourceItem findEtItem() { + for (int i = 0; i < this.getItemCount(); i++) { DataSourceItem item = this.getItemAt(i); if (item.type == DataSourceType.ET_SERVER) { - this.removeItem(item); - break; + return item; } + } + return null; + } + + void addDataSourceItem(String path, DataSourceType type) { + DataSourceItem newItem = new DataSourceItem(path, type); + if (!contains(newItem)) { + addItem(newItem); } } - boolean hasEtItem() { - for (int i=0; i<this.getItemCount(); i++) { - DataSourceItem item = this.getItemAt(i); - if (item.type == DataSourceType.ET_SERVER) { - return true; - } - } - return false; - } - - String getEtName() { - return configurationModel.getEtName() + "@" + configurationModel.getHost() + ":" + configurationModel.getPort(); + void updateEtItem() { + DataSourceItem item = findEtItem(); + item.name = configurationModel.getEtPath(); } } Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java Thu Mar 5 22:53:56 2015 @@ -12,6 +12,7 @@ import javax.swing.JButton; import javax.swing.JPanel; +import org.hps.monitoring.application.model.ConnectionStatus; import org.hps.monitoring.application.model.ConnectionStatusModel; /** @@ -65,11 +66,9 @@ @Override public void propertyChange(final PropertyChangeEvent evt) { - System.out.println("EventButtonsPanel.propertyChange - " + evt.getPropertyName()); if (evt.getPropertyName().equals(ConnectionStatusModel.CONNECTION_STATUS_PROPERTY)) { setConnectionStatus((ConnectionStatus) evt.getNewValue()); } else if (evt.getPropertyName().equals(ConnectionStatusModel.PAUSED_PROPERTY)) { - System.out.println(" setPaused: " + (boolean) evt.getNewValue()); setPaused((boolean) evt.getNewValue()); } } Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/EventProcessing.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/EventProcessing.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/EventProcessing.java Thu Mar 5 22:53:56 2015 @@ -11,7 +11,10 @@ import org.hps.conditions.database.DatabaseConditionsManager; import org.hps.job.JobManager; import org.hps.monitoring.application.model.ConfigurationModel; +import org.hps.monitoring.application.model.ConnectionStatus; +import org.hps.monitoring.application.model.SteeringType; import org.hps.monitoring.application.util.ErrorHandler; +import org.hps.monitoring.application.util.EtSystemUtil; import org.hps.monitoring.subsys.et.EtSystemMonitor; import org.hps.monitoring.subsys.et.EtSystemStripCharts; import org.hps.record.LCSimEventBuilder; @@ -20,6 +23,7 @@ import org.hps.record.composite.CompositeRecordProcessor; import org.hps.record.composite.EventProcessingThread; import org.hps.record.enums.DataSourceType; +import org.hps.record.et.EtConnection; import org.hps.record.evio.EvioDetectorConditionsProcessor; import org.lcsim.conditions.ConditionsManager; import org.lcsim.conditions.ConditionsReader; @@ -30,26 +34,53 @@ * @author Jeremy McCormick <[log in to unmask]> * */ -public class EventProcessing { +class EventProcessing { MonitoringApplication application; - SessionState state; - ErrorHandler errorHandler; Logger logger; + SessionState sessionState; List<CompositeRecordProcessor> processors; + /** + * + */ + class SessionState { + JobManager jobManager; + LCSimEventBuilder eventBuilder; + CompositeLoop loop; + EventProcessingThread processingThread; + Thread sessionWatchdogThread; + EtConnection connection; + } + + /** + * + * @param application + * @param processors + */ EventProcessing( MonitoringApplication application, List<CompositeRecordProcessor> processors) { this.application = application; - this.state = application.sessionState; - this.logger = MonitoringApplication.logger; - this.errorHandler = application.errorHandler; + this.sessionState = new SessionState(); this.processors = processors; - } - + this.logger = MonitoringApplication.logger; + } + + /** + * + * @return + */ + SessionState getSessionState() { + return sessionState; + } + + /** + * + * @param configurationModel + */ void setup(ConfigurationModel configurationModel) { - logger.info("setting up LCSim"); + MonitoringApplication.logger.info("setting up LCSim"); // Get steering resource or file as a String parameter. String steering = null; @@ -63,11 +94,11 @@ else steering = configurationModel.getSteeringResource(); - logger.config("Set steering to " + steering + " with type " + (steeringType == SteeringType.RESOURCE ? "RESOURCE" : "FILE")); + MonitoringApplication.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. - state.jobManager = new JobManager(); + sessionState.jobManager = new JobManager(); if (configurationModel.hasValidProperty(ConfigurationModel.DETECTOR_ALIAS_PROPERTY)) { // Set a detector alias. @@ -80,7 +111,7 @@ createEventBuilder(configurationModel); // Configure the job manager for the XML steering. - state.jobManager.setPerformDryRun(true); + sessionState.jobManager.setPerformDryRun(true); if (steeringType == SteeringType.RESOURCE) { setupSteeringResource(steering); } else if (steeringType.equals(SteeringType.FILE)) { @@ -109,7 +140,7 @@ } catch (Throwable t) { // Catch all errors and rethrow them as RuntimeExceptions. - errorHandler.setError(t).setMessage("Error setting up LCSim.").printStackTrace().raiseException(); + application.errorHandler.setError(t).setMessage("Error setting up LCSim.").printStackTrace().raiseException(); } // Setup the CompositeLoop. @@ -128,17 +159,21 @@ try { // Create a new instance of the builder class. - state.eventBuilder = (LCSimEventBuilder) Class.forName(eventBuilderClassName).newInstance(); + 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(state.eventBuilder); + ConditionsManager.defaultInstance().addConditionsListener(sessionState.eventBuilder); //logger.config("successfully initialized event builder: " + eventBuilderClassName); } + /** + * + * @param configurationModel + */ void setupLoop(ConfigurationModel configurationModel) { CompositeLoopConfiguration loopConfig = new CompositeLoopConfiguration() @@ -146,9 +181,9 @@ .setStopOnErrors(configurationModel.getDisconnectOnError()) .setDataSourceType(configurationModel.getDataSourceType()) .setProcessingStage(configurationModel.getProcessingStage()) - .setEtConnection(state.connection) + .setEtConnection(sessionState.connection) .setFilePath(configurationModel.getDataSourcePath()) - .setLCSimEventBuilder(state.eventBuilder) + .setLCSimEventBuilder(sessionState.eventBuilder) .setDetectorName(configurationModel.getDetectorName()); if (configurationModel.hasValidProperty(ConfigurationModel.MAX_EVENTS_PROPERTY)) { @@ -160,7 +195,7 @@ } // Add all Drivers from the JobManager. - for (Driver driver : state.jobManager.getDriverExecList()) { + for (Driver driver : sessionState.jobManager.getDriverExecList()) { loopConfig.add(driver); } @@ -183,8 +218,29 @@ loopConfig.add(new EvioDetectorConditionsProcessor(configurationModel.getDetectorName())); // Create the CompositeLoop with the configuration. - state.loop = new CompositeLoop(loopConfig); + sessionState.loop = new CompositeLoop(loopConfig); } + + /** + * + * @param steering + */ + void setupSteeringFile(String steering) { + sessionState.jobManager.setup(new File(steering)); + } + + /** + * + * @param steering + * @throws IOException + */ + void setupSteeringResource(String steering) throws IOException { + 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(); + } /** * Stop the event processing by executing a <code>STOP</code> command on the record loop and @@ -192,20 +248,20 @@ * that the event processing does not potentially hang in a call to * <code>EtSystem.getEvents()</code> forever. */ - void stop() { + synchronized void stop() { // Is the event processing thread not null? - if (state.processingThread != null) { + if (sessionState.processingThread != null) { // Is the event processing thread actually still alive? - if (state.processingThread.isAlive()) { + if (sessionState.processingThread.isAlive()) { // Request the event processing loop to execute stop. - state.loop.execute(Command.STOP); + sessionState.loop.execute(Command.STOP); try { // This should always work, because the ET system is disconnected before this. - state.processingThread.join(); + sessionState.processingThread.join(); } catch (InterruptedException e) { // Don't know when this would ever happen. e.printStackTrace(); @@ -213,49 +269,38 @@ } // Notify of last error that occurred in event processing. - if (state.loop.getLastError() != null) { - errorHandler.setError(state.loop.getLastError()).log().printStackTrace(); + if (sessionState.loop.getLastError() != null) { + application.errorHandler.setError(sessionState.loop.getLastError()).log().printStackTrace(); } // Set the event processing thread to null as it is unusable now. - state.processingThread = null; + sessionState.processingThread = null; } // Set the loop to null as a new one will be created for next session. - state.loop = null; + sessionState.loop = null; } - - void setupSteeringFile(String steering) { - //logger.config("setting up steering file: " + steering); - state.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."); - state.jobManager.setup(is); - is.close(); - } - - void start() { + + /** + * + */ + synchronized void start() { // Start the event processing thread. - state.processingThread = new EventProcessingThread(state.loop); - state.processingThread.start(); + sessionState.processingThread = new EventProcessingThread(sessionState.loop); + sessionState.processingThread.start(); // Start the watchdog thread which will auto-disconnect when event processing is done. - state.sessionWatchdogThread = new SessionWatchdogThread(state.processingThread); - state.sessionWatchdogThread.start(); + sessionState.sessionWatchdogThread = new SessionWatchdogThread(sessionState.processingThread); + sessionState.sessionWatchdogThread.start(); } /** * Notify the event processor to pause. */ - void pause() { + synchronized void pause() { if (!application.connectionModel.getPaused()) { - state.loop.pause(); + sessionState.loop.pause(); application.connectionModel.setPaused(true); } } @@ -263,10 +308,10 @@ /** * */ - void next() { + synchronized void next() { if (application.connectionModel.getPaused()) { application.connectionModel.setPaused(false); - state.loop.execute(Command.GO_N, 1L, true); + sessionState.loop.execute(Command.GO_N, 1L, true); application.connectionModel.setPaused(true); } } @@ -274,34 +319,124 @@ /** * Notify the event processor to resume processing events, if paused. */ - void resume() { + synchronized void resume() { if (application.connectionModel.getPaused()) { // Notify event processor to continue. - state.loop.resume(); + sessionState.loop.resume(); application.connectionModel.setPaused(false); } } - void killWatchdogThread() { + /** + * + */ + synchronized void killWatchdogThread() { // Is the session watchdog thread not null? - if (state.sessionWatchdogThread != null) { + if (sessionState.sessionWatchdogThread != null) { // Is the thread still alive? - if (state.sessionWatchdogThread.isAlive()) { + if (sessionState.sessionWatchdogThread.isAlive()) { // Interrupt the thread which should cause it to stop. - state.sessionWatchdogThread.interrupt(); + sessionState.sessionWatchdogThread.interrupt(); try { // This should always work once the thread is interrupted. - state.sessionWatchdogThread.join(); + sessionState.sessionWatchdogThread.join(); } catch (InterruptedException e) { // This should never happen. e.printStackTrace(); } } // Set the thread object to null. - state.sessionWatchdogThread = null; - } - } - + sessionState.sessionWatchdogThread = null; + } + } + + /** + * Cleanup the ET connection. + */ + synchronized void closeEtConnection() { + if (sessionState.connection != null) { + if (sessionState.connection.getEtSystem().alive()) { + sessionState.connection.cleanup(); + } + sessionState.connection = null; + } + } + + /** + * + * @return + */ + boolean isActive() { + return sessionState.processingThread.isAlive(); + } + + /** + * Connect to the ET system using the current connection settings. + */ + 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()) { + // 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. + application.connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED); + } + } + + /** + * + * @return + */ + boolean usingEtServer() { + return application.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. + */ + void createEtConnection() { + // Setup connection to ET system. + sessionState.connection = EtSystemUtil.createEtConnection(application.configurationModel); + + if (sessionState.connection != null) { + // Set status to connected as there is now a live ET connection. + application.connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED); + //logger.info("successfully connected to ET system"); + } else { + application.errorHandler.setError(new RuntimeException("Failed to create ET connection.")).log().printStackTrace().raiseException(); + } + } + + /** + * Disconnect from the current ET session with a particular status. + * @param status The connection status. + */ + void disconnect() { + + // Kill the session watch dog thread. + killWatchdogThread(); + + // Cleanup the ET connection. + closeEtConnection(); + + // Change application state to disconnected. + application.connectionModel.setConnectionStatus(ConnectionStatus.DISCONNECTED); + } + + /** + * This class notifies the application to disconnect if the event processing thread completes. + */ class SessionWatchdogThread extends Thread { Thread processingThread; @@ -317,13 +452,11 @@ processingThread.join(); // Activate a disconnect using the ActionEvent which is used by the disconnect button. - application.actionListener.actionPerformed(new ActionEvent(Thread.currentThread(), 0, Commands.DISCONNECT)); - + application.actionPerformed(new ActionEvent(Thread.currentThread(), 0, Commands.DISCONNECT)); + } catch (InterruptedException e) { - // This probably just means that the disconnect button was pushed, and this thread - // should no longer monitor the event processing. - e.printStackTrace(); - } + // This happens when the thread is interrupted by the user pressing the disconnect button. + } } } } Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java Thu Mar 5 22:53:56 2015 @@ -21,6 +21,7 @@ import javax.swing.filechooser.FileFilter; import org.hps.monitoring.application.model.ConfigurationModel; +import org.hps.monitoring.application.model.SteeringType; import org.hps.monitoring.application.util.ResourceUtil; import org.jdom.Document; import org.jdom.Element; Modified: 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 (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/LogTable.java Thu Mar 5 22:53:56 2015 @@ -11,7 +11,7 @@ * This is a simple Swing component for the table of log messages. * @author Jeremy McCormick <[log in to unmask]> */ -public class LogTable extends JTable { +class LogTable extends JTable { private DefaultTableModel model; static final String[] logTableColumns = { "Date", "Level", "Message" }; Copied: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/Main.java (from r2271, java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/Main.java) ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/Main.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/Main.java Thu Mar 5 22:53:56 2015 @@ -1,4 +1,4 @@ -package org.hps.monitoring; +package org.hps.monitoring.application; import java.io.File; @@ -9,15 +9,17 @@ import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; -import org.hps.monitoring.application.MonitoringApplication; import org.hps.monitoring.application.model.Configuration; /** * This is the front-end for running the monitoring app via a {@link #main(String[])} method. */ -public class Main { +public final class Main { + private Main() { + } + public static void main(String[] args) { // Set up command line parsing. @@ -49,4 +51,4 @@ MonitoringApplication.create(configuration); } -} +} Modified: 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 (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MenuBar.java Thu Mar 5 22:53:56 2015 @@ -1,35 +1,70 @@ package org.hps.monitoring.application; import static org.hps.monitoring.application.Commands.EXIT; -import static org.hps.monitoring.application.Commands.OPEN_FILE; +import static org.hps.monitoring.application.Commands.FILE_CLOSE; +import static org.hps.monitoring.application.Commands.FILE_OPEN; +import static org.hps.monitoring.application.Commands.PLOTS_CLEAR; import static org.hps.monitoring.application.Commands.PLOTS_SAVE; -import static org.hps.monitoring.application.Commands.PLOTS_CLEAR; import static org.hps.monitoring.application.Commands.SETTINGS_LOAD; import static org.hps.monitoring.application.Commands.SETTINGS_LOAD_DEFAULT; import static org.hps.monitoring.application.Commands.SETTINGS_SAVE; import static org.hps.monitoring.application.Commands.SETTINGS_SHOW; - +import static org.hps.monitoring.application.Commands.WINDOW_DEFAULTS; +import static org.hps.monitoring.application.Commands.WINDOW_MAXIMIZE; +import static org.hps.monitoring.application.Commands.WINDOW_MINIMIZE; + +import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; -public class MenuBar extends JMenuBar { - - MenuBar(ActionListener listener) { +import org.hps.monitoring.application.model.ConfigurationModel; +import org.hps.monitoring.application.model.ConnectionStatus; +import org.hps.monitoring.application.model.ConnectionStatusModel; +import org.hps.record.enums.DataSourceType; + +/** + * This is the primary menu bar for the monitoring application. + * + * @author Jeremy McCormick <[log in to unmask]> + */ +class MenuBar extends JMenuBar implements PropertyChangeListener, ActionListener { + + JMenuItem closeFileItem; + JMenuItem openFileItem; + JMenu settingsMenu; + ConfigurationModel configurationModel; + + MenuBar(ConfigurationModel configurationModel, ConnectionStatusModel connectionModel, ActionListener listener) { + + // Do not need to listen for changes on this model. + this.configurationModel = configurationModel; + + // Need to listen for connection status changes. + connectionModel.addPropertyChangeListener(this); JMenu fileMenu = new JMenu("File"); fileMenu.setMnemonic(KeyEvent.VK_F); add(fileMenu); - JMenuItem openFileItem = new JMenuItem("Open File ..."); + openFileItem = new JMenuItem("Open File ..."); openFileItem.setMnemonic(KeyEvent.VK_P); - openFileItem.setActionCommand(OPEN_FILE); + openFileItem.setActionCommand(FILE_OPEN); openFileItem.addActionListener(listener); openFileItem.setToolTipText("Open an EVIO or LCIO data file"); fileMenu.add(openFileItem); + + closeFileItem = new JMenuItem("Close File"); + closeFileItem.setMnemonic(KeyEvent.VK_C); + closeFileItem.setActionCommand(FILE_CLOSE); + closeFileItem.addActionListener(listener); + closeFileItem.setToolTipText("Close the current file data source"); + fileMenu.add(closeFileItem); JMenuItem exitItem = new JMenuItem("Exit"); exitItem.setMnemonic(KeyEvent.VK_X); @@ -38,11 +73,11 @@ exitItem.setToolTipText("Exit from the application"); fileMenu.add(exitItem); - JMenu settingsMenu = new JMenu("Settings"); + settingsMenu = new JMenu("Settings"); settingsMenu.setMnemonic(KeyEvent.VK_S); add(settingsMenu); - JMenuItem settingsItem = new JMenuItem("Open Settings Dialog ..."); + JMenuItem settingsItem = new JMenuItem("Open Settings Window ..."); settingsItem.setMnemonic(KeyEvent.VK_O); settingsItem.setActionCommand(SETTINGS_SHOW); settingsItem.addActionListener(listener); @@ -89,6 +124,34 @@ clearPlotsItem.setEnabled(true); clearPlotsItem.setToolTipText("Clear the AIDA plots"); plotsMenu.add(clearPlotsItem); + + JMenu windowMenu = new JMenu("Window"); + windowMenu.setMnemonic(KeyEvent.VK_W); + add(windowMenu); + + JMenuItem maximizeItem = new JMenuItem("Maximize"); + maximizeItem.setMnemonic(KeyEvent.VK_M); + maximizeItem.setActionCommand(WINDOW_MAXIMIZE); + maximizeItem.addActionListener(listener); + maximizeItem.setEnabled(true); + maximizeItem.setToolTipText("Maximize the application window"); + windowMenu.add(maximizeItem); + + JMenuItem minimizeItem = new JMenuItem("Minimize"); + minimizeItem.setMnemonic(KeyEvent.VK_I); + minimizeItem.setActionCommand(WINDOW_MINIMIZE); + minimizeItem.addActionListener(listener); + minimizeItem.setEnabled(true); + minimizeItem.setToolTipText("Minimize the application window"); + windowMenu.add(minimizeItem); + + JMenuItem defaultsItem = new JMenuItem("Restore Defaults"); + defaultsItem.setMnemonic(KeyEvent.VK_D); + defaultsItem.setActionCommand(WINDOW_DEFAULTS); + defaultsItem.addActionListener(listener); + defaultsItem.setEnabled(true); + defaultsItem.setToolTipText("Restore the window defaults"); + windowMenu.add(defaultsItem); /* @@ -138,5 +201,26 @@ utilMenu.add(screenshotItem); */ } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals(ConnectionStatusModel.CONNECTION_STATUS_PROPERTY)) { + ConnectionStatus status = (ConnectionStatus) evt.getNewValue(); + boolean connected = status.equals(ConnectionStatus.CONNECTED); + closeFileItem.setEnabled(!connected); + openFileItem.setEnabled(!connected); + } + } + + @Override + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals(Commands.DATA_SOURCE_CHANGED)) { + if (!configurationModel.getDataSourceType().equals(DataSourceType.ET_SERVER)) { + closeFileItem.setEnabled(true); + } else { + closeFileItem.setEnabled(false); + } + } + } } Modified: 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 (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringApplication.java Thu Mar 5 22:53:56 2015 @@ -1,5 +1,23 @@ package org.hps.monitoring.application; +import static org.hps.monitoring.application.Commands.CONNECT; +import static org.hps.monitoring.application.Commands.DATA_SOURCE_CHANGED; +import static org.hps.monitoring.application.Commands.DISCONNECT; +import static org.hps.monitoring.application.Commands.EXIT; +import static org.hps.monitoring.application.Commands.FILE_CLOSE; +import static org.hps.monitoring.application.Commands.FILE_OPEN; +import static org.hps.monitoring.application.Commands.NEXT; +import static org.hps.monitoring.application.Commands.PAUSE; +import static org.hps.monitoring.application.Commands.PLOTS_CLEAR; +import static org.hps.monitoring.application.Commands.PLOTS_SAVE; +import static org.hps.monitoring.application.Commands.RESUME; +import static org.hps.monitoring.application.Commands.SETTINGS_LOAD; +import static org.hps.monitoring.application.Commands.SETTINGS_LOAD_DEFAULT; +import static org.hps.monitoring.application.Commands.SETTINGS_SAVE; +import static org.hps.monitoring.application.Commands.SETTINGS_SHOW; +import static org.hps.monitoring.application.Commands.WINDOW_DEFAULTS; +import static org.hps.monitoring.application.Commands.WINDOW_MAXIMIZE; +import static org.hps.monitoring.application.Commands.WINDOW_MINIMIZE; import hep.aida.jfree.AnalysisFactory; import hep.aida.jfree.plotter.PlotterRegion; import hep.aida.jfree.plotter.PlotterRegionListener; @@ -8,6 +26,7 @@ import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -16,13 +35,20 @@ import java.util.logging.LogRecord; import java.util.logging.Logger; -import org.hps.monitoring.application.RunPanel.RunPanelUpdater; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.filechooser.FileFilter; +import javax.swing.filechooser.FileNameExtensionFilter; + +import org.hps.monitoring.application.DataSourceComboBox.DataSourceItem; import org.hps.monitoring.application.model.Configuration; import org.hps.monitoring.application.model.ConfigurationModel; import org.hps.monitoring.application.model.ConnectionStatusModel; import org.hps.monitoring.application.model.RunModel; +import org.hps.monitoring.application.util.DialogUtil; import org.hps.monitoring.application.util.ErrorHandler; -import org.hps.monitoring.application.util.EtSystemUtil; +import org.hps.monitoring.application.util.EvioFileFilter; import org.hps.monitoring.plotting.MonitoringAnalysisFactory; import org.hps.monitoring.plotting.MonitoringPlotFactory; import org.hps.monitoring.subsys.StatusCode; @@ -34,36 +60,49 @@ import org.lcsim.util.aida.AIDA; /** + * This is the primary class that implements the monitoring GUI application. + * It should not be used directly. Instead the {@link Main} class should be + * used from the command line or via the supplied script built automatically + * by Maven. * * @author Jeremy McCormick <[log in to unmask]> - * */ -public class MonitoringApplication implements PropertyChangeListener, SystemStatusListener { - - static Logger logger; +final class MonitoringApplication implements ActionListener, PropertyChangeListener, SystemStatusListener { + + // Setup application logging. + static final Logger logger; static { logger = Logger.getLogger(MonitoringApplication.class.getSimpleName()); } Handler logHandler; - ErrorHandler errorHandler; + // Application error handling. + final ErrorHandler errorHandler; - MonitoringApplicationFrame frame; - ActionListener actionListener = new MonitoringApplicationActionListener(this); - - RunModel runModel = new RunModel(); - ConfigurationModel configurationModel = new ConfigurationModel(); - ConnectionStatusModel connectionModel = new ConnectionStatusModel(); - - SessionState sessionState; + // The main GUI components inside a JFrame. + final MonitoringApplicationFrame frame; + + // The primary data models. + final RunModel runModel = new RunModel(); + final ConfigurationModel configurationModel = new ConfigurationModel(); + final ConnectionStatusModel connectionModel = new ConnectionStatusModel(); + + // The global configuration settings. + Configuration configuration; + + // The default configuration resource embedded in the jar. + static final String DEFAULT_CONFIGURATION = "/org/hps/monitoring/config/default_config.prop"; + + // Encapsulation of ET connection and event processing. EventProcessing processing; - - // The default configuration resource. - static final String DEFAULT_CONFIGURATION = "/org/hps/monitoring/config/default_config.prop"; - - // The application's global Configuration settings. - Configuration configuration; - + + // Filters for opening files. + static final FileFilter lcioFilter = new FileNameExtensionFilter("LCIO files", "slcio"); + static final EvioFileFilter evioFilter = new EvioFileFilter(); + + /** + * Default log handler. + */ class LogHandler extends Handler { /** @@ -80,176 +119,198 @@ } } + /** + * Instantiate and show the monitoring application with the given configuration. + * @param configuration The Configuration object containing application settings. + */ MonitoringApplication(Configuration configuration) { + + // Setup the main GUI component. + frame = new MonitoringApplicationFrame(this); // Setup the error handler. errorHandler = new ErrorHandler(frame, logger); - - // Setup the main GUI component. - frame = new MonitoringApplicationFrame(this); - + // Add this class as a listener on the configuration model. configurationModel.addPropertyChangeListener(this); // Setup the logger. setupLogger(); - + // Setup AIDA plotting and connect it to the GUI. setupAida(); // Set the configuration. if (configuration != null) { - // User specified configuration. + // There was a user specified configuration. this.configuration = configuration; } else { - // Use the default configuration resource. + // Use the default configuration. this.configuration = new Configuration(DEFAULT_CONFIGURATION); } // Load the configuration. loadConfiguration(this.configuration); - } - + + // Setup the data source combo box. + frame.dataSourceComboBox.initialize(); + + logger.info("initialized successfully"); + } + + /** + * Static utility method for creating new instance. + * @param configuration The application settings. + * @return The new monitoring application instance. + */ + static MonitoringApplication create(Configuration configuration) { + return new MonitoringApplication(configuration); + } + + /** + * Handle property changes. + * @param evt The property change event. + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + // TODO: Handle log level configuration change here. + } + + /** + * The primary action handler for the application. + * @param e The ActionEvent to handle. + */ + public void actionPerformed(ActionEvent e) { + + String cmd = e.getActionCommand(); + if (CONNECT.equals(cmd)) { + // Run the start session method on a separate thread. + new Thread() { + public void run() { + startSession(); + } + }.start(); + } else if (DISCONNECT.equals(cmd)) { + // Run the stop session method on a separate thread. + new Thread() { + public void run() { + stopSession(); + } + }.start(); + } else if (PLOTS_SAVE.equals(cmd)) { + savePlots(); + } else if (EXIT.equals(cmd)) { + exit(); + } else if (PAUSE.equals(cmd)) { + processing.pause(); + } else if (NEXT.equals(cmd)) { + processing.next(); + } else if (RESUME.equals(cmd)) { + processing.resume(); + } else if (SETTINGS_SHOW.equals(cmd)) { + showSettingsDialog(); + } else if (SETTINGS_LOAD.equals(cmd)) { + loadSettings(); + } else if (SETTINGS_SAVE.equals(cmd)) { + saveSettings(); + } else if (PLOTS_CLEAR.equals(cmd)) { + clearPlots(); + } else if (SETTINGS_LOAD_DEFAULT.equals(cmd)) { + loadDefaultSettings(); + } else if (FILE_OPEN.equals(cmd)) { + openFile(); + } else if (WINDOW_DEFAULTS.equals(cmd)) { + restoreDefaultWindow(); + } else if (WINDOW_MAXIMIZE.equals(cmd)) { + maximizeWindow(); + } else if (WINDOW_MINIMIZE.equals(cmd)) { + minimizeWindow(); + } else if (FILE_CLOSE.equals(cmd)) { + closeFile(); + } + + /*else if (CHOOSE_LOG_FILE.equals(cmd)) { + //chooseLogFile(); + } else if (LOG_TO_TERMINAL.equals(cmd)) { + //logToTerminal(); + } else if (SCREENSHOT.equals(cmd)) { + //chooseScreenshot(); + } else if (SAVE_LOG_TABLE.equals(cmd)) { + //saveLogTableToFile(); + } else if (CLEAR_LOG_TABLE.equals(cmd)) { + //clearLogTable(); + } else if (LOG_LEVEL_CHANGED.equals(cmd)) { + //setLogLevel(); + } else if (VALIDATE_DATA_FILE.equals(cmd)) { + //if (fileValidationThread == null) { + // new FileValidationThread().start(); + //} + } + */ + } + + /** + * Setup AIDA plotting into the GUI components. + */ void setupAida() { + // Register the factory for display plots in tabs. MonitoringAnalysisFactory.register(); + + // Set the root tab pane for displaying plots. MonitoringPlotFactory.setRootPane(frame.plotPanel.getPlotPane()); + + // Setup the region listener to connect the plot info window. MonitoringPlotFactory.setPlotterRegionListener(new PlotterRegionListener() { @Override public void regionSelected(PlotterRegion region) { - if (region == null) - throw new RuntimeException("The region arg is null!!!"); - frame.plotInfoPanel.setCurrentRegion(region); + if (region != null) { + frame.plotInfoPanel.setCurrentRegion(region); + } } }); + + // Perform global configuration of the JFreeChart back end. AnalysisFactory.configure(); } + /** + * Setup the logger. + */ void setupLogger() { 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_CONFIGURATION)); - } - - @Override - public void propertyChange(PropertyChangeEvent evt) { - // TODO Auto-generated method stub - } - + logger.setLevel(Level.ALL); + logger.info("logging initialized"); + } + + /** + * This method sets the configuration on the model, which fires a change for every property. + * @param configuration The new configuration. + */ void loadConfiguration(Configuration configuration) { - // 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()); - } - - - /** - * Connect to the ET system using the current connection settings. - */ - 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()) { - // 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. - connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED); - } - } - - /** - * - * @return - */ - 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. - */ - 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. - connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED); - - //logger.info("successfully connected to ET system"); - - } else { - errorHandler.setError(new RuntimeException("Failed to create ET connection.")).log().printStackTrace().raiseException(); - } - } - + if (configuration.getFile() != null) + logger.config("loaded configuration from file: " + configuration.getFile().getPath()); + else + logger.config("loaded configuration from resource: " + configuration.getResourcePath()); + } + + /** + * Reset the plots and clear the tabs in the plot window. + */ void resetPlots() { // Clear the static AIDA tree in case plots are hanging around from previous sessions. AIDA.defaultInstance().clearAll(); - // Reset plots. + // Reset plot panel which removes all tabs. frame.plotPanel.reset(); - } - - - /** - * Disconnect from the current ET session with a particular status. - * @param status The connection status. - */ - void disconnect() { - - //logger.fine("Disconnecting the current session."); - - // Cleanup the ET connection. - cleanupEtConnection(); - - // Change application state to disconnected. - connectionModel.setConnectionStatus(ConnectionStatus.DISCONNECTED); - - //logger.info("Disconnected from the session."); - } - - /** - * Cleanup the ET connection. - */ - void cleanupEtConnection() { - if (sessionState != null) { - if (sessionState.connection != null) { - if (sessionState.connection.getEtSystem().alive()) { - sessionState.connection.cleanup(); - } - sessionState.connection = null; - } - } - } - + + logger.info("plots were cleared"); + } + /** * Configure the system status monitor panel for a new job. */ @@ -268,6 +329,8 @@ // Add this class as a listener so all status changes can be logged. systemStatus.addListener(this); } + + logger.info("system status monitor initialized successfully"); } /** @@ -285,23 +348,22 @@ } // Log all status changes. - //logger.log(level, "STATUS, " + "subsys: " + status.getSubsystem() + ", " - // + "code: " + status.getStatusCode().name() - // + ", " + "descr: " + status.getDescription() - // + ", " + "mesg: " + status.getMessage()); - } - - /** - * 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. + logger.log(level, "STATUS, " + "subsys: " + status.getSubsystem() + ", " + + "code: " + status.getStatusCode().name() + + ", " + "descr: " + status.getDescription() + + ", " + "mesg: " + status.getMessage()); + } + + /** + * <p> + * Start a new monitoring session. + * <p> + * This method is executed in a separate thread from the EDT within {@link #actionPerformed(ActionEvent)} + * so that 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 ..."); + + logger.info("starting new session"); try { @@ -313,78 +375,229 @@ // e.g. an LCSim Driver, etc. SystemStatusRegistry.getSystemStatusRegistery().clear(); - // Setup event processing. - sessionState = new SessionState(); + // List of extra composite record processors including the updater for the RunPanel. List<CompositeRecordProcessor> processors = new ArrayList<CompositeRecordProcessor>(); processors.add(frame.runPanel.new RunPanelUpdater()); + + // Initialize event processing with the list of processors and reference to the application. processing = new EventProcessing(this, processors); + + // Configure event processing from the global application settings. + logger.info("setting up event processing on source " + configurationModel.getDataSourcePath() + + " with type " + configurationModel.getDataSourceType()); processing.setup(configurationModel); // Setup the system status monitor table. setupSystemStatusMonitor(); - // Connect to the ET system. - connect(); - - // Start event processing. - processing.start(); - - //logger.info("successfully started the monitoring session"); + // Connect to the ET system, if applicable. + processing.connect(); + + // Start the event processing thread. + processing.start(); + + logger.info("new session successfully initialized"); } 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. - // FIXME: This should never be needed as connected should only be set at end w/o errors. - disconnect(); - - } finally { - // Close modal window. - //dialog.dispatchEvent(new WindowEvent(dialog, WindowEvent.WINDOW_CLOSING)); - } - } - - /** - * Stop the session by killing the event processing thread, ending the job, and disconnecting - * from the ET system. + // Disconnect from the ET system. + processing.disconnect(); + + // Log the error that occurred and show a pop up dialog. + errorHandler.setError(e).log().printStackTrace().showErrorDialog("There was an error while starting the session." + + '\n' + "See the log for details.", "Session Error"); + + logger.severe("failed to start new session"); + } + } + + /** + * Stop the session by disconnecting from the ET system and stopping the event processing. */ void stopSession() { - // Show a modal message window while this method executes. - //JDialog dialog = DialogUtil.showStatusDialog(this, "Info", "Disconnecting from session ..."); - - try { - // Log message. - //logger.log(Level.FINER, "stopping the session"); - - // Kill the watchdog thread which looks for disconnects, if it is active. - processing.killWatchdogThread(); - - // Disconnect from ET system, if using the ET server, and set the proper disconnected - // GUI state. - disconnect(); - - // Stop the event processing, which is called after the ET system goes down to avoid - // hanging in calls to ET system. - processing.stop(); - - //logger.log(Level.INFO, "session was stopped"); - - } finally { - // Close modal message window. - //dialog.dispatchEvent(new WindowEvent(dialog, WindowEvent.WINDOW_CLOSING)); - } + + logger.info("stopping the session"); + + // Disconnect from ET system, if using the ET server, and set the proper disconnected GUI state. + processing.disconnect(); + + // Stop the event processing, which is called after the ET system goes down to avoid hanging in calls to ET system. + processing.stop(); + + logger.info("session was stopped"); } /** * Exit from the application. */ - void exit() { - cleanupEtConnection(); + void exit() { + // Cleanup ET system if necessary. + if (processing != null && processing.isActive()) { + logger.info("killing active ET connection"); + processing.closeEtConnection(); + } frame.setVisible(false); + logger.info("exiting the application"); + logger.getHandlers()[0].flush(); System.exit(0); } + + /** + * Save AIDA plots to a file using a file chooser. + */ + void savePlots() { + JFileChooser fc = new JFileChooser(); + int r = fc.showSaveDialog(frame); + if (r == JFileChooser.APPROVE_OPTION) { + File fileName = fc.getSelectedFile(); + try { + AIDA.defaultInstance().saveAs(fileName); + logger.info("saved plots to file: " + fileName); + DialogUtil.showInfoDialog(frame, + "Plots Saved", + "Plots were successfully saved to AIDA file."); + } catch (IOException e) { + errorHandler.setError(e).setMessage("Error Saving Plots").printStackTrace().log().showErrorDialog(); + } + } + } + + /** + * Clear the current set of AIDA plots in the default data tree. + */ + void clearPlots() { + int confirmation = DialogUtil.showConfirmationDialog(frame, + "Are you sure you want to clear the plots", "Clear Plots Confirmation"); + if (confirmation == JOptionPane.YES_OPTION) { + AIDA.defaultInstance().clearAll(); + DialogUtil.showInfoDialog(frame, + "Plots Clear", + "The AIDA plots were cleared."); + } + logger.info("plots were cleared"); + } + + /** + * Load default application settings. + */ + void loadDefaultSettings() { + configuration = new Configuration(MonitoringApplication.DEFAULT_CONFIGURATION); + configurationModel.setConfiguration(configuration); + DialogUtil.showInfoDialog(frame, + "Default Configuration Loaded", + "The default configuration was loaded."); + logger.config("default settings loaded"); + } + + /** + * Show the settings dialog window. + */ + void showSettingsDialog() { + frame.settingsDialog.setVisible(true); + } + + /** + * Open a file data source using a <code>JFileChooser</code>. + */ + void openFile() { + JFileChooser fc = new JFileChooser(System.getProperty("user.dir")); + fc.setAcceptAllFileFilterUsed(false); + fc.addChoosableFileFilter(lcioFilter); + fc.addChoosableFileFilter(evioFilter); + fc.setDialogTitle("Select Data File"); + int r = fc.showDialog(frame, "Select ..."); + if (r == JFileChooser.APPROVE_OPTION) { + + // Set data source path. + final String filePath = fc.getSelectedFile().getPath(); + + // Set data source type. + FileFilter filter = fc.getFileFilter(); + DataSourceType type = null; + if (filter == lcioFilter) { + type = DataSourceType.LCIO_FILE; + } else if (filter == evioFilter) { + type = DataSourceType.EVIO_FILE; + } else { + // This should never happen. + throw new RuntimeException(); + } + + configurationModel.setDataSourcePath(filePath); + configurationModel.setDataSourceType(type); + + logger.config("set new data source " + filePath + " with type " + type); + } + } + + /** + * Save current settings to a file using a file chooser. + */ + void saveSettings() { + JFileChooser fc = new JFileChooser(); + fc.setDialogTitle("Save Configuration"); + fc.setCurrentDirectory(new File(".")); + int r = fc.showSaveDialog(frame); + if (r == JFileChooser.APPROVE_OPTION) { + File f = fc.getSelectedFile(); + configuration.writeToFile(f); + logger.info("saved configuration to file: " + f.getPath()); + DialogUtil.showInfoDialog(frame, + "Settings Saved", + "Settings were saved successfully."); + } + } + + /** + * Load settings from a properties file using a file chooser. + */ + void loadSettings() { + JFileChooser fc = new JFileChooser(); + fc.setDialogTitle("Load Settings"); + fc.setCurrentDirectory(new File(".")); + int r = fc.showDialog(frame, "Load ..."); + if (r == JFileChooser.APPROVE_OPTION) { + File f = fc.getSelectedFile(); + configuration = new Configuration(f); + loadConfiguration(configuration); + logger.info("loaded configuration from file: " + f.getPath()); + DialogUtil.showInfoDialog(frame, + "Settings Loaded", + "Settings were loaded successfully."); + } + } + + /** + * Maximize the application window. + */ + void maximizeWindow() { + frame.setExtendedState(JFrame.MAXIMIZED_BOTH); + } + + /** + * Minimize the application window. + */ + void minimizeWindow() { + frame.setExtendedState(JFrame.ICONIFIED); + } + + /** + * Restore the default GUI layout. + */ + void restoreDefaultWindow() { + maximizeWindow(); + frame.restoreDefaults(); + } + + /** + * Remove the currently selected file from the data source list. + */ + void closeFile() { + if (!configurationModel.getDataSourceType().equals(DataSourceType.ET_SERVER)) { + DataSourceItem item = (DataSourceItem) frame.dataSourceComboBox.getSelectedItem(); + if (item.name.equals(configurationModel.getDataSourcePath())) { + frame.dataSourceComboBox.removeItem(frame.dataSourceComboBox.getSelectedItem()); + } + } + } } Modified: 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 (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java Thu Mar 5 22:53:56 2015 @@ -7,9 +7,9 @@ import java.awt.Rectangle; import javax.swing.BoxLayout; -import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFrame; +import javax.swing.JMenuBar; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSeparator; @@ -17,9 +17,8 @@ import javax.swing.JTabbedPane; import javax.swing.SwingConstants; -import org.hps.monitoring.application.DataSourceComboBox.DataSourceItem; - /** + * This class instantiates the primary GUI components of the monitoring application. * * @author Jeremy McCormick <[log in to unmask]> */ @@ -31,6 +30,12 @@ LogTable logTable; SystemStatusTable systemStatusTable; JPanel buttonsPanel; + + JSplitPane mainSplitPane; + JSplitPane rightSplitPane; + JSplitPane leftSplitPane; + + DataSourceComboBox dataSourceComboBox; SettingsDialog settingsDialog; @@ -72,7 +77,7 @@ topPanel.add(sep); // Create the buttons panel. - buttonsPanel = new EventButtonsPanel(application.connectionModel, application.actionListener); + buttonsPanel = new EventButtonsPanel(application.connectionModel, application); topPanel.add(buttonsPanel); // Add vertical separator. @@ -81,11 +86,7 @@ topPanel.add(sep); // Add the data source combo box. - JComboBox<DataSourceItem> dataSourceComboBox = - new DataSourceComboBox( - application.configurationModel, - application.connectionModel, - application.actionListener); + dataSourceComboBox = new DataSourceComboBox(application.configurationModel, application.connectionModel); topPanel.add(dataSourceComboBox); // Create the bottom panel. @@ -107,14 +108,14 @@ // Create the log table and add it to the tabs. logTable = new LogTable(); - tableTabbedPane.addTab("Log", new JScrollPane(logTable)); + tableTabbedPane.addTab("Log Messages", new JScrollPane(logTable)); // Create the system monitor. 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); + leftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, runPanel, tableTabbedPane); leftPanel.add(leftSplitPane, BorderLayout.CENTER); // Create the right panel. @@ -130,17 +131,19 @@ setProportionalSize(plotPanel, RIGHT_PANEL_WIDTH, PLOT_PANEL_HEIGHT); // 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 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, plotPanel, plotInfoPanel); setProportionalSize(rightSplitPane, RIGHT_PANEL_WIDTH, FULL_SIZE); 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); + mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel); bottomPanel.add(mainSplitPane, BorderLayout.CENTER); // Create the menu bar. - setJMenuBar(new MenuBar(application.actionListener)); + MenuBar menu = new MenuBar(application.configurationModel, application.connectionModel, application); + setJMenuBar(menu); + dataSourceComboBox.addActionListener(menu); // Setup the frame now that all components have been added. pack(); @@ -148,7 +151,7 @@ setVisible(true); // Setup the settings dialog box. - settingsDialog = new SettingsDialog(application.configurationModel, application.actionListener); + settingsDialog = new SettingsDialog(application.configurationModel, application); } /** @@ -171,4 +174,10 @@ Dimension scaledDimension = new Dimension((int)(bounds.getWidth() * scaleX), (int)(bounds.getHeight() * scaleY)); component.setPreferredSize(scaledDimension); } + + void restoreDefaults() { + mainSplitPane.resetToPreferredSizes(); + leftSplitPane.resetToPreferredSizes(); + rightSplitPane.resetToPreferredSizes(); + } } Modified: 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 (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java Thu Mar 5 22:53:56 2015 @@ -42,7 +42,7 @@ * <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 { +class PlotInfoPanel extends JPanel implements AIDAListener, ActionListener, FunctionListener { JComboBox<Object> plotComboBox; JTable infoTable = new JTable(); Modified: 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 (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/PlotPanel.java Thu Mar 5 22:53:56 2015 @@ -9,7 +9,7 @@ * This is the panel containing the monitoring plots. * @author Jeremy McCormick <[log in to unmask]> */ -public class PlotPanel extends JPanel { +class PlotPanel extends JPanel { private JTabbedPane plotPane; Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/RunPanel.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/RunPanel.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/RunPanel.java Thu Mar 5 22:53:56 2015 @@ -40,7 +40,7 @@ * Dashboard for displaying information about the current run. * @author Jeremy McCormick <[log in to unmask]> */ -public class RunPanel extends JPanel implements PropertyChangeListener { +class RunPanel extends JPanel implements PropertyChangeListener { FieldPanel runNumberField = new FieldPanel("Run Number", "", 10, false); DatePanel startDateField = new DatePanel("Run Start", "", 16, false); Modified: 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 (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SessionState.java Thu Mar 5 22:53:56 2015 @@ -6,6 +6,10 @@ import org.hps.record.composite.EventProcessingThread; import org.hps.record.et.EtConnection; +/** + * This is the session state for job processing. + * @author Jeremy McCormick <[log in to unmask]> + */ class SessionState { JobManager jobManager; LCSimEventBuilder eventBuilder; Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SettingsDialog.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SettingsDialog.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SettingsDialog.java Thu Mar 5 22:53:56 2015 @@ -12,7 +12,7 @@ * The modal dialog for entering settings. It contains a <code>JPanel</code> with the different * settings sub-tabs. */ -public class SettingsDialog extends JDialog { +class SettingsDialog extends JDialog { final SettingsPanel settingsPanel; Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SettingsPanel.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SettingsPanel.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SettingsPanel.java Thu Mar 5 22:53:56 2015 @@ -17,7 +17,7 @@ /** * The container component with the tabs that have job and connection settings. */ -public class SettingsPanel extends JPanel implements ActionListener { +class SettingsPanel extends JPanel implements ActionListener { JTabbedPane tabs; JobSettingsPanel jobPanel; Modified: 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 (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SystemStatusTable.java Thu Mar 5 22:53:56 2015 @@ -1,11 +1,6 @@ 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 static org.hps.monitoring.application.model.SystemStatusTableModel.*; import java.awt.Color; import java.awt.Component; Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java Thu Mar 5 22:53:56 2015 @@ -3,7 +3,6 @@ import java.io.File; import java.util.logging.Level; -import org.hps.monitoring.application.SteeringType; import org.hps.record.enums.DataSourceType; import org.hps.record.enums.ProcessingStage; import org.jlab.coda.et.enums.Mode; @@ -15,7 +14,7 @@ public final class ConfigurationModel extends AbstractModel { Configuration configuration; - + // Job setting properties. public static final String DETECTOR_NAME_PROPERTY = "DetectorName"; public static final String DETECTOR_ALIAS_PROPERTY = "DetectorAlias"; @@ -375,6 +374,10 @@ public Long getMaxEvents() { return configuration.getLong(MAX_EVENTS_PROPERTY); } + + public String getEtPath() { + return getEtName() + "@" + getHost() + ":" + getPort(); + } public void remove(String property) { if (hasPropertyKey(property)) { @@ -397,5 +400,5 @@ @Override public String[] getPropertyNames() { return CONFIG_PROPERTIES; - } + } } Copied: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java (from r2271, java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/ConnectionStatus.java) ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/ConnectionStatus.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java Thu Mar 5 22:53:56 2015 @@ -1,9 +1,11 @@ -package org.hps.monitoring.application; +package org.hps.monitoring.application.model; import java.awt.Color; /** - * Status of the connection to the ET server from the monitoring client. + * This is the status of the connection to the ET server from the monitoring client, + * and it includes a color that should be displayed in the GUI for the associated + * text. */ public enum ConnectionStatus { @@ -16,7 +18,7 @@ this.color = color; } - Color getColor() { + public Color getColor() { return color; } } Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java Thu Mar 5 22:53:56 2015 @@ -2,8 +2,6 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; - -import org.hps.monitoring.application.ConnectionStatus; /** * This model updates listeners when the connection status changes from disconnected @@ -12,7 +10,7 @@ * * @author Jeremy McCormick <[log in to unmask]> */ -public class ConnectionStatusModel extends AbstractModel { +public final class ConnectionStatusModel extends AbstractModel { public static final String CONNECTION_STATUS_PROPERTY = "ConnectionStatus"; public static final String PAUSED_PROPERTY = "Paused"; @@ -46,7 +44,6 @@ } public void setPaused(boolean paused) { - System.out.println("ConnectionStatusModel.setPause - " + paused); boolean oldValue = this.paused; this.paused = paused; for (PropertyChangeListener listener : propertyChangeSupport.getPropertyChangeListeners()) { Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/HasConfigurationModel.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/HasConfigurationModel.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/HasConfigurationModel.java Thu Mar 5 22:53:56 2015 @@ -1,7 +1,7 @@ package org.hps.monitoring.application.model; /** - * Mixin interface for classes that have an associated {@link ConfigurationModel}. + * Mix-in interface for classes that have an associated {@link ConfigurationModel}. */ public interface HasConfigurationModel { Copied: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/SteeringType.java (from r2271, java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SteeringType.java) ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/SteeringType.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/SteeringType.java Thu Mar 5 22:53:56 2015 @@ -1,4 +1,4 @@ -package org.hps.monitoring.application; +package org.hps.monitoring.application.model; /** * The type of steering to use for event processing. Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/SystemStatusTableModel.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/SystemStatusTableModel.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/SystemStatusTableModel.java Thu Mar 5 22:53:56 2015 @@ -15,8 +15,7 @@ import org.hps.monitoring.subsys.SystemStatusListener; /** - * A <code>JTableModel</code> that has a list of {@link org.hps.monitoring.subsys.SystemStatus} - * objects. + * A <code>JTableModel</code> that has a list of {@link org.hps.monitoring.subsys.SystemStatus} objects. */ public final class SystemStatusTableModel extends AbstractTableModel implements SystemStatusListener { @@ -123,7 +122,7 @@ @Override public void statusChanged(SystemStatus status) { int rowNumber = statuses.indexOf(status); - this.fireTableRowsUpdated(rowNumber, rowNumber); + fireTableRowsUpdated(rowNumber, rowNumber); } public void clear() { Copied: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/package-info.java (from r2271, java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/package-info.java) ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/package-info.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/package-info.java Thu Mar 5 22:53:56 2015 @@ -22,4 +22,4 @@ * </p> * @author Jeremy McCormick <[log in to unmask]> */ -package org.hps.monitoring; +package org.hps.monitoring.application; Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/util/ErrorHandler.java ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/util/ErrorHandler.java (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/util/ErrorHandler.java Thu Mar 5 22:53:56 2015 @@ -102,6 +102,20 @@ SwingUtilities.invokeLater(runnable); return this; } + + /** + * Show an error dialog with a custom message and title. + * @return This object. + */ + public ErrorHandler showErrorDialog(final String message, final String title) { + final Runnable runnable = new Runnable() { + public void run() { + JOptionPane.showMessageDialog(component, message, title, JOptionPane.ERROR_MESSAGE); + } + }; + SwingUtilities.invokeLater(runnable); + return this; + } /** * Rethrow the error as a <code>RuntimeException</code>. Additional methods cannot be chained to Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/resources/org/hps/monitoring/config/default_config.prop ============================================================================= --- java/branches/monitoring-app-HPSJAVA-442/src/main/resources/org/hps/monitoring/config/default_config.prop (original) +++ java/branches/monitoring-app-HPSJAVA-442/src/main/resources/org/hps/monitoring/config/default_config.prop Thu Mar 5 22:53:56 2015 @@ -2,8 +2,6 @@ # Monitoring Application configuration # job settings -AutoSaveAida=true -AidaFileName=monitoringPlots.aida DetectorName=HPS-Proposal2014-v8-6pt6 DisconnectOnError=false DisconnectOnEndRun=true @@ -18,7 +16,7 @@ # event source DataSourceType=ET_SERVER -DataSourcePath= +#DataSourcePath= ProcessingStage=LCIO # ET connection settings