Print

Print


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