Print

Print


Author: [log in to unmask]
Date: Tue Mar  3 19:46:30 2015
New Revision: 2237

Log:
Work in progress on monitoring-app branch.

Added:
    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/DataSourceComboBox.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/model/ConnectionStatusModel.java
    java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/util/ResourceUtil.java
    java/branches/monitoring-app-HPSJAVA-442/src/main/resources/monitoringButtonGraphics/
    java/branches/monitoring-app-HPSJAVA-442/src/main/resources/monitoringButtonGraphics/connected-128.png   (with props)
    java/branches/monitoring-app-HPSJAVA-442/src/main/resources/monitoringButtonGraphics/disconnected-128.png   (with props)
Removed:
    java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/MonitoringActionListener.java
Modified:
    java/branches/monitoring-app-HPSJAVA-442/pom.xml
    java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.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/ConnectionSettingsPanel.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/ConnectionStatusPanel.java
    java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/DataSourcePanel.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/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/RunPanel.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/model/AbstractModel.java
    java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java

Modified: java/branches/monitoring-app-HPSJAVA-442/pom.xml
 =============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/pom.xml	(original)
+++ java/branches/monitoring-app-HPSJAVA-442/pom.xml	Tue Mar  3 19:46:30 2015
@@ -117,5 +117,10 @@
             <groupId>org.reflections</groupId>
             <artifactId>reflections</artifactId>
         </dependency>
+        <dependency>
+            <groupId>javax.jlfgr</groupId>
+            <artifactId>jlfgr</artifactId>
+            <version>1.0</version>
+        </dependency>
     </dependencies>
 </project>

Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java
 =============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java	(original)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java	Tue Mar  3 19:46:30 2015
@@ -1,22 +1,22 @@
 package org.hps.monitoring.application;
 
 import java.awt.Color;
-import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.GridBagConstraints;
 import java.awt.Insets;
 import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
 import javax.swing.JComboBox;
 import javax.swing.JFormattedTextField;
-import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JTextField;
 
+import org.hps.monitoring.application.model.ConfigurationModel;
 import org.hps.monitoring.application.model.HasConfigurationModel;
 
 /**
@@ -25,18 +25,20 @@
  * for layout.
  */
 // TODO: This should use features of JFormattedTextField instead of plain JTextField.
-abstract class AbstractFieldsPanel extends JPanel implements PropertyChangeListener, HasConfigurationModel, ActionListener {
+abstract class AbstractFieldsPanel extends JPanel implements PropertyChangeListener, HasConfigurationModel, ActionListener, AddActionListener {
 
     private int currY = 0;
     private Insets insets;
     private boolean editable = false;
+    
+    protected ConfigurationModel configurationModel;
 
     /**
      * Class constructor.
      * @param insets The insets for the panel.
      * @param editable Editable setting.
      */
-    AbstractFieldsPanel(Insets insets, boolean editable) {
+    protected AbstractFieldsPanel(Insets insets, boolean editable) {
         this.insets = insets;
         this.editable = editable;
     }
@@ -44,7 +46,7 @@
     /**
      * Class constructor.
      */
-    AbstractFieldsPanel() {
+    protected AbstractFieldsPanel() {
         this.insets = new Insets(1, 1, 1, 1);
     }
 
@@ -255,6 +257,36 @@
      * sub-components should attach this to individual components.
      * @param listener The AcitonListener to add.
      */
-    void addActionListener(ActionListener listener) {
-    }
+    @Override
+    public void addActionListener(ActionListener listener) {
+        // Sub-classes should add the listener to the appropriate child components.
+    }
+    
+    /**
+     * Sub-classes should override this method to add their own listeners to update from the model.
+     */
+    @Override
+    public void setConfigurationModel(ConfigurationModel model) {
+        this.configurationModel = model;
+        
+        // This listener is used to push GUI values into the model.
+        this.configurationModel.addPropertyChangeListener(this);
+    }        
+    
+    @Override
+    public ConfigurationModel getConfigurationModel() {
+        return configurationModel;
+    }
+    
+    boolean accept(PropertyChangeEvent evt) {
+        if (evt.getPropertyName().equals("ancestor")) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+    
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {        
+    }    
 }

Added: 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	(added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/AddActionListener.java	Tue Mar  3 19:46:30 2015
@@ -0,0 +1,8 @@
+package org.hps.monitoring.application;
+
+import java.awt.event.ActionListener;
+
+public 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	Tue Mar  3 19:46:30 2015
@@ -6,12 +6,21 @@
  */
 public 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 AIDA_AUTO_SAVE = "aidaAutoSave";
     static final String AIDA_AUTO_SAVE_CHANGED = "aidaAutoSaveChanged";
     static final String BLOCKING_CHANGED = "blockingChanged";
     static final String CHOOSE_COMPACT_FILE = "chooseCompactFile";
     static final String CHOOSE_LOG_FILE = "chooseLogFile";
-    static final String CHOOSE_FILE_SOURCE = "chooseFileSource";
+    
     static final String CHOOSE_STEERING_FILE = "chooseSteeringFile";
     static final String CONNECT = "connect";
     static final String CLEAR_LOG_TABLE = "clearLogTable";
@@ -24,7 +33,7 @@
     static final String EVENT_BUILDER_CHANGED = "eventBuilderChanged";
     static final String EXIT = "exit";
     static final String FREEZE_CONDITIONS_CHANGED = "freezeConditionsChanged";
-    static final String LOAD_DEFAULT_CONFIG_FILE = "loadDefaultConfigFile";
+    
     static final String LOG_LEVEL_CHANGED = "logLevelChanged";
     static final String LOG_TO_FILE = "logToFile";
     static final String LOG_TO_FILE_CHANGED = "logToFileChanged";
@@ -35,15 +44,15 @@
     static final String RESET_PLOTS = "resetPlots";
     static final String RESTORE_DEFAULT_GUI_LAYOUT = "restoreDefaultGuiLayout";
     static final String RESUME = "resume";
-    static final String SAVE_CONFIG_FILE = "saveConfigFile";
+    
     static final String SAVE_LAYOUT = "saveLayout";
     static final String SAVE_LOG_TABLE = "saveLogTable";
     static final String SAVE_PLOTS = "savePlots";
     static final String SCREENSHOT = "screenshot";
-    static final String SELECT_CONFIG_FILE = "selectConfigFile";
+    
     static final String SELECT_LOG_FILE = "logToFile";
     static final String SET_STEERING_RESOURCE = "setSteeringResource";
-    static final String SHOW_SETTINGS = "showSettings";
+    
     static final String STEERING_TYPE_CHANGED = "steeringTypeChanged";
     static final String STEERING_RESOURCE_CHANGED = "steeringResourceChanged";
     static final String USER_RUN_NUMBER_CHANGED = "userRunNumberChanged";

Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java
 =============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java	(original)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java	Tue Mar  3 19:46:30 2015
@@ -1,11 +1,25 @@
 package org.hps.monitoring.application;
 
-import static org.hps.monitoring.application.Commands.*;
-import static org.hps.monitoring.application.model.ConfigurationModel.*;
+import static org.hps.monitoring.application.Commands.BLOCKING_CHANGED;
+import static org.hps.monitoring.application.Commands.VERBOSE_CHANGED;
+import static org.hps.monitoring.application.Commands.WAIT_MODE_CHANGED;
+import static org.hps.monitoring.application.model.ConfigurationModel.BLOCKING_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.CHUNK_SIZE_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.ET_NAME_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.HOST_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.PORT_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.PRESCALE_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.QUEUE_SIZE_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.STATION_NAME_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.STATION_POSITION_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.VERBOSE_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.WAIT_MODE_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.WAIT_TIME_PROPERTY;
 
 import java.awt.GridBagLayout;
 import java.awt.Insets;
 import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 
@@ -34,9 +48,11 @@
     private JTextField waitTimeField;
     private JTextField prescaleField;
 
-    static final String[] waitModes = { Mode.SLEEP.name(), Mode.TIMED.name(), Mode.ASYNC.name() };
-
-    ConfigurationModel configurationModel;
+    static final String[] waitModes = { 
+        Mode.SLEEP.name(), 
+        Mode.TIMED.name(), 
+        Mode.ASYNC.name() 
+    };
 
     /**
      * Class constructor.
@@ -44,7 +60,7 @@
     ConnectionSettingsPanel() {
 
         super(new Insets(5, 5, 5, 5), true);
-
+                        
         setLayout(new GridBagLayout());
 
         etNameField = addField("ET Name", "", 20);
@@ -109,12 +125,19 @@
     /**
      * Updates the GUI from changes in the ConfigurationModel.
      */
-    public class ConfigurationSettingsChangeListener implements PropertyChangeListener {
+    public class ConnectionSettingsChangeListener implements PropertyChangeListener {
         @Override
         public void propertyChange(PropertyChangeEvent evt) {
 
+            System.out.println("ConnectionSettingsChangeListener.propertyChange");
+            System.out.println("  src: " + evt.getSource());
+            System.out.println("  propName: " + evt.getPropertyName());
+            System.out.println("  oldValue: " + evt.getOldValue());
+            System.out.println("  newValue: " + evt.getNewValue());
+            System.out.println("  newValue: " + evt.getPropagationId());
+            
+            //if (evt.getSource() instanceof ConfigurationModel) {
             Object value = evt.getNewValue();
-
             if (evt.getPropertyName().equals(ET_NAME_PROPERTY)) {
                 etNameField.setText((String) value);
             } else if (evt.getPropertyName().equals(HOST_PROPERTY)) {
@@ -148,30 +171,42 @@
      */
     @Override
     public void propertyChange(PropertyChangeEvent evt) {
-
-        if (evt.getPropertyName().equals("ancestor"))
+        
+        if (!accept(evt)) {
             return;
-
+        }
+        
+        System.out.println("ConnectionSettingsPanel.propertyChange");
+        System.out.println("  src: " + evt.getSource());
+        System.out.println("  propName: " + evt.getPropertyName());
+        System.out.println("  oldValue: " + evt.getOldValue());
+        System.out.println("  newValue: " + evt.getNewValue());
+        System.out.println("  propValue: " + evt.getPropagationId());
+        
         Object source = evt.getSource();
-
-        if (source.equals(etNameField)) {
-            configurationModel.setEtName(etNameField.getText());
-        } else if (source.equals(hostField)) {
-            configurationModel.setHost(hostField.getText());
-        } else if (source.equals(portField)) {
-            configurationModel.setPort(Integer.parseInt(portField.getText()));
-        } else if (source.equals(stationNameField)) {
-            configurationModel.setStationName(stationNameField.getText());
-        } else if (source.equals(chunkSizeField)) {
-            configurationModel.setChunkSize(Integer.parseInt(chunkSizeField.getText()));
-        } else if (source.equals(queueSizeField)) {
-            configurationModel.setQueueSize(Integer.parseInt(queueSizeField.getText()));
-        } else if (source.equals(stationPositionField)) {
-            configurationModel.setStationPosition(Integer.parseInt(stationPositionField.getText()));
-        } else if (source.equals(waitTimeField)) {
-            configurationModel.setWaitTime(Integer.parseInt(waitTimeField.getText()));
-        } else if (source.equals(prescaleField)) {
-            configurationModel.setPrescale(Integer.parseInt(prescaleField.getText()));
+        configurationModel.removePropertyChangeListener(this);
+        try {
+            if (source.equals(etNameField)) {
+                configurationModel.setEtName(etNameField.getText());
+            } else if (source.equals(hostField)) {
+                configurationModel.setHost(hostField.getText());
+            } else if (source.equals(portField)) {
+                configurationModel.setPort(Integer.parseInt(portField.getText()));
+            } else if (source.equals(stationNameField)) {
+                configurationModel.setStationName(stationNameField.getText());
+            } else if (source.equals(chunkSizeField)) {
+                configurationModel.setChunkSize(Integer.parseInt(chunkSizeField.getText()));
+            } else if (source.equals(queueSizeField)) {
+                configurationModel.setQueueSize(Integer.parseInt(queueSizeField.getText()));
+            } else if (source.equals(stationPositionField)) {
+                configurationModel.setStationPosition(Integer.parseInt(stationPositionField.getText()));
+            } else if (source.equals(waitTimeField)) {
+                configurationModel.setWaitTime(Integer.parseInt(waitTimeField.getText()));
+            } else if (source.equals(prescaleField)) {
+                configurationModel.setPrescale(Integer.parseInt(prescaleField.getText()));
+            }
+        } finally {
+            configurationModel.addPropertyChangeListener(this);
         }
     }
 
@@ -188,21 +223,11 @@
             configurationModel.setVerbose(verboseCheckBox.isSelected());
         }
     }
-
-    @Override
-    public void setConfigurationModel(ConfigurationModel configurationModel) {
-        // Set the ConfigurationModel reference.
-        this.configurationModel = configurationModel;
-
-        // This listener pushes GUI values into the configuration.
-        this.configurationModel.addPropertyChangeListener(this);
-
+    
+    public void setConfigurationModel(ConfigurationModel model) {
+        super.setConfigurationModel(model);
+        
         // This listener updates the GUI from changes in the configuration.
-        this.configurationModel.addPropertyChangeListener(new ConfigurationSettingsChangeListener());
-    }
-
-    @Override
-    public ConfigurationModel getConfigurationModel() {
-        return configurationModel;
+        this.configurationModel.addPropertyChangeListener(new ConnectionSettingsChangeListener());
     }
 }

Modified: 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/ConnectionStatus.java	Tue Mar  3 19:46:30 2015
@@ -1,14 +1,22 @@
 package org.hps.monitoring.application;
+
+import java.awt.Color;
 
 /**
  * Status of the connection to the ET server from the monitoring client.
  */
-// FIXME: Just change to disconnected and connected.
 public enum ConnectionStatus {
-    DISCONNECTED,
-    DISCONNECTING,
-    ERROR,
-    CONNECTION_REQUESTED,
-    CONNECTED,
-    PAUSED
+
+    DISCONNECTED(Color.RED),
+    CONNECTED(Color.GREEN);
+    
+    Color color;    
+    
+    ConnectionStatus(Color color) {
+        this.color = color;
+    }
+    
+    Color getColor() {
+        return color;
+    }
 }

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	Tue Mar  3 19:46:30 2015
@@ -6,20 +6,22 @@
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.Insets;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
 import javax.swing.JLabel;
 import javax.swing.JPanel;
-import javax.swing.JSeparator;
 import javax.swing.JTextField;
-import javax.swing.SwingConstants;
 import javax.swing.SwingUtilities;
+
+import org.hps.monitoring.application.model.ConnectionStatusModel;
 
 /**
  * This is the panel for showing the current connection status (connected, disconnected, etc.).
  */
-class ConnectionStatusPanel extends JPanel {
+class ConnectionStatusPanel extends JPanel implements PropertyChangeListener {
 
     JTextField statusField;
     JTextField dateField;
@@ -29,11 +31,16 @@
 
     private static final int PANEL_HEIGHT = 50;
     private static final int PANEL_WIDTH = 400;
+    
+    ConnectionStatusModel model;
 
     /**
      * Class constructor.
      */
-    ConnectionStatusPanel() {
+    ConnectionStatusPanel(ConnectionStatusModel model) {
+        
+        this.model = model;
+        this.model.addPropertyChangeListener(this);
 
         setMinimumSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
 
@@ -43,13 +50,6 @@
 
         GridBagConstraints c = new GridBagConstraints();
         c.weightx = c.weighty = 1.0;
-
-        // Bottom separator.
-        c.gridx = 0;
-        c.gridy = 0;
-        c.fill = GridBagConstraints.HORIZONTAL;
-        c.gridwidth = GridBagConstraints.REMAINDER;
-        add(new JSeparator(SwingConstants.HORIZONTAL), c);
 
         // Connection status label.
         c = new GridBagConstraints();
@@ -96,15 +96,6 @@
         dateField.setFont(font);
         dateField.setMinimumSize(new Dimension(200, 50));
         add(dateField, c);
-
-        // Bottom separator.
-        c = new GridBagConstraints();
-        c.gridx = 0;
-        c.gridy = 2;
-        c.fill = GridBagConstraints.HORIZONTAL;
-        c.gridwidth = GridBagConstraints.REMAINDER;
-        c.insets = new Insets(10, 0, 0, 0);
-        add(new JSeparator(SwingConstants.HORIZONTAL), c);
     }
 
     void setConnectionStatus(final ConnectionStatus status) {
@@ -115,4 +106,17 @@
             }
         });
     }
+
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {
+        if (evt.getPropertyName().equals(ConnectionStatusModel.CONNECTION_STATUS_PROPERTY)) {
+            final ConnectionStatus status = (ConnectionStatus) evt.getNewValue();
+            SwingUtilities.invokeLater(new Runnable() {
+                public void run() {
+                    statusField.setText(status.name());
+                    dateField.setText(dateFormat.format(new Date()));
+                }
+            }); 
+        }        
+    }
 }

Added: 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	(added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/DataSourceComboBox.java	Tue Mar  3 19:46:30 2015
@@ -0,0 +1,44 @@
+package org.hps.monitoring.application;
+
+import java.awt.Dimension;
+import java.awt.event.ActionListener;
+import java.io.File;
+
+import javax.swing.JComboBox;
+
+import org.hps.monitoring.application.DataSourceComboBox.DataSourceItem;
+import org.hps.record.enums.DataSourceType;
+
+/**
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ *
+ */
+public class DataSourceComboBox extends JComboBox<DataSourceItem> {
+
+    DataSourceComboBox(ActionListener listener) {
+        addActionListener(listener);
+        setPreferredSize(new Dimension(400, this.getPreferredSize().height));        
+    }
+    
+    static class DataSourceItem {
+        
+        File file;
+        String name;
+        DataSourceType type;
+        
+        DataSourceItem(String name, DataSourceType type) {
+            this.type = type;
+        }
+        
+        DataSourceItem(File file, DataSourceType type) {
+            this.file = file;
+            this.name = file.getName();
+            this.file = file;
+        }
+
+        public String toString() {
+            return name;
+        }        
+    }         
+}

Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/DataSourcePanel.java
 =============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/DataSourcePanel.java	(original)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/DataSourcePanel.java	Tue Mar  3 19:46:30 2015
@@ -1,6 +1,6 @@
 package org.hps.monitoring.application;
 
-import static org.hps.monitoring.application.Commands.CHOOSE_FILE_SOURCE;
+import static org.hps.monitoring.application.Commands.OPEN_FILE;
 import static org.hps.monitoring.application.Commands.DATA_SOURCE_TYPE_CHANGED;
 import static org.hps.monitoring.application.Commands.PROCESSING_STAGE_CHANGED;
 import static org.hps.monitoring.application.Commands.VALIDATE_DATA_FILE;
@@ -32,9 +32,17 @@
  */
 class DataSourcePanel extends AbstractFieldsPanel {
 
-    static final String[] dataSourceTypes = { DataSourceType.ET_SERVER.description(), DataSourceType.EVIO_FILE.description(), DataSourceType.LCIO_FILE.description() };
-
-    static final String[] processingStages = { ProcessingStage.ET.name(), ProcessingStage.EVIO.name(), ProcessingStage.LCIO.name() };
+    static final String[] dataSourceTypes = { 
+        DataSourceType.ET_SERVER.description(), 
+        DataSourceType.EVIO_FILE.description(), 
+        DataSourceType.LCIO_FILE.description() 
+    };
+    
+    static final String[] processingStages = { 
+        ProcessingStage.ET.name(), 
+        ProcessingStage.EVIO.name(), 
+        ProcessingStage.LCIO.name() 
+    };
 
     JComboBox<?> dataSourceTypeComboBox;
     JTextField dataSourcePathField;
@@ -42,11 +50,10 @@
     JButton validateDataFileButton;
     JComboBox<?> processingStageComboBox;
 
-    ConfigurationModel configurationModel;
-
     DataSourcePanel() {
+        
         setLayout(new GridBagLayout());
-
+        
         dataSourceTypeComboBox = addComboBox("Data Source", dataSourceTypes);
         dataSourceTypeComboBox.setSelectedIndex(0);
         dataSourceTypeComboBox.setActionCommand(DATA_SOURCE_TYPE_CHANGED);
@@ -56,7 +63,7 @@
         dataSourcePathField.addPropertyChangeListener(this);
 
         fileSourceButton = addButton("Select data file");
-        fileSourceButton.setActionCommand(CHOOSE_FILE_SOURCE);
+        fileSourceButton.setActionCommand(OPEN_FILE);
         fileSourceButton.addActionListener(this);
 
         validateDataFileButton = addButton("Validate data file");
@@ -121,38 +128,28 @@
             }
         }
     }
-
-    @Override
-    public void setConfigurationModel(ConfigurationModel configurationModel) {
-        this.configurationModel = configurationModel;
-
-        // This listener pushes GUI values into the configuration.
-        this.configurationModel.addPropertyChangeListener(this);
-
-        // This listener updates the GUI from changes in the configuration.
-        this.configurationModel.addPropertyChangeListener(new DataSourceChangeListener());
-    }
-
-    @Override
-    public ConfigurationModel getConfigurationModel() {
-        return configurationModel;
-    }
-
-    @Override
+    
+    /**
+     * 
+     * @param e
+     */
+    @Override   
     public void actionPerformed(ActionEvent e) {
-        if (DATA_SOURCE_TYPE_CHANGED.equals(e.getActionCommand())) {
-            DataSourceType dataSourceType = DataSourceType.values()[dataSourceTypeComboBox.getSelectedIndex()];
-            configurationModel.setDataSourceType(dataSourceType);
-            validateDataFileButton.setEnabled(dataSourceType.isFile());
-        } else if (PROCESSING_STAGE_CHANGED.equals(e.getActionCommand())) {
-            ProcessingStage processingStage = ProcessingStage.values()[processingStageComboBox.getSelectedIndex()];
-            configurationModel.setProcessingStage(processingStage);
-        } else if (CHOOSE_FILE_SOURCE.equals(e.getActionCommand())) {
-            chooseDataFile();
+        try {
+            configurationModel.removePropertyChangeListener(this);
+            if (DATA_SOURCE_TYPE_CHANGED.equals(e.getActionCommand())) {
+                DataSourceType dataSourceType = DataSourceType.values()[dataSourceTypeComboBox.getSelectedIndex()];
+                configurationModel.setDataSourceType(dataSourceType);
+                validateDataFileButton.setEnabled(dataSourceType.isFile());
+            } else if (PROCESSING_STAGE_CHANGED.equals(e.getActionCommand())) {
+                ProcessingStage processingStage = ProcessingStage.values()[processingStageComboBox.getSelectedIndex()];
+                configurationModel.setProcessingStage(processingStage);
+            } else if (OPEN_FILE.equals(e.getActionCommand())) {
+                chooseDataFile();
+            }
+        } finally {
+            configurationModel.addPropertyChangeListener(this);
         }
-    }
-
-    public void propertyChange(PropertyChangeEvent evt) {
     }
 
     /**
@@ -165,12 +162,17 @@
             if (evt.getPropertyName().equals("ancestor"))
                 return;
             Object value = evt.getNewValue();
-            if (DATA_SOURCE_TYPE_PROPERTY.equals(evt.getPropertyName())) {
-                dataSourceTypeComboBox.setSelectedIndex(((DataSourceType) evt.getNewValue()).ordinal());
-            } else if (DATA_SOURCE_PATH_PROPERTY.equals(evt.getPropertyName())) {
-                dataSourcePathField.setText((String) value);
-            } else if (PROCESSING_STAGE_PROPERTY.equals(evt.getPropertyName())) {
-                processingStageComboBox.setSelectedItem(value.toString());
+            configurationModel.removePropertyChangeListener(this);
+            try {
+                if (DATA_SOURCE_TYPE_PROPERTY.equals(evt.getPropertyName())) {
+                    dataSourceTypeComboBox.setSelectedIndex(((DataSourceType) evt.getNewValue()).ordinal());
+                } else if (DATA_SOURCE_PATH_PROPERTY.equals(evt.getPropertyName())) {
+                    dataSourcePathField.setText((String) value);
+                } else if (PROCESSING_STAGE_PROPERTY.equals(evt.getPropertyName())) {
+                    processingStageComboBox.setSelectedItem(value.toString());
+                }
+            } finally {
+                configurationModel.addPropertyChangeListener(this);
             }
         }
     }
@@ -179,4 +181,11 @@
         // Hook the validate button to the main app where that task actually executes.
         validateDataFileButton.addActionListener(listener);
     }
+    
+    @Override
+    public void setConfigurationModel(ConfigurationModel model) {
+        super.setConfigurationModel(model);
+        
+        model.addPropertyChangeListener(new DataSourceChangeListener());
+    }
 }

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	Tue Mar  3 19:46:30 2015
@@ -1,110 +1,111 @@
 package org.hps.monitoring.application;
 
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
+import java.awt.FlowLayout;
+import java.awt.Image;
 import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
 
+import javax.imageio.ImageIO;
+import javax.swing.ImageIcon;
 import javax.swing.JButton;
 import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+import org.hps.monitoring.application.model.ConnectionStatusModel;
 
 /**
  * This is the panel with buttons for connecting or disconnecting and controlling the app from pause
  * mode.
  */
-class EventButtonsPanel extends JPanel {
+class EventButtonsPanel extends JPanel implements PropertyChangeListener {
 
-    JButton nextEventsButton;
+    JButton nextButton;
     JButton pauseButton;
     JButton connectButton;
-
-    /**
-     * Class constructor.
-     */
-    EventButtonsPanel() {
-
-        GridBagLayout layout = new GridBagLayout();
-        setLayout(layout);
-
-        GridBagConstraints c = new GridBagConstraints();
-        c.gridx = 0;
-        c.gridy = 0;
-        c.insets = new Insets(0, 0, 0, 10);
-        connectButton = new JButton("Connect");
-        connectButton.setEnabled(true);
-        connectButton.setActionCommand(Commands.CONNECT);
-        add(connectButton, c);
-
-        c = new GridBagConstraints();
-        c.gridx = 1;
-        c.gridy = 0;
-        c.insets = new Insets(0, 0, 0, 10);
-        pauseButton = new JButton("Pause");
-        pauseButton.setActionCommand(Commands.PAUSE);
-        pauseButton.setEnabled(false);
-        add(pauseButton, c);
-
-        c = new GridBagConstraints();
-        c.gridx = 2;
-        c.gridy = 0;
-        nextEventsButton = new JButton("Next Event");
-        nextEventsButton.setEnabled(false);
-        nextEventsButton.setActionCommand(Commands.NEXT);
-        add(nextEventsButton, c);
+    JButton resumeButton;
+    
+    static final ImageIcon connectedIcon = getImageIcon("/monitoringButtonGraphics/connected-128.png");
+    static final ImageIcon disconnectedIcon = getImageIcon("/monitoringButtonGraphics/disconnected-128.png");
+    
+    EventButtonsPanel(ConnectionStatusModel connectionModel, ActionListener listener) {
+        
+        connectionModel.addPropertyChangeListener(this);
+        
+        setLayout(new FlowLayout());
+        connectButton = addButton(disconnectedIcon, Commands.CONNECT, listener, true);
+        resumeButton = addButton("/toolbarButtonGraphics/media/Play24.gif", Commands.RESUME, listener, false);
+        pauseButton = addButton("/toolbarButtonGraphics/media/Pause24.gif", Commands.PAUSE, listener, false);
+        nextButton = addButton("/toolbarButtonGraphics/media/StepForward24.gif", Commands.NEXT, listener, false);
+    }
+           
+    final JButton addButton(ImageIcon icon, String command, ActionListener listener, boolean enabled) {
+        JButton button = new JButton();
+        button.setIcon(icon);
+        button.setEnabled(enabled);
+        button.addActionListener(listener);
+        button.setActionCommand(command);
+        this.add(button);
+        return button;
+    }
+    
+    final JButton addButton(String resource, String actionCommand, ActionListener listener, boolean enabled) {
+        return addButton(getImageIcon(resource), actionCommand, listener, enabled);
+    }
+        
+    static ImageIcon getImageIcon(String resource) {
+        Image image = null;
+        try {
+            image = ImageIO.read(EventButtonsPanel.class.getResource(resource));
+            image = image.getScaledInstance(24, 24, 0);
+        } catch (IOException e) {            
+        }
+        return new ImageIcon(image);
     }
 
-    /**
-     * Set the application connection state.
-     * @param connected True if application is connected or false if disconnected.
-     */
-    void setConnected(boolean connected) {
-        if (connected) {
-            connectButton.setText("Disconnect");
-            connectButton.setActionCommand(Commands.DISCONNECT);
-        } else {
-            connectButton.setText("Connect");
-            connectButton.setActionCommand(Commands.CONNECT);
+    @Override
+    public void propertyChange(final PropertyChangeEvent evt) {
+        if (evt.getPropertyName().equals(ConnectionStatusModel.CONNECTION_STATUS_PROPERTY)) {
+            SwingUtilities.invokeLater(new Runnable() {
+                public void run() {
+                    setConnectionStatus((ConnectionStatus) evt.getNewValue());
+                }
+            });
+        } else if (evt.getPropertyName().equals(ConnectionStatusModel.PAUSED_PROPERTY)) {
+            SwingUtilities.invokeLater(new Runnable() {
+                public void run() {
+                    setPaused((boolean) evt.getNewValue());
+                }
+            });
         }
     }
-
-    /**
-     * Add an ActionListener to this component.
-     * @param listener The ActionListener.
-     */
-    void addActionListener(ActionListener listener) {
-        nextEventsButton.addActionListener(listener);
-        pauseButton.addActionListener(listener);
-        connectButton.addActionListener(listener);
-    }
-
-    /**
-     * Eanble the pause button.
-     * @param e Set to true to enable the pause button; false to disable.
-     */
-    void enablePauseButton(boolean e) {
-        this.pauseButton.setEnabled(e);
-    }
-
-    /**
-     * Enable the "next events" button.
-     * @param e Set to true to enable; false to disable.
-     */
-    void enableNextEventsButton(boolean e) {
-        this.nextEventsButton.setEnabled(e);
-    }
-
-    /**
-     * Set the pause mode state.
-     * @param enable Set to true to enable pause mode; false to disable.
-     */
-    void setPauseModeState(boolean enable) {
-        this.nextEventsButton.setEnabled(enable);
-        if (enable) {
-            pauseButton.setText("Resume");
-            pauseButton.setActionCommand(Commands.RESUME);
-        } else {
-            pauseButton.setText("Pause");
-            pauseButton.setActionCommand(Commands.PAUSE);
-        }
+    
+    void setConnectionStatus(final ConnectionStatus status) {
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                if (status.equals(ConnectionStatus.DISCONNECTED)) {
+                    nextButton.setEnabled(false);
+                    pauseButton.setEnabled(false);
+                    resumeButton.setEnabled(false);
+                    connectButton.setActionCommand(Commands.CONNECT);
+                    connectButton.setIcon(disconnectedIcon);
+                } else {
+                    pauseButton.setEnabled(true);
+                    connectButton.setActionCommand(Commands.DISCONNECT);
+                    connectButton.setIcon(connectedIcon);
+                }
+            }
+        });
+    }       
+    
+    void setPaused(final boolean paused) {
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                resumeButton.setEnabled(paused);
+                pauseButton.setEnabled(!paused);
+                nextButton.setEnabled(paused);
+            }
+        });
     }
 }

Added: 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	(added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/EventProcessing.java	Tue Mar  3 19:46:30 2015
@@ -0,0 +1,245 @@
+package org.hps.monitoring.application;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.logging.Logger;
+
+import org.freehep.record.loop.RecordLoop.Command;
+import org.hps.conditions.database.DatabaseConditionsManager;
+import org.hps.job.JobManager;
+import org.hps.monitoring.application.model.ConfigurationModel;
+import org.hps.monitoring.application.util.ErrorHandler;
+import org.hps.monitoring.subsys.et.EtSystemMonitor;
+import org.hps.monitoring.subsys.et.EtSystemStripCharts;
+import org.hps.record.LCSimEventBuilder;
+import org.hps.record.composite.CompositeLoop;
+import org.hps.record.composite.CompositeLoopConfiguration;
+import org.hps.record.composite.EventProcessingThread;
+import org.hps.record.enums.DataSourceType;
+import org.hps.record.evio.EvioDetectorConditionsProcessor;
+import org.lcsim.conditions.ConditionsManager;
+import org.lcsim.conditions.ConditionsReader;
+import org.lcsim.util.Driver;
+
+/**
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ *
+ */
+public class EventProcessing {
+    
+    SessionState state;
+    ErrorHandler errorHandler;
+    Logger logger;
+    
+    EventProcessing(SessionState state, Logger logger, ErrorHandler errorHandler) {
+        this.state = state;
+        this.logger = logger;        
+        this.errorHandler = errorHandler;        
+    }
+
+    void setup(ConfigurationModel configurationModel) {
+        logger.info("setting up LCSim");
+
+        // Get steering resource or file as a String parameter.
+        String steering = null;
+        SteeringType steeringType = configurationModel.getSteeringType();
+        if (steeringType.equals(SteeringType.FILE))
+            try {
+                steering = configurationModel.getSteeringFile().getCanonicalPath();
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        else
+            steering = configurationModel.getSteeringResource();
+
+        logger.config("Set steering to " + steering + " with type " + (steeringType == SteeringType.RESOURCE ? "RESOURCE" : "FILE"));
+
+        try {
+            // Create and the job manager.  The conditions manager is instantiated from this call but not configured.
+            state.jobManager = new JobManager();
+            
+            if (configurationModel.hasValidProperty(ConfigurationModel.DETECTOR_ALIAS_PROPERTY)) {
+                // Set a detector alias.                
+                ConditionsReader.addAlias(configurationModel.getDetectorName(), "file://" + configurationModel.getDetectorAlias());
+                logger.config("using detector alias " + configurationModel.getDetectorAlias());
+            }
+                        
+            // Setup the event builder to translate from EVIO to LCIO.
+            // This must happen before Driver setup so the builder's listeners are activated first!
+            createEventBuilder(configurationModel);
+            
+            // Configure the job manager for the XML steering.
+            state.jobManager.setPerformDryRun(true);
+            if (steeringType == SteeringType.RESOURCE) {
+                setupSteeringResource(steering);
+            } else if (steeringType.equals(SteeringType.FILE)) {
+                setupSteeringFile(steering);
+            }
+           
+            // Is there a user specified run number from the JobPanel?
+            if (configurationModel.hasValidProperty(ConfigurationModel.USER_RUN_NUMBER_PROPERTY)) {
+                int userRunNumber = configurationModel.getUserRunNumber();
+                String detectorName = configurationModel.getDetectorName();
+                DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
+                logger.config("setting user run number " + userRunNumber + " with detector " + detectorName);
+                conditionsManager.setDetector(configurationModel.getDetectorName(), userRunNumber);
+                if (configurationModel.hasPropertyKey(ConfigurationModel.FREEZE_CONDITIONS_PROPERTY)) {
+                    // Freeze the conditions system to ignore run numbers from the events.  
+                    logger.config("user configured to freeze conditions system from monitoring app");
+                    conditionsManager.freeze();
+                } else {
+                    // Allow run numbers to be picked up from the events.
+                    logger.config("user run number specified but conditions system is NOT frozen");
+                    conditionsManager.unfreeze();
+                }
+            }
+
+            logger.info("LCSim setup was successful.");
+
+        } catch (Throwable t) {
+            // Catch all errors and rethrow them as RuntimeExceptions.
+            errorHandler.setError(t).setMessage("Error setting up LCSim.").printStackTrace().raiseException();
+        }
+        
+        // Setup the CompositeLoop.
+        setupLoop(configurationModel);
+    }
+    
+    /**
+     * Create the event builder for converting EVIO events to LCSim.
+     */
+    void createEventBuilder(ConfigurationModel configurationModel) {
+
+        // Get the class for the event builder.
+        String eventBuilderClassName = configurationModel.getEventBuilderClassName();
+
+        //logger.config("initializing event builder: " + eventBuilderClassName);
+
+        try {
+            // Create a new instance of the builder class.
+            state.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);
+
+        //logger.config("successfully initialized event builder: " + eventBuilderClassName);
+    }
+    
+    void setupLoop(ConfigurationModel configurationModel) {
+
+        CompositeLoopConfiguration loopConfig = new CompositeLoopConfiguration()
+            .setStopOnEndRun(configurationModel.getDisconnectOnEndRun())
+            .setStopOnErrors(configurationModel.getDisconnectOnError())
+            .setDataSourceType(configurationModel.getDataSourceType())
+            .setProcessingStage(configurationModel.getProcessingStage())
+            .setEtConnection(state.connection)
+            .setFilePath(configurationModel.getDataSourcePath())
+            .setLCSimEventBuilder(state.eventBuilder)
+            .setDetectorName(configurationModel.getDetectorName());
+
+        if (configurationModel.hasValidProperty(ConfigurationModel.MAX_EVENTS_PROPERTY)) {
+            long maxEvents = configurationModel.getMaxEvents();
+            if (maxEvents > 0L) {
+                //logger.config("processing will stop after max events: " + maxEvents);
+                loopConfig.setMaxRecords(maxEvents);
+            }
+        }
+        
+        // Add all Drivers from the JobManager.
+        for (Driver driver : state.jobManager.getDriverExecList()) {
+            loopConfig.add(driver);
+        }
+
+        // Using ET server?
+        if (configurationModel.getDataSourceType().equals(DataSourceType.ET_SERVER)) {
+
+            // ET system monitor.
+            loopConfig.add(new EtSystemMonitor());
+
+            // ET system strip charts.
+            loopConfig.add(new EtSystemStripCharts());
+        }
+
+        // FIXME: Do this externally?
+        // RunPanel updater.
+        //loopConfig.add(frame.runPanel.new RunModelUpdater());
+                
+        // Setup for conditions activation via EVIO events.
+        loopConfig.add(new EvioDetectorConditionsProcessor(configurationModel.getDetectorName()));
+
+        // Create the CompositeLoop with the configuration.
+        state.loop = new CompositeLoop(loopConfig);        
+    }    
+    
+    
+    
+    /**
+     * Stop the event processing by executing a <code>STOP</code> command on the record loop and
+     * killing the event processing thread. This is executed after the ET system is disconnected so
+     * that the event processing does not potentially hang in a call to
+     * <code>EtSystem.getEvents()</code> forever.
+     */
+    void stop() {
+
+        // Is the event processing thread not null?
+        if (state.processingThread != null) {
+
+            // Is the event processing thread actually still alive?
+            if (state.processingThread.isAlive()) {
+
+                // Request the event processing loop to execute stop.
+                state.loop.execute(Command.STOP);
+
+                try {
+                    // This should always work, because the ET system is disconnected before this.
+                    state.processingThread.join();
+                } catch (InterruptedException e) {
+                    // Don't know when this would ever happen.
+                    e.printStackTrace();
+                }
+            }
+
+            // Notify of last error that occurred in event processing.
+            if (state.loop.getLastError() != null) {
+                errorHandler.setError(state.loop.getLastError()).log().printStackTrace();
+            }
+
+            // Set the event processing thread to null as it is unusable now.
+            state.processingThread = null;
+        }
+
+        // Set the loop to null as a new one will be created for next session.
+        state.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() {
+        
+        // Create the processing thread.
+        state.processingThread = new EventProcessingThread(state.loop);
+
+        // Start the processing thread.
+        state.processingThread.start();
+    }
+    
+
+    
+}

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	Tue Mar  3 19:46:30 2015
@@ -1,7 +1,33 @@
 package org.hps.monitoring.application;
 
-import static org.hps.monitoring.application.Commands.*;
-import static org.hps.monitoring.application.model.ConfigurationModel.*;
+import static org.hps.monitoring.application.Commands.AIDA_AUTO_SAVE_CHANGED;
+import static org.hps.monitoring.application.Commands.DETECTOR_ALIAS_CHANGED;
+import static org.hps.monitoring.application.Commands.DETECTOR_NAME_CHANGED;
+import static org.hps.monitoring.application.Commands.DISCONNECT_ON_END_RUN_CHANGED;
+import static org.hps.monitoring.application.Commands.DISCONNECT_ON_ERROR_CHANGED;
+import static org.hps.monitoring.application.Commands.EVENT_BUILDER_CHANGED;
+import static org.hps.monitoring.application.Commands.FREEZE_CONDITIONS_CHANGED;
+import static org.hps.monitoring.application.Commands.LOG_LEVEL_CHANGED;
+import static org.hps.monitoring.application.Commands.LOG_TO_FILE_CHANGED;
+import static org.hps.monitoring.application.Commands.STEERING_RESOURCE_CHANGED;
+import static org.hps.monitoring.application.Commands.STEERING_TYPE_CHANGED;
+import static org.hps.monitoring.application.Commands.USER_RUN_NUMBER_CHANGED;
+import static org.hps.monitoring.application.model.ConfigurationModel.AIDA_AUTO_SAVE_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.AIDA_FILE_NAME_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.DETECTOR_ALIAS_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.DETECTOR_NAME_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.DISCONNECT_ON_END_RUN_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.DISCONNECT_ON_ERROR_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.EVENT_BUILDER_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.FREEZE_CONDITIONS_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.LOG_FILE_NAME_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.LOG_LEVEL_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.LOG_TO_FILE_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.MAX_EVENTS_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.STEERING_FILE_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.STEERING_RESOURCE_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.STEERING_TYPE_PROPERTY;
+import static org.hps.monitoring.application.model.ConfigurationModel.USER_RUN_NUMBER_PROPERTY;
 
 import java.awt.GridBagLayout;
 import java.awt.Insets;
@@ -11,18 +37,6 @@
 import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
-import java.net.JarURLConnection;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
 import java.util.logging.Level;
 
 import javax.swing.JButton;
@@ -33,12 +47,11 @@
 import javax.swing.filechooser.FileFilter;
 
 import org.hps.monitoring.application.model.ConfigurationModel;
-import org.hps.record.LCSimEventBuilder;
+import org.hps.monitoring.application.util.ResourceUtil;
 import org.jdom.Document;
 import org.jdom.Element;
 import org.jdom.JDOMException;
 import org.jdom.input.SAXBuilder;
-import org.reflections.Reflections;
 
 /**
  * This is the GUI panel for setting job parameters. It is connected to the global configuration via
@@ -66,9 +79,6 @@
     // The package where steering resources must be located.
     static final String STEERING_PACKAGE = "org/hps/steering/monitoring/";
 
-    // This connects the GUI to the global configuration model.
-    ConfigurationModel configurationModel;
-
     // The available LogLevel settings as an array of strings.
     static final String[] LOG_LEVELS = new String[] { 
         Level.ALL.toString(), 
@@ -88,9 +98,10 @@
     JobSettingsPanel() {
 
         super(new Insets(4, 2, 2, 4), true);
+        
         setLayout(new GridBagLayout());
 
-        steeringResourcesComboBox = addComboBoxMultiline("Steering File Resource", findSteeringResources(STEERING_PACKAGE));
+        steeringResourcesComboBox = addComboBoxMultiline("Steering File Resource", ResourceUtil.findSteeringResources(STEERING_PACKAGE));
         steeringResourcesComboBox.setActionCommand(STEERING_RESOURCE_CHANGED);
         steeringResourcesComboBox.addActionListener(this);
         
@@ -105,7 +116,7 @@
         steeringTypeComboBox.setActionCommand(STEERING_TYPE_CHANGED);
         steeringTypeComboBox.addActionListener(this);
         
-        detectorNameComboBox = addComboBox("Detector Name", this.findDetectorNames());
+        detectorNameComboBox = addComboBox("Detector Name", ResourceUtil.findDetectorNames());
         detectorNameComboBox.setActionCommand(DETECTOR_NAME_CHANGED);
         detectorNameComboBox.addActionListener(this);
         
@@ -133,7 +144,7 @@
         maxEventsField.setEnabled(true);
         maxEventsField.setEditable(true);
         
-        eventBuilderComboBox = addComboBox("LCSim Event Builder", this.findEventBuilderClassNames());
+        eventBuilderComboBox = addComboBox("LCSim Event Builder", ResourceUtil.findEventBuilderClassNames());
         eventBuilderComboBox.setSize(24, eventBuilderComboBox.getPreferredSize().height);
         eventBuilderComboBox.setActionCommand(EVENT_BUILDER_CHANGED);
         eventBuilderComboBox.addActionListener(this);
@@ -167,37 +178,14 @@
     }
 
     @Override
-    public void setConfigurationModel(ConfigurationModel configModel) {
-
-        // Set the ConfigurationModel reference.
-        this.configurationModel = configModel;
-
-        // This listener pushes GUI values into the configuration.
-        this.configurationModel.addPropertyChangeListener(this);
-
-        // This listener updates the GUI from changes in the configuration.
-        this.configurationModel.addPropertyChangeListener(new JobSettingsChangeListener());
-    }
-
-    @Override
     public ConfigurationModel getConfigurationModel() {
         return configurationModel;
     }
 
     /**
-     * Enable this component.
-     * @param enable Whether to enable or not.
-     */
-    /*
-     * void enableJobPanel(boolean enable) { detectorNameField.setEnabled(enable);
-     * eventBuilderField.setEnabled(enable); steeringTypeComboBox.setEnabled(enable);
-     * steeringFileField.setEnabled(enable); steeringResourcesComboBox.setEnabled(enable); }
-     */
-
-    /**
      * Attaches the ActionListener from the main app to specific GUI components in this class.
      */
-    void addActionListener(ActionListener listener) {
+    public void addActionListener(ActionListener listener) {
         logFileNameField.addActionListener(listener);
         logToFileCheckbox.addActionListener(listener);
         steeringResourcesComboBox.addActionListener(listener);
@@ -299,37 +287,50 @@
     }
 
     @Override
-    public void actionPerformed(ActionEvent e) {
-        if (e.getActionCommand().equals(Commands.CHOOSE_STEERING_FILE)) {
-            this.chooseSteeringFile();
-        } else if (e.getActionCommand().equals(Commands.CHOOSE_COMPACT_FILE)) {
-            chooseCompactFile();
-        } else if (DISCONNECT_ON_ERROR_CHANGED.equals(e.getActionCommand())) {
-            configurationModel.setDisconnectOnError(disconnectOnErrorCheckBox.isSelected());
-        } else if (DISCONNECT_ON_END_RUN_CHANGED.equals(e.getActionCommand())) {
-            configurationModel.setDisconnectOnEndRun(disconnectOnEndRunCheckBox.isSelected());
-        } else if (STEERING_TYPE_CHANGED.equals(e.getActionCommand())) {
-            configurationModel.setSteeringType(SteeringType.valueOf((String) steeringTypeComboBox.getSelectedItem()));
-        } else if (STEERING_RESOURCE_CHANGED.equals(e.getActionCommand())) {
-            configurationModel.setSteeringResource((String) steeringResourcesComboBox.getSelectedItem());
-        } else if (LOG_TO_FILE_CHANGED.equals(e.getActionCommand())) {
-            configurationModel.setLogToFile(logToFileCheckbox.isSelected());
-        } else if (LOG_LEVEL_CHANGED.equals(e.getActionCommand())) {
-            configurationModel.setLogLevel(Level.parse((String) logLevelComboBox.getSelectedItem()));
-        } else if (AIDA_AUTO_SAVE_CHANGED.equals(e.getActionCommand())) {
-            configurationModel.setAidaAutoSave(aidaAutoSaveCheckbox.isSelected());
-        } else if (EVENT_BUILDER_CHANGED.equals(e.getActionCommand())) {
-            configurationModel.setEventBuilderClassName((String) eventBuilderComboBox.getSelectedItem());
-        } else if (DETECTOR_NAME_CHANGED.equals(e.getActionCommand())) {
-            configurationModel.setDetectorName((String) detectorNameComboBox.getSelectedItem());
-        } else if (FREEZE_CONDITIONS_CHANGED.equals(e.getActionCommand())) {
-            if (configurationModel.hasPropertyKey(USER_RUN_NUMBER_PROPERTY) && configurationModel.getUserRunNumber() != null) {
-                configurationModel.setFreezeConditions(freezeConditionsCheckBox.isSelected());
-            } else {
-                throw new IllegalArgumentException("Conditions system may only be frozen if there is a valid user run number.");
-            }
-        } else if (DETECTOR_ALIAS_CHANGED.equals(e.getActionCommand())) {
-            configurationModel.setDetectorName(detectorAliasField.getText());
+    public void actionPerformed(ActionEvent event) {
+
+        //System.out.println("JobSettingsPanel.actionPerformed - " + event.getActionCommand());
+        //System.out.println("  source: " + event.getSource());
+
+        try {
+            configurationModel.removePropertyChangeListener(this);
+            if (event.getActionCommand().equals(Commands.CHOOSE_STEERING_FILE)) {
+                chooseSteeringFile();
+            } else if (event.getActionCommand().equals(Commands.CHOOSE_COMPACT_FILE)) {
+                chooseCompactFile();
+            } else if (DISCONNECT_ON_ERROR_CHANGED.equals(event.getActionCommand())) {
+                configurationModel.setDisconnectOnError(disconnectOnErrorCheckBox.isSelected());
+            } else if (DISCONNECT_ON_END_RUN_CHANGED.equals(event.getActionCommand())) {
+                configurationModel.setDisconnectOnEndRun(disconnectOnEndRunCheckBox.isSelected());
+            } else if (STEERING_TYPE_CHANGED.equals(event.getActionCommand())) {
+                configurationModel.setSteeringType(SteeringType.valueOf((String) steeringTypeComboBox.getSelectedItem()));
+            } else if (STEERING_RESOURCE_CHANGED.equals(event.getActionCommand())) {
+                configurationModel.setSteeringResource((String) steeringResourcesComboBox.getSelectedItem());
+            } else if (LOG_TO_FILE_CHANGED.equals(event.getActionCommand())) {
+                configurationModel.setLogToFile(logToFileCheckbox.isSelected());
+            } else if (LOG_LEVEL_CHANGED.equals(event.getActionCommand())) {
+                configurationModel.setLogLevel(Level.parse((String) logLevelComboBox.getSelectedItem()));
+            } else if (AIDA_AUTO_SAVE_CHANGED.equals(event.getActionCommand())) {
+                configurationModel.setAidaAutoSave(aidaAutoSaveCheckbox.isSelected());
+            } else if (EVENT_BUILDER_CHANGED.equals(event.getActionCommand())) {
+                configurationModel.setEventBuilderClassName((String) eventBuilderComboBox.getSelectedItem());
+            } else if (DETECTOR_NAME_CHANGED.equals(event.getActionCommand())) {
+                try {
+                    configurationModel.setDetectorName((String) detectorNameComboBox.getSelectedItem());
+                } catch (Exception exception) {
+                    exception.printStackTrace();
+                }
+            } else if (FREEZE_CONDITIONS_CHANGED.equals(event.getActionCommand())) {
+                if (configurationModel.hasPropertyKey(USER_RUN_NUMBER_PROPERTY) && configurationModel.getUserRunNumber() != null) {
+                    configurationModel.setFreezeConditions(freezeConditionsCheckBox.isSelected());
+                } else {
+                    throw new IllegalArgumentException("Conditions system may only be frozen if there is a valid user run number.");
+                }
+            } else if (DETECTOR_ALIAS_CHANGED.equals(event.getActionCommand())) {
+                configurationModel.setDetectorName(detectorAliasField.getText());
+            }
+        } finally {
+            configurationModel.addPropertyChangeListener(this);
         }
     }
 
@@ -338,199 +339,121 @@
      * GUI are distinguishable by their component object.
      */
     @Override
-    public void propertyChange(PropertyChangeEvent evt) {
-
-        // FIXME: Anyway to make sure this is not needed?
-        if (evt.getPropertyName().equals("ancestor"))
-            return;
-
-        Object source = evt.getSource();
-
-        if (source == steeringFileField) {
-            configurationModel.setSteeringFile(steeringFileField.getText());
-        } else if (source == logFileNameField) {
-            configurationModel.setLogFileName(logFileNameField.getText());
-        } else if (source == aidaSaveFileNameField) {
-            configurationModel.setAidaFileName(aidaSaveFileNameField.getText());
-        } else if (source == aidaAutoSaveCheckbox) {
-            configurationModel.setAidaAutoSave(aidaAutoSaveCheckbox.isSelected());
-        } else if (source == userRunNumberField) {
-            // Is run number being reset to null or empty?
-            if (userRunNumberField.getText() == null || userRunNumberField.getText().isEmpty()) {
-                System.out.println("resetting user run number back to null");
-                // Update the model to null user run number and do not freeze the conditions system.
-                configurationModel.setUserRunNumber(null);
-                configurationModel.setFreezeConditions(false);
-            } else {
-                try {
-                    System.out.println("setting new user run number " + evt.getNewValue());
-                    // Parse the run number.  Need to catch errors because it might be an invalid string.
-                    int userRunNumber = Integer.parseInt(userRunNumberField.getText());
-                    configurationModel.setUserRunNumber(userRunNumber);
-                    configurationModel.setFreezeConditions(true);
-                    System.out.println("successfully set run number to userRunNumber");
-                } catch (NumberFormatException e) {
-                    System.out.println("bad number format so ignoring user run number " + evt.getNewValue());
-                    userRunNumberField.setText((String) evt.getOldValue());
-                    throw new IllegalArgumentException("The value " + evt.getNewValue() + " is not a valid run number.");
-                }                            
-            }
-        } else if (source == maxEventsField) {
-            configurationModel.setMaxEvents(Long.parseLong(maxEventsField.getText()));
-            System.out.println("setMaxEvents - " + configurationModel.getMaxEvents());
-        }
-    }
-
-    /**
-     * Update the GUI from changes in the underlying configuration. The changes from the
-     * configuration are distinguishable by their property name.
+    public void propertyChange(PropertyChangeEvent evt) {                            
+        configurationModel.removePropertyChangeListener(this);
+        try {
+            Object source = evt.getSource();            
+            if (source == steeringFileField) {
+                configurationModel.setSteeringFile(steeringFileField.getText());
+            } else if (source == logFileNameField) {
+                configurationModel.setLogFileName(logFileNameField.getText());
+            } else if (source == aidaSaveFileNameField) {
+                configurationModel.setAidaFileName(aidaSaveFileNameField.getText());
+            } else if (source == aidaAutoSaveCheckbox) {
+                configurationModel.setAidaAutoSave(aidaAutoSaveCheckbox.isSelected());
+            } else if (source == userRunNumberField) {
+                // Is run number being reset to null or empty?
+                if (userRunNumberField.getText() == null || userRunNumberField.getText().isEmpty()) {
+                    // System.out.println("resetting user run number back to null");
+                    // Update the model to null user run number and do not freeze the conditions system.
+                    configurationModel.setUserRunNumber(null);
+                    configurationModel.setFreezeConditions(false);
+                } else {
+                    try {
+                        // System.out.println("setting new user run number " + evt.getNewValue());
+                        // Parse the run number. Need to catch errors because it might be an invalid string.
+                        int userRunNumber = Integer.parseInt(userRunNumberField.getText());
+                        configurationModel.setUserRunNumber(userRunNumber);
+                        configurationModel.setFreezeConditions(true);
+                        System.out.println("successfully set run number to userRunNumber");
+                    } catch (NumberFormatException e) {
+                        System.out.println("bad number format so ignoring user run number " + evt.getNewValue());
+                        userRunNumberField.setText((String) evt.getOldValue());
+                        // throw new IllegalArgumentException("The value " + evt.getNewValue() + " is not a valid run number.");
+                    }
+                }
+            } else if (source == maxEventsField) {
+                configurationModel.setMaxEvents(Long.parseLong(maxEventsField.getText()));
+                System.out.println("setMaxEvents - " + configurationModel.getMaxEvents());
+            }
+        } finally {
+            configurationModel.addPropertyChangeListener(this);
+        }
+    }
+
+    /**
+     * Update the GUI from changes in the underlying model. 
+     * The changes are distinguishable by their property name.
      */
     private class JobSettingsChangeListener implements PropertyChangeListener {
         @Override
         public void propertyChange(PropertyChangeEvent evt) {
-
-            // FIXME: Anyway to make sure this is not needed?
-            if (evt.getPropertyName().equals("ancestor"))
-                return;
-
-            Object value = evt.getNewValue();
-
-            if (evt.getPropertyName().equals(DETECTOR_NAME_PROPERTY)) {
-                detectorNameComboBox.setSelectedItem((String) value);
-            } else if (evt.getPropertyName().equals(DETECTOR_ALIAS_PROPERTY)) {
-                detectorAliasField.setText((String) value);
-            } else if (evt.getPropertyName().equals(AIDA_AUTO_SAVE_PROPERTY)) {
-                aidaAutoSaveCheckbox.setSelected((Boolean) value);
-            } else if (evt.getPropertyName().equals(AIDA_FILE_NAME_PROPERTY)) {
-                aidaSaveFileNameField.setText((String) value);
-            } else if (evt.getPropertyName().equals(DISCONNECT_ON_ERROR_PROPERTY)) {
-                disconnectOnErrorCheckBox.setSelected((Boolean) value);
-            } else if (evt.getPropertyName().equals(DISCONNECT_ON_END_RUN_PROPERTY)) {
-                disconnectOnEndRunCheckBox.setSelected((Boolean) value);
-            } else if (evt.getPropertyName().equals(EVENT_BUILDER_PROPERTY)) {
-                eventBuilderComboBox.setSelectedItem((String) value);
-            } else if (evt.getPropertyName().equals(LOG_FILE_NAME_PROPERTY)) {
-                logFileNameField.setText((String) value);
-            } else if (evt.getPropertyName().equals(LOG_LEVEL_PROPERTY)) {
-                logLevelComboBox.setSelectedItem(value.toString());
-            } else if (evt.getPropertyName().equals(LOG_TO_FILE_PROPERTY)) {
-                logToFileCheckbox.setSelected((Boolean) value);
-            } else if (evt.getPropertyName().equals(STEERING_TYPE_PROPERTY)) {
-                steeringTypeComboBox.setSelectedIndex(((SteeringType) value).ordinal());
-            } else if (evt.getPropertyName().equals(STEERING_FILE_PROPERTY)) {
-                if (value != null) {                    
-                    steeringFileField.setText((String) value);
-                } else {
-                    // A null value here is actually okay and means this field should be reset to have no value.
-                    steeringFileField.setText(null);
+            System.out.println("JobSettingsChangeListener.propertyChange");
+            System.out.println("  src: " + evt.getSource());
+            System.out.println("  propName: " + evt.getPropertyName());
+            System.out.println("  oldValue: " + evt.getOldValue());
+            System.out.println("  newValue: " + evt.getNewValue());
+            System.out.println("  propId: " + evt.getPropagationId());
+            if (evt.getSource() instanceof ConfigurationModel) {
+                Object value = evt.getNewValue();
+                configurationModel.removePropertyChangeListener(this);
+                try {
+                    if (evt.getPropertyName().equals(DETECTOR_NAME_PROPERTY)) {
+                        detectorNameComboBox.setSelectedItem((String) value);
+                    } else if (evt.getPropertyName().equals(DETECTOR_ALIAS_PROPERTY)) {
+                        detectorAliasField.setText((String) value);
+                    } else if (evt.getPropertyName().equals(AIDA_AUTO_SAVE_PROPERTY)) {
+                        aidaAutoSaveCheckbox.setSelected((Boolean) value);
+                    } else if (evt.getPropertyName().equals(AIDA_FILE_NAME_PROPERTY)) {
+                        aidaSaveFileNameField.setText((String) value);
+                    } else if (evt.getPropertyName().equals(DISCONNECT_ON_ERROR_PROPERTY)) {
+                        disconnectOnErrorCheckBox.setSelected((Boolean) value);
+                    } else if (evt.getPropertyName().equals(DISCONNECT_ON_END_RUN_PROPERTY)) {
+                        disconnectOnEndRunCheckBox.setSelected((Boolean) value);
+                    } else if (evt.getPropertyName().equals(EVENT_BUILDER_PROPERTY)) {
+                        eventBuilderComboBox.setSelectedItem((String) value);
+                    } else if (evt.getPropertyName().equals(LOG_FILE_NAME_PROPERTY)) {
+                        logFileNameField.setText((String) value);
+                    } else if (evt.getPropertyName().equals(LOG_LEVEL_PROPERTY)) {
+                        logLevelComboBox.setSelectedItem(value.toString());
+                    } else if (evt.getPropertyName().equals(LOG_TO_FILE_PROPERTY)) {
+                        logToFileCheckbox.setSelected((Boolean) value);
+                    } else if (evt.getPropertyName().equals(STEERING_TYPE_PROPERTY)) {
+                        steeringTypeComboBox.setSelectedIndex(((SteeringType) value).ordinal());
+                    } else if (evt.getPropertyName().equals(STEERING_FILE_PROPERTY)) {
+                        if (value != null) {
+                            steeringFileField.setText((String) value);
+                        } else {
+                            // A null value here is actually okay and means this field should be reset to have no value.
+                            steeringFileField.setText(null);
+                        }
+                    } else if (evt.getPropertyName().equals(STEERING_RESOURCE_PROPERTY)) {
+                        steeringResourcesComboBox.setSelectedItem(value);
+                    } else if (evt.getPropertyName().equals(USER_RUN_NUMBER_PROPERTY)) {
+                        if (value != null) {
+                            userRunNumberField.setText(Integer.toString((int) value));
+                        } else {
+                            userRunNumberField.setText(null);
+                        }
+                    } else if (evt.getPropertyName().equals(FREEZE_CONDITIONS_PROPERTY)) {
+                        if (value != null) {
+                            freezeConditionsCheckBox.setSelected((Boolean) value);
+                        }
+                    } else if (evt.getPropertyName().equals(MAX_EVENTS_PROPERTY)) {
+                        if (value != null) {
+                            maxEventsField.setText(value.toString());
+                        }
+                    }
+                } finally {
+                    configurationModel.addPropertyChangeListener(this);
                 }
-            } else if (evt.getPropertyName().equals(STEERING_RESOURCE_PROPERTY)) {
-                steeringResourcesComboBox.setSelectedItem(value);
-            } else if (evt.getPropertyName().equals(USER_RUN_NUMBER_PROPERTY)) {
-                if (value != null) {
-                    userRunNumberField.setText(Integer.toString((int)value));
-                } else {
-                    userRunNumberField.setText(null);
-                }
-            } else if (evt.getPropertyName().equals(FREEZE_CONDITIONS_PROPERTY)) {
-                if (value != null) {
-                    freezeConditionsCheckBox.setSelected((Boolean) value);
-                }
-            } else if (evt.getPropertyName().equals(MAX_EVENTS_PROPERTY)) {
-                if (value != null) {
-                    maxEventsField.setText(value.toString());
-                }
             }
         }
     }
     
-    /**
-     * Get the files with extension 'lcsim' from all loaded jar files.
-     * @param packageName The package name for filtering the resources.
-     * @return A list of embedded steering file resources.
-     */
-    private static String[] findSteeringResources(String packageName) {
-        List<String> resources = new ArrayList<String>();
-        URL url = JobSettingsPanel.class.getResource("MonitoringApplication.class");
-        String scheme = url.getProtocol();
-        if (!"jar".equals(scheme)) {
-            throw new IllegalArgumentException("Unsupported scheme.  Only jar is allowed.");
-        }
-        try {
-            JarURLConnection con = (JarURLConnection) url.openConnection();
-            JarFile archive = con.getJarFile();
-            Enumeration<JarEntry> entries = archive.entries();
-            while (entries.hasMoreElements()) {
-                JarEntry entry = entries.nextElement();
-                if (entry.getName().endsWith(".lcsim") && entry.getName().contains(packageName)) {
-                    resources.add(entry.getName());
-                }
-            }
-            archive.close();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-        java.util.Collections.sort(resources);
-        String[] arr = new String[resources.size()];
-        for (int i = 0; i < arr.length; i++) {
-            arr[i] = resources.get(i);
-        }
-        return arr;
-    }
-    
-    /**
-     * Find all classes that implement {@link org.hps.record.LCSimEventBuilder} and return
-     * a list of their canonical names.
-     * @return The list of classes implementing LCSimEventBuilder.
-     */
-    private static String[] findEventBuilderClassNames() {
-        Reflections reflections = new Reflections("org.hps");
-        Set<Class<? extends LCSimEventBuilder>> subTypes = reflections.getSubTypesOf(LCSimEventBuilder.class);
-        Set<String> classNames = new HashSet<String>();
-        for (Class<? extends LCSimEventBuilder> type : subTypes) {
-            classNames.add(type.getCanonicalName());
-        }
-        return classNames.toArray(new String[classNames.size()]);        
-    }
- 
-    /**
-     * Find a list of available detector names.
-     * Only those detectors that have names starting with "HPS" in their
-     * detector.properties files will be returned.
-     * @return The list of available detector names.
-     */
-    private static String[] findDetectorNames() {
-        ClassLoader classLoader = JobSettingsPanel.class.getClassLoader();
-        List<String> detectorNames = new ArrayList<String>();
-        URL url = JobSettingsPanel.class.getResource("MonitoringApplication.class");
-        String protocol = url.getProtocol();
-        if (!"jar".equals(protocol)) {
-            throw new RuntimeException("Unsupported URL protocol: " + url.getProtocol());
-        }
-        try {
-            JarURLConnection con = (JarURLConnection) url.openConnection();
-            JarFile archive = con.getJarFile();
-            Enumeration<JarEntry> entries = archive.entries();
-            while (entries.hasMoreElements()) {
-                JarEntry entry = entries.nextElement();
-                if (entry.getName().endsWith("detector.properties")) {
-                    InputStream inputStream = classLoader.getResourceAsStream(entry.getName());
-                    if (inputStream == null) {
-                        throw new RuntimeException("Failed to load jar entry: " + entry.getName());
-                    }
-                    Properties properties = new Properties();
-                    properties.load(inputStream);
-                    String detectorName = properties.getProperty("name");
-                    if (detectorName.startsWith("HPS")) {
-                        detectorNames.add(detectorName);
-                    }
-                }
-            }
-            archive.close();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-        Collections.sort(detectorNames);
-        return detectorNames.toArray(new String[detectorNames.size()]);
+    @Override
+    public void setConfigurationModel(ConfigurationModel model) {
+        super.setConfigurationModel(model);
+        model.addPropertyChangeListener(new JobSettingsChangeListener());
     }
 }

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	Tue Mar  3 19:46:30 2015
@@ -8,7 +8,7 @@
 import javax.swing.table.DefaultTableModel;
 
 /**
- * This is a simple Swing component to model the log table.
+ * This is a simple Swing component for the table of log messages.
  * @author Jeremy McCormick <[log in to unmask]>
  */
 public class LogTable extends JTable {

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	Tue Mar  3 19:46:30 2015
@@ -1,77 +1,74 @@
 package org.hps.monitoring.application;
+
+import static org.hps.monitoring.application.Commands.*;
 
 import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
 
-import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JMenu;
 import javax.swing.JMenuBar;
 import javax.swing.JMenuItem;
 
-import static org.hps.monitoring.application.Commands.*;
-
 public class MenuBar extends JMenuBar {
 
-    private JMenuItem savePlotsItem;
-    private JMenuItem logItem;
-    private JMenuItem terminalItem;
-    private JMenuItem saveLayoutItem;
+    //private JMenuItem savePlotsItem;
+    //private JMenuItem logItem;
+    //private JMenuItem terminalItem;
+    //private JMenuItem saveLayoutItem;
     
     MenuBar(ActionListener listener) {
 
-        JMenu applicationMenu = new JMenu("Application");
-        applicationMenu.setMnemonic(KeyEvent.VK_A);
-        add(applicationMenu);
-
-        JMenuItem loadConfigItem = new JMenuItem("Load Settings ...");
-        //loadConfigItem.addActionListener(listener);
-        loadConfigItem.setMnemonic(KeyEvent.VK_C);
-        loadConfigItem.setActionCommand(SELECT_CONFIG_FILE);
-        loadConfigItem.setToolTipText("Load application settings from a properties file");
-        applicationMenu.add(loadConfigItem);
-
-        JMenuItem saveConfigItem = new JMenuItem("Save Settings ...");
-        //saveConfigItem.addActionListener(listener);
-        saveConfigItem.setMnemonic(KeyEvent.VK_S);
-        saveConfigItem.setActionCommand(SAVE_CONFIG_FILE);
-        saveConfigItem.setToolTipText("Save settings to a properties file");
-        applicationMenu.add(saveConfigItem);
-
-        JMenuItem settingsItem = new JMenuItem("Show Settings ...");
-        settingsItem.setMnemonic(KeyEvent.VK_P);
-        settingsItem.setActionCommand(SHOW_SETTINGS);
-        //settingsItem.addActionListener(listener);
-        settingsItem.setToolTipText("Show application settings menu");
-        applicationMenu.add(settingsItem);
-
-        applicationMenu.addSeparator();
-
-        saveLayoutItem = new JCheckBoxMenuItem("Save GUI Layout");
-        saveLayoutItem.setActionCommand(SAVE_LAYOUT);
-        //saveLayoutItem.addActionListener(listener);
-        saveLayoutItem.setToolTipText("Include current GUI layout when saving settings.");
-        //if (configurationModel.hasPropertyKey(ConfigurationModel.SAVE_LAYOUT_PROPERTY)) {
-        //    saveLayoutItem.setSelected(configurationModel.getSaveLayout());
-        //}
-        //saveLayoutItem.addPropertyChangeListener(this); 
+        JMenu fileMenu = new JMenu("File");
+        fileMenu.setMnemonic(KeyEvent.VK_F);
+        add(fileMenu);
         
-        applicationMenu.add(saveLayoutItem);
-
-        JMenuItem restoreLayoutItem = new JMenuItem("Restore Default GUI Layout");
-        restoreLayoutItem.setActionCommand(RESTORE_DEFAULT_GUI_LAYOUT);
-        //restoreLayoutItem.addActionListener(listener);
-        restoreLayoutItem.setToolTipText("Restore the GUI windows to their default positions and sizes");
-        applicationMenu.add(restoreLayoutItem);
-
-        applicationMenu.addSeparator();
-
+        JMenuItem openFileItem = new JMenuItem("Open File ...");
+        openFileItem.setMnemonic(KeyEvent.VK_P);
+        openFileItem.setActionCommand(OPEN_FILE);
+        openFileItem.addActionListener(listener);
+        openFileItem.setToolTipText("Open an EVIO or LCIO data file");
+        fileMenu.add(openFileItem);
+              
         JMenuItem exitItem = new JMenuItem("Exit");
         exitItem.setMnemonic(KeyEvent.VK_X);
         exitItem.setActionCommand(EXIT);
-        //exitItem.addActionListener(listener);
+        exitItem.addActionListener(listener);
         exitItem.setToolTipText("Exit from the application");
-        applicationMenu.add(exitItem);
+        fileMenu.add(exitItem);
+                
+        JMenu settingsMenu = new JMenu("Settings");
+        settingsMenu.setMnemonic(KeyEvent.VK_S);
+        add(settingsMenu);
+        
+        JMenuItem settingsItem = new JMenuItem("Show Settings ...");
+        settingsItem.setMnemonic(KeyEvent.VK_P);
+        settingsItem.setActionCommand(SETTINGS_SHOW);
+        settingsItem.addActionListener(listener);
+        settingsItem.setToolTipText("Show settings dialog");
+        settingsMenu.add(settingsItem);
+        
+        JMenuItem loadConfigItem = new JMenuItem("Load Settings ...");
+        loadConfigItem.addActionListener(listener);
+        loadConfigItem.setMnemonic(KeyEvent.VK_C);
+        loadConfigItem.setActionCommand(SETTINGS_LOAD);
+        loadConfigItem.setToolTipText("Load settings from a properties file");
+        settingsMenu.add(loadConfigItem);
 
+        JMenuItem saveConfigItem = new JMenuItem("Save Settings ...");
+        saveConfigItem.addActionListener(listener);
+        saveConfigItem.setMnemonic(KeyEvent.VK_S);
+        saveConfigItem.setActionCommand(SETTINGS_SAVE);
+        saveConfigItem.setToolTipText("Save configuration to a properties file");
+        settingsMenu.add(saveConfigItem);
+        
+        JMenuItem defaultSettingsItem = new JMenuItem("Load Default Settings");
+        defaultSettingsItem.addActionListener(listener);
+        defaultSettingsItem.setMnemonic(KeyEvent.VK_D);
+        defaultSettingsItem.setActionCommand(SETTINGS_LOAD_DEFAULT);
+        defaultSettingsItem.setToolTipText("Load the default settings");
+        settingsMenu.add(defaultSettingsItem);
+                      
+        /*               
         JMenu plotsMenu = new JMenu("Plots");
         plotsMenu.setMnemonic(KeyEvent.VK_O);
         add(plotsMenu);
@@ -143,6 +140,7 @@
         //screenshotItem.addActionListener(this);
         screenshotItem.setToolTipText("Save a screenshot to file");
         utilMenu.add(screenshotItem);
+        */
     }
     
 }

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	Tue Mar  3 19:46:30 2015
@@ -1,56 +1,62 @@
 package org.hps.monitoring.application;
 
+import static org.hps.monitoring.application.Commands.*;
+import hep.aida.jfree.AnalysisFactory;
+import hep.aida.jfree.plotter.PlotterRegion;
+import hep.aida.jfree.plotter.PlotterRegionListener;
+
 import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
 import java.util.logging.Handler;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.util.logging.Logger;
 
-import org.hps.conditions.database.DatabaseConditionsManager;
-import org.hps.job.JobManager;
-import org.hps.monitoring.application.RunPanel.RunModelUpdater;
+import javax.swing.JFileChooser;
+import javax.swing.filechooser.FileFilter;
+import javax.swing.filechooser.FileNameExtensionFilter;
+
 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.plotting.MonitoringAnalysisFactory;
+import org.hps.monitoring.plotting.MonitoringPlotFactory;
+import org.hps.monitoring.subsys.StatusCode;
+import org.hps.monitoring.subsys.SystemStatus;
+import org.hps.monitoring.subsys.SystemStatusListener;
 import org.hps.monitoring.subsys.SystemStatusRegistry;
-import org.hps.monitoring.subsys.et.EtSystemMonitor;
-import org.hps.monitoring.subsys.et.EtSystemStripCharts;
-import org.hps.record.LCSimEventBuilder;
-import org.hps.record.composite.CompositeLoop;
-import org.hps.record.composite.CompositeLoopConfiguration;
-import org.hps.record.composite.EventProcessingThread;
 import org.hps.record.enums.DataSourceType;
-import org.hps.record.evio.EvioDetectorConditionsProcessor;
-import org.lcsim.conditions.ConditionsManager;
-import org.lcsim.conditions.ConditionsReader;
-import org.lcsim.util.Driver;
 import org.lcsim.util.aida.AIDA;
 
-public class MonitoringApplication implements PropertyChangeListener {
+public class MonitoringApplication implements PropertyChangeListener, ActionListener, SystemStatusListener {
 
     static Logger logger;
+    static {
+        logger = Logger.getLogger(MonitoringApplication.class.getSimpleName());
+    }
     Handler logHandler;
     
     ErrorHandler errorHandler;
    
-    MonitoringActionListener actions;
     MonitoringApplicationFrame frame;    
-    SettingsDialog settingsDialog = new SettingsDialog();
     
     RunModel runModel = new RunModel();
     ConfigurationModel configurationModel = new ConfigurationModel();
+    ConnectionStatusModel connectionModel = new ConnectionStatusModel();
     
     SessionState sessionState;
+    EventProcessing processing;
     
     // The default configuration resource.
-    private static final String DEFAULT_CONFIG_RESOURCE = "/org/hps/monitoring/config/default_config.prop";
+    private static final String DEFAULT_CONFIGURATION = "/org/hps/monitoring/config/default_config.prop";
 
     // The application's global Configuration settings.
     private Configuration configuration;
@@ -75,6 +81,18 @@
         
         // Setup the error handler.
         this.errorHandler = new ErrorHandler(frame, logger);
+        
+        // Setup the main GUI component, passing it the data models and this object as the primary ActionListener.
+        frame = new MonitoringApplicationFrame(configurationModel, runModel, connectionModel, this);
+                        
+        // Add this class as a listener on the configuration model.
+        configurationModel.addPropertyChangeListener(this);
+        
+        // Setup the logger.
+        setupLogger();
+        
+        // Setup plotting backend and connect to the GUI.
+        setupAida();
         
         // Set the configuration.
         if (configuration != null) {
@@ -82,36 +100,33 @@
             this.configuration = configuration;
         } else {
             // Use the default configuration resource.
-            this.configuration = new Configuration(DEFAULT_CONFIG_RESOURCE);
-        }
-        
-        // Setup the action listener.
-        actions = new MonitoringActionListener(this);
-        
-        // Setup the main GUI component.
-        frame = new MonitoringApplicationFrame(actions);
-        frame.setRunModel(runModel);
-        
-        // Setup the logger.
-        setupLogger();
-        
-        // Setup the settings dialog box.
-        settingsDialog.addActionListener(actions);
-        settingsDialog.setConfigurationModel(configurationModel);
-        
-        // Add this class as a listener on the configuration model.
-        configurationModel.addPropertyChangeListener(this);      
-        
-        // Load the configuration.
+            this.configuration = new Configuration(DEFAULT_CONFIGURATION);
+        }
+                                      
+        // Load the current configuration.
         loadConfiguration();
     }
     
-    private void setupLogger() {
-        logger = Logger.getLogger(MonitoringApplication.class.getSimpleName());
+    void setupAida() {
+        MonitoringAnalysisFactory.register();
+        MonitoringPlotFactory.setRootPane(frame.plotPanel.getPlotPane());
+        MonitoringPlotFactory.setPlotterRegionListener(new PlotterRegionListener() {
+            @Override
+            public void regionSelected(PlotterRegion region) {
+                if (region == null)
+                    throw new RuntimeException("The region arg is null!!!");
+                // System.out.println("MonitoringApplication - regionSelected - " + region.title());
+                frame.plotInfoPanel.setCurrentRegion(region);
+            }
+        });
+        AnalysisFactory.configure();
+    }
+    
+    void setupLogger() {
         logHandler = new LogHandler();
         logger.setUseParentHandlers(false);
         logger.addHandler(logHandler);
-        logger.setLevel(Level.ALL);
+        logger.setLevel(Level.ALL);        
     }
         
     public static MonitoringApplication create(Configuration configuration) {
@@ -119,12 +134,12 @@
     }    
     
     public static MonitoringApplication create() {
-        return create(new Configuration(DEFAULT_CONFIG_RESOURCE));
+        return create(new Configuration(DEFAULT_CONFIGURATION));
     }
     
     @Override
     public void propertyChange(PropertyChangeEvent evt) {
-        // TODO Auto-generated method stub        
+        // TODO Auto-generated method stub
     }
     
     void loadConfiguration() {
@@ -133,10 +148,10 @@
         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());
+        //if (configuration.getFile() != null)
+            //logger.config("Loaded configuration from file: " + configuration.getFile().getPath());
+        //else
+            //logger.config("Loaded configuration from resource: " + configuration.getResourcePath());
     }
     
     /**
@@ -146,15 +161,13 @@
      */
     void startSession() {
 
-        logger.fine("Starting a new monitoring session.");
+        //logger.fine("Starting a new monitoring session.");
 
         // Show a modal window that will block the GUI until connected or an error occurs.
         //JDialog dialog = DialogUtil.showStatusDialog(this, "Info", "Starting new session ...");
 
         try {
             
-            sessionState = new SessionState();
-
             // Reset the plot panel and global AIDA state.
             resetPlots();
 
@@ -163,35 +176,38 @@
             // e.g. an LCSim Driver, etc.
             SystemStatusRegistry.getSystemStatusRegistery().clear();
 
-            // Setup the LCSim JobControlManager and event builder.
-            setupLCSim();
-
+            // Setup event processing.
+            sessionState = new SessionState();
+            processing = new EventProcessing(sessionState, logger, errorHandler);
+            processing.setup(configurationModel);
+                        
+            // Add the dashboard updater.
+            sessionState.loop.getCompositeLoopAdapters().get(0).addProcessor(frame.runPanel.new RunModelUpdater());
+          
+            // Setup the system status monitor table.
+            setupSystemStatusMonitor();
+            
             // Connect to the ET system.
             connect();
-
-            // Setup the EventProcessingChain object using the EtConnection.
-            setupCompositeLoop();
+          
+            // Start event processing.
+            processing.start();
             
-            // Start the event processing thread.
-            startEventProcessingThread();
-
-            // Setup the system status monitor table.
-            //setupSystemStatusMonitor();
-
             // Start thread which will trigger a disconnect if the event processing finishes.
             //startSessionWatchdogThread();            
 
-            logger.info("successfully started the monitoring session");
+            //logger.info("successfully started the monitoring session");
 
         } catch (Exception e) {
 
-            logger.severe("error occurred while setting up the session");
+            //logger.severe("error occurred while setting up the session");
 
             // Log the error that occurred.
             errorHandler.setError(e).log().printStackTrace();
 
             // Disconnect from the session.
-            //disconnect(ConnectionStatus.ERROR);
+            // FIXME: This should never be needed as connected should only be set at end w/o errors.
+            disconnect();
 
         } finally {
             // Close modal window.
@@ -202,7 +218,7 @@
     /**
      * Connect to the ET system using the current connection settings.
      */
-    private void connect() throws IOException {
+    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.
@@ -210,9 +226,6 @@
 
         // Setup the network connection if using an ET server.
         if (usingEtServer()) {
-
-            setConnectionStatus(ConnectionStatus.CONNECTION_REQUESTED);
-
             // Create a connection to the ET server.
             try {
                 createEtConnection();
@@ -221,10 +234,14 @@
             }
         } else {
             // This is when a direct file source is used and ET is not needed.
-            setConnectionStatus(ConnectionStatus.CONNECTED);
-        }
-    }
-    
+            connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED);
+        }
+    }
+    
+    /**
+     * 
+     * @return
+     */
     boolean usingEtServer() {
         return configurationModel.getDataSourceType().equals(DataSourceType.ET_SERVER);
     }    
@@ -233,7 +250,7 @@
      * Create a connection to an ET system using current parameters from the GUI. If successful, the
      * application's ConnectionStatus is changed to CONNECTED.
      */
-    private void createEtConnection() {
+    void createEtConnection() {
 
         // Setup connection to ET system.
         sessionState.connection = EtSystemUtil.createEtConnection(configurationModel);
@@ -241,29 +258,15 @@
         if (sessionState.connection != null) {
 
             // Set status to connected as there is now a live ET connection.
-            setConnectionStatus(ConnectionStatus.CONNECTED);
-
-            logger.info("successfully connected to ET system");
+            connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED);
+
+            //logger.info("successfully connected to ET system");
 
         } else {
-            // Some error occurred and the connection was not created.
-            setConnectionStatus(ConnectionStatus.ERROR);
-
             errorHandler.setError(new RuntimeException("Failed to create ET connection.")).log().printStackTrace().raiseException();
         }
     }    
-    
-    /**
-     * Set the connection status.
-     * @param status The connection status.
-     */
-    void setConnectionStatus(ConnectionStatus status) {
-        // FIXME
-        //frame.connectionStatusPanel.setConnectionStatus(status);
-        logger.info("connection status changed to: " + status.name());
-        logHandler.flush();
-    }
-    
+        
     void resetPlots() {
 
         // Clear the static AIDA tree in case plots are hanging around from previous sessions.
@@ -272,164 +275,261 @@
         // Reset plots.
         frame.plotPanel.reset();
     }           
-    
-    /**
-     * Setup the LCSim job manager and the event builder.
-     */
-    void setupLCSim() {
-
-        logger.info("setting up LCSim");
-
-        // Get steering resource or file as a String parameter.
-        String steering = null;
-        SteeringType steeringType = configurationModel.getSteeringType();
-        if (steeringType.equals(SteeringType.FILE))
-            try {
-                steering = configurationModel.getSteeringFile().getCanonicalPath();
-            } catch (IOException e) {
-                throw new RuntimeException(e);
+                          
+    /**
+     * The action handler method for the application.
+     * @param e The event to handle.
+     */
+    public void actionPerformed(ActionEvent e) {
+
+        System.out.println("MonitoringApplication.actionPerformed - " + e.getActionCommand());
+
+        String cmd = e.getActionCommand();
+        if (CONNECT.equals(cmd)) {
+            // Run the start session method on a 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 (SAVE_PLOTS.equals(cmd)) {
+            //savePlots();
+        } else if (CHOOSE_LOG_FILE.equals(cmd)) {
+            //chooseLogFile();
+        } else if (LOG_TO_TERMINAL.equals(cmd)) {
+            //logToTerminal();
+        } else if (SCREENSHOT.equals(cmd)) {
+            //chooseScreenshot();
+        } else if (EXIT.equals(cmd)) {
+            //exit();
+        } else if (SAVE_LOG_TABLE.equals(cmd)) {
+            //saveLogTableToFile();
+        } else if (CLEAR_LOG_TABLE.equals(cmd)) {
+            //clearLogTable();
+        } else if (PAUSE.equals(cmd)) {
+            //pauseEventProcessing();
+        } else if (NEXT.equals(cmd)) {
+            //nextEvent();
+        } else if (RESUME.equals(cmd)) {
+            //resumeEventProcessing();
+        } else if (LOG_LEVEL_CHANGED.equals(cmd)) {
+            //setLogLevel();
+        } else if (AIDA_AUTO_SAVE.equals(cmd)) {
+            //getJobSettingsPanel().chooseAidaAutoSaveFile();
+        } else if (SETTINGS_SHOW.equals(cmd)) {
+            showConfigurationDialog();
+        } else if (SETTINGS_LOAD.equals(cmd)) {
+            //chooseConfigurationFile();
+        } else if (SETTINGS_SAVE.equals(cmd)) {
+            //updateLayoutConfiguration(); /* Save current GUI layout settings first, if needed. */
+            //saveConfigurationFile();
+        } else if (SAVE_LAYOUT.equals(cmd)) {
+            //setSaveLayout();
+        } else if (RESTORE_DEFAULT_GUI_LAYOUT.equals(cmd)) {
+            //restoreDefaultLayout();
+        } else if (VALIDATE_DATA_FILE.equals(cmd)) {
+            //if (fileValidationThread == null) {
+            //    new FileValidationThread().start();
+            //}
+        } else if (RESET_PLOTS.equals(cmd)) {
+            //resetAidaTree();
+        } else if (SETTINGS_LOAD_DEFAULT.equals(cmd)) {
+            loadDefaultSettings();
+            DialogUtil.showInfoDialog(frame,
+                    "Default Configuration Loaded", 
+                    "The default configuration was loaded from resource " + '\n' + DEFAULT_CONFIGURATION);
+        } else if (OPEN_FILE.equals(cmd)) {
+            openFile();
+        }
+    }
+        
+    /**
+     * 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();
+
+        // Update state of GUI to disconnected.
+        //setDisconnectedGuiState();
+
+        // Change application state to disconnected.
+        connectionModel.setConnectionStatus(ConnectionStatus.DISCONNECTED);
+
+        //logger.info("Disconnected from the session.");
+    }    
+    
+    /**
+     * Cleanup the ET connection.
+     */
+    void cleanupEtConnection() {
+        if (sessionState.connection != null) {
+            if (sessionState.connection.getEtSystem().alive()) {
+                //logger.fine("cleaning up ET connection");
+                sessionState.connection.cleanup();
+                //logger.fine("done cleaning up tET connection");
             }
-        else
-            steering = configurationModel.getSteeringResource();
-
-        logger.config("Set steering to " + steering + " with type " + (steeringType == SteeringType.RESOURCE ? "RESOURCE" : "FILE"));
+            sessionState.connection = null;
+        }
+    }
+    
+    /**
+     * Configure the system status monitor panel for a new job.
+     */
+    void setupSystemStatusMonitor() {
+        // Clear the system status monitor table.
+        frame.systemStatusTable.getTableModel().clear();
+
+        // Get the global registry of SystemStatus objects.
+        SystemStatusRegistry registry = SystemStatusRegistry.getSystemStatusRegistery();
+
+        // Process the SystemStatus objects.
+        for (SystemStatus systemStatus : registry.getSystemStatuses()) {
+            // Add a row to the table for every SystemStatus.
+            frame.systemStatusTable.getTableModel().addSystemStatus(systemStatus);
+
+            // Add this class as a listener so all status changes can be logged.
+            systemStatus.addListener(this);
+        }
+    }
+    
+    /**
+     * Hook for logging all status changes from the system status monitor.
+     */
+    @Override
+    public void statusChanged(SystemStatus status) {
+
+        // Choose the appropriate log level.
+        Level level = Level.INFO;
+        if (status.getStatusCode().equals(Level.WARNING)) {
+            level = Level.WARNING;
+        } else if (status.getStatusCode().ordinal() >= StatusCode.ERROR.ordinal()) {
+            level = Level.SEVERE;
+        }
+
+        // Log all status changes.
+        //logger.log(level, "STATUS, " + "subsys: " + status.getSubsystem() + ", " 
+        //        + "code: " + status.getStatusCode().name() 
+        //        + ", " + "descr: " + status.getDescription() 
+        //       + ", " + "mesg: " + status.getMessage());
+    }
+    
+    /**
+     * Stop the session by killing the event processing thread, ending the job, and disconnecting
+     * from the ET system.
+     */
+    void stopSession() {
+        // Show a modal message window while this method executes.
+        //JDialog dialog = DialogUtil.showStatusDialog(this, "Info", "Disconnecting from session ...");
 
         try {
-            // Create and the job manager.  The conditions manager is instantiated from this call but not configured.
-            sessionState.jobManager = new JobManager();
+            // Log message.
+            //logger.log(Level.FINER, "stopping the session");
+
+            // Kill the watchdog thread which looks for disconnects, if it is active.
+            //killSessionWatchdogThread();
+
+            // Automatically write AIDA file from job settings.
+            //saveAidaFile();
+
+            // 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));
+        }
+    }       
+    
+    void loadDefaultSettings() {
+        configuration = new Configuration(DEFAULT_CONFIGURATION);
+        configurationModel.setConfiguration(configuration);
+    }
+    
+    void showConfigurationDialog() {
+        frame.settingsDialog.setVisible(true);
+    }
+    
+    /**
+     * This is a simple file filter that will accept files with ".evio" anywhere in their name. 
+     */
+    static class EvioFileFilter extends FileFilter {
+
+        public EvioFileFilter() {            
+        }
+        
+        @Override
+        public boolean accept(File pathname) {
+            if (pathname.getName().contains(".evio") || pathname.isDirectory()) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+        
+        @Override
+        public String getDescription() {
+            return "EVIO files";
+        }        
+    }
+    
+    /**
+     * Open a file data source using a <code>JFileChooser</code>.
+     */
+    static FileFilter lcioFilter = new FileNameExtensionFilter("LCIO files", "slcio");
+    static EvioFileFilter evioFilter = new EvioFileFilter();
+    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();
+            configurationModel.setDataSourcePath(filePath);
             
-            if (configurationModel.hasValidProperty(ConfigurationModel.DETECTOR_ALIAS_PROPERTY)) {
-                // Set a detector alias.                
-                ConditionsReader.addAlias(configurationModel.getDetectorName(), "file://" + configurationModel.getDetectorAlias());
-                logger.config("using detector alias " + configurationModel.getDetectorAlias());
+            // Set data source type.
+            FileFilter filter = fc.getFileFilter();
+            if (filter == lcioFilter) {
+                configurationModel.setDataSourceType(DataSourceType.LCIO_FILE);
+            } else if (filter == evioFilter) {
+                configurationModel.setDataSourceType(DataSourceType.EVIO_FILE);
             }
-                        
-            // Setup the event builder to translate from EVIO to LCIO.
-            // This must happen before Driver setup so the builder's listeners are activated first!
-            createEventBuilder();
-            
-            // Configure the job manager for the XML steering.
-            sessionState.jobManager.setPerformDryRun(true);
-            if (steeringType == SteeringType.RESOURCE) {
-                setupSteeringResource(steering);
-            } else if (steeringType.equals(SteeringType.FILE)) {
-                setupSteeringFile(steering);
-            }
-           
-            // Is there a user specified run number from the JobPanel?
-            if (configurationModel.hasValidProperty(ConfigurationModel.USER_RUN_NUMBER_PROPERTY)) {
-                int userRunNumber = configurationModel.getUserRunNumber();
-                String detectorName = configurationModel.getDetectorName();
-                DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
-                logger.config("setting user run number " + userRunNumber + " with detector " + detectorName);
-                conditionsManager.setDetector(configurationModel.getDetectorName(), userRunNumber);
-                if (configurationModel.hasPropertyKey(ConfigurationModel.FREEZE_CONDITIONS_PROPERTY)) {
-                    // Freeze the conditions system to ignore run numbers from the events.  
-                    logger.config("user configured to freeze conditions system from monitoring app");
-                    conditionsManager.freeze();
-                } else {
-                    // Allow run numbers to be picked up from the events.
-                    logger.config("user run number specified but conditions system is NOT frozen");
-                    conditionsManager.unfreeze();
-                }
-            }
-
-            logger.info("LCSim setup was successful.");
-
-        } catch (Throwable t) {
-            // Catch all errors and rethrow them as RuntimeExceptions.
-            errorHandler.setError(t).setMessage("Error setting up LCSim.").printStackTrace().raiseException();
-        }
-    }
-
-    void setupSteeringFile(String steering) {
-        logger.config("setting up steering file: " + steering);
-        sessionState.jobManager.setup(new File(steering));
-    }
-
-    void setupSteeringResource(String steering) throws IOException {
-        logger.config("setting up steering resource: " + steering);
-        InputStream is = this.getClass().getClassLoader().getResourceAsStream(steering);
-        if (is == null)
-            throw new IOException("Steering resource is not accessible or does not exist.");
-        sessionState.jobManager.setup(is);
-        is.close();
-    }
-        
-    /**
-     * Create the event builder for converting EVIO events to LCSim.
-     */
-    void createEventBuilder() {
-
-        // Get the class for the event builder.
-        String eventBuilderClassName = configurationModel.getEventBuilderClassName();
-
-        logger.config("initializing event builder: " + eventBuilderClassName);
-
-        try {
-            // Create a new instance of the builder class.
-            sessionState.eventBuilder = (LCSimEventBuilder) Class.forName(eventBuilderClassName).newInstance();
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to create LCSimEventBuilder.", e);
-        }
-
-        // Add the builder as a listener so it is notified when conditions change.
-        ConditionsManager.defaultInstance().addConditionsListener(sessionState.eventBuilder);
-
-        logger.config("successfully initialized event builder: " + eventBuilderClassName);
-    }
-    
-    void setupCompositeLoop() {
-
-        CompositeLoopConfiguration loopConfig = new CompositeLoopConfiguration()
-            .setStopOnEndRun(configurationModel.getDisconnectOnEndRun())
-            .setStopOnErrors(configurationModel.getDisconnectOnError())
-            .setDataSourceType(configurationModel.getDataSourceType())
-            .setProcessingStage(configurationModel.getProcessingStage())
-            .setEtConnection(sessionState.connection)
-            .setFilePath(configurationModel.getDataSourcePath())
-            .setLCSimEventBuilder(sessionState.eventBuilder)
-            .setDetectorName(configurationModel.getDetectorName());
-
-        if (configurationModel.hasValidProperty(ConfigurationModel.MAX_EVENTS_PROPERTY)) {
-            long maxEvents = configurationModel.getMaxEvents();
-            if (maxEvents > 0L) {
-                logger.config("processing will stop after max events: " + maxEvents);
-                loopConfig.setMaxRecords(maxEvents);
-            }
-        }
-        
-        // Add all Drivers from the JobManager.
-        for (Driver driver : sessionState.jobManager.getDriverExecList()) {
-            loopConfig.add(driver);
-        }
-
-        // Using ET server?
-        if (usingEtServer()) {
-
-            // ET system monitor.
-            loopConfig.add(new EtSystemMonitor());
-
-            // ET system strip charts.
-            loopConfig.add(new EtSystemStripCharts());
-        }
-
-        // RunPanel updater.
-        loopConfig.add(frame.runPanel.new RunModelUpdater());
-                
-        // Setup for conditions activation via EVIO events.
-        loopConfig.add(new EvioDetectorConditionsProcessor(configurationModel.getDetectorName()));
-
-        // Create the CompositeLoop with the configuration.
-        sessionState.loop = new CompositeLoop(loopConfig);        
+        }
     }    
     
-    void startEventProcessingThread() {
-        
-        // Create the processing thread.
-        sessionState.processingThread = new EventProcessingThread(sessionState.loop);
-
-        // Start the processing thread.
-        sessionState.processingThread.start();
-    }
+    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();
+            //log(Level.CONFIG, "Saving configuration to file <" + f.getPath() + ">");
+            configuration.writeToFile(f);
+        }
+    }
+    
+    
 }

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	Tue Mar  3 19:46:30 2015
@@ -2,16 +2,25 @@
 
 import java.awt.BorderLayout;
 import java.awt.Dimension;
+import java.awt.FlowLayout;
 import java.awt.GraphicsConfiguration;
 import java.awt.Rectangle;
 import java.awt.event.ActionListener;
 
+import javax.swing.BoxLayout;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
 import javax.swing.JFrame;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
+import javax.swing.JSeparator;
 import javax.swing.JSplitPane;
 import javax.swing.JTabbedPane;
+import javax.swing.SwingConstants;
 
+import org.hps.monitoring.application.DataSourceComboBox.DataSourceItem;
+import org.hps.monitoring.application.model.ConfigurationModel;
+import org.hps.monitoring.application.model.ConnectionStatusModel;
 import org.hps.monitoring.application.model.RunModel;
 
 /**
@@ -24,33 +33,77 @@
     PlotPanel plotPanel;
     PlotInfoPanel plotInfoPanel;
     LogTable logTable;
+    SystemStatusTable systemStatusTable;
+    JPanel buttonsPanel;
     
-    GraphicsConfiguration graphics = this.getGraphicsConfiguration();
-    Rectangle bounds = graphics.getBounds();
+    SettingsDialog settingsDialog;
+    
+    // Proportional layout parameters relative to the screen size.
+    static final double FULL_SIZE = 1.0;
+    static final double TOP_PANEL_HEIGHT = 0.05;
+    static final double BOTTOM_PANEL_HEIGHT = FULL_SIZE - TOP_PANEL_HEIGHT;
+    static final double LEFT_PANEL_WIDTH = 0.3;
+    static final double RIGHT_PANEL_WIDTH = FULL_SIZE - LEFT_PANEL_WIDTH;
+    static final double PLOT_PANEL_HEIGHT = 0.8;
     
     /**
      * 
      * @param listener
      */
-    public MonitoringApplicationFrame(ActionListener listener) {
+    public MonitoringApplicationFrame(
+            ConfigurationModel configurationModel, 
+            RunModel runModel, 
+            ConnectionStatusModel connectionModel, 
+            ActionListener listener) {
                 
         // Create the content panel.
         JPanel contentPanel = new JPanel();
-        contentPanel.setLayout(new BorderLayout());
-        contentPanel.setPreferredSize(scaleBounds(1.0, 1.0));
         setContentPane(contentPanel);
+        contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
+        contentPanel.setOpaque(true);
+        setProportionalSize(contentPanel, FULL_SIZE, FULL_SIZE);
         
         // Create the top panel.
         JPanel topPanel = new JPanel();
-        topPanel.setPreferredSize(scaleBounds(1.0, 0.1));
+        topPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 0));
+        setProportionalSize(topPanel, FULL_SIZE, TOP_PANEL_HEIGHT);
+        contentPanel.add(topPanel);
+        
+        // Create the connection status panel.
+        JPanel connectionPanel = new ConnectionStatusPanel(connectionModel);
+        topPanel.add(connectionPanel);
+        
+        // Add vertical separator.
+        JSeparator sep = new JSeparator(SwingConstants.VERTICAL);
+        sep.setPreferredSize(new Dimension(5, topPanel.getPreferredSize().height));
+        topPanel.add(sep);
+        
+        // Create the buttons panel.
+        buttonsPanel = new EventButtonsPanel(connectionModel, listener);
+        topPanel.add(buttonsPanel);
+        
+        // Add vertical separator.
+        sep = new JSeparator(SwingConstants.VERTICAL);
+        sep.setPreferredSize(new Dimension(5, topPanel.getPreferredSize().height));
+        topPanel.add(sep);
+        
+        // Add the data source combo box.
+        JComboBox<DataSourceItem> dataSourceComboBox = new DataSourceComboBox(listener);
+        topPanel.add(dataSourceComboBox);
+        
+        // Create the bottom panel.
+        JPanel bottomPanel = new JPanel();
+        bottomPanel.setLayout(new BorderLayout());
+        setProportionalSize(bottomPanel, FULL_SIZE, BOTTOM_PANEL_HEIGHT);
+        contentPanel.add(bottomPanel);
                                 
         // Create the left panel.
         JPanel leftPanel = new JPanel();
         leftPanel.setLayout(new BorderLayout());
-        leftPanel.setPreferredSize(scaleBounds(0.3, 1.0));
+        setProportionalSize(leftPanel, LEFT_PANEL_WIDTH, FULL_SIZE);
                         
         // Create the run dashboard.
-        runPanel = new RunPanel();
+        runPanel = new RunPanel(runModel);
 
         // Create the tabbed pane for content in bottom of left panel such as log table and system monitor.
         JTabbedPane tableTabbedPane = new JTabbedPane();
@@ -60,7 +113,7 @@
         tableTabbedPane.addTab("Log", new JScrollPane(logTable));
         
         // Create the system monitor.
-        SystemStatusTable systemStatusTable = new SystemStatusTable();
+        systemStatusTable = new SystemStatusTable();
         tableTabbedPane.addTab("System Status Monitor", new JScrollPane(systemStatusTable));
         
         // Vertical split pane in left panel.
@@ -76,48 +129,48 @@
                 
         // Create the plot panel.
         plotPanel = new PlotPanel();
-        plotPanel.setPreferredSize(scaleBounds(0.7, 0.8));
+        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.setPreferredSize(scaleBounds(0.7, 1.0));
+        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);
-        contentPanel.add(mainSplitPane, BorderLayout.CENTER);
+        bottomPanel.add(mainSplitPane, BorderLayout.CENTER);
         
         // Create the menu bar.
-        setJMenuBar(new MenuBar(listener));
-        
-        // Setup the frame now that all components have been added.
+        setJMenuBar(new MenuBar(listener));                
+                        
+        // Setup the frame now that all components have been added.        
         pack();
         setExtendedState(JFrame.MAXIMIZED_BOTH);
         setVisible(true);
+        
+        // Setup the settings dialog box.
+        settingsDialog = new SettingsDialog(configurationModel, listener);
     }
     
     /**
-     * Scale the screen bounds of the <code>JFrame</code> by the given proportions.
+     * Set the size of a Swing component using proportions of the current screen bounds.
+     * @param component The component to resize.
      * @param scaleX The X scaling (must be between 0 and 1).
      * @param scaleY The Y scaling (must be between 0 and 1).
+     * @param setSize Call the setSize method as well as setPreferredSize (which is the default).
      * @return
      */
-    Dimension scaleBounds(double scaleX, double scaleY) {                
+    void setProportionalSize(JComponent component, double scaleX, double scaleY) {                    
+        GraphicsConfiguration graphics = this.getGraphicsConfiguration();        
+        Rectangle bounds = graphics.getBounds();        
         if (scaleX < 0 || scaleX > 1) {
             throw new IllegalArgumentException("scaleX must be > 0 and <= 1.");
         }
         if (scaleY < 0 || scaleY > 1) {
-            throw new IllegalArgumentException("scaleX must be > 0 and <= 1.");
+            throw new IllegalArgumentException("scaleY must be > 0 and <= 1.");
         }
-        return new Dimension((int)(bounds.getX() * scaleX), (int)(bounds.getY() * scaleX));
-    }        
-    
-    /**
-     * 
-     * @param runModel
-     */
-    void setRunModel(RunModel runModel) {
-        runPanel.setModel(runModel);
-    }    
+        Dimension scaledDimension = new Dimension((int)(bounds.getWidth() * scaleX), (int)(bounds.getHeight() * scaleY));
+        component.setPreferredSize(scaledDimension);
+    }           
 }

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	Tue Mar  3 19:46:30 2015
@@ -261,33 +261,33 @@
     public void propertyChange(PropertyChangeEvent evt) {
         Object value = evt.getNewValue();
         if (RUN_NUMBER_PROPERTY.equals(evt.getPropertyName())) {
-            this.runNumberField.setValue((Integer) value);
+            runNumberField.setValue((Integer) value);
         } else if (START_DATE_PROPERTY.equals(evt.getPropertyName())) {
             if (value != null)
-                this.startDateField.setValue((Date) value);
+                startDateField.setValue((Date) value);
             else
-                this.startDateField.setValue("");
+                startDateField.setValue("");
         } else if (END_DATE_PROPERTY.equals(evt.getPropertyName())) {
             if (value != null)
-                this.endDateField.setValue((Date) value);
+                endDateField.setValue((Date) value);
             else
-                this.endDateField.setValue("");
+                endDateField.setValue("");
         } else if (RUN_LENGTH_PROPERTY.equals(evt.getPropertyName())) {
-            this.lengthField.setValue((Integer) value);
+            lengthField.setValue((Integer) value);
         } else if (TOTAL_EVENTS_PROPERTY.equals(evt.getPropertyName())) {
-            this.totalEventsField.setValue((Integer) value);
+            totalEventsField.setValue((Integer) value);
         } else if (EVENTS_RECEIVED_PROPERTY.equals(evt.getPropertyName())) {
-            this.eventsReceivedField.setValue((Integer) value);
+            eventsReceivedField.setValue((Integer) value);
         } else if (ELAPSED_TIME_PROPERTY.equals(evt.getPropertyName())) {
-            this.elapsedTimeField.setValue((Integer) value);
+            elapsedTimeField.setValue((Integer) value);
         } else if (DATA_RECEIVED_PROPERTY.equals(evt.getPropertyName())) {
-            this.dataReceivedField.setValue(formatter.format((Double) value));
+            dataReceivedField.setValue(formatter.format((Double) value));
         } else if (EVENT_NUMBER_PROPERTY.equals(evt.getPropertyName())) {
-            this.eventNumberField.setValue((Integer) value);
+            eventNumberField.setValue((Integer) value);
         } else if (DATA_RATE_PROPERTY.equals(evt.getPropertyName())) {
-            this.dataRateField.setValue(formatter.format((Double) value));
+            dataRateField.setValue(formatter.format((Double) value));
         } else if (EVENT_RATE_PROPERTY.equals(evt.getPropertyName())) {
-            this.eventRateField.setValue(formatter.format((Double) value));
+            eventRateField.setValue(formatter.format((Double) value));
         }
     }
 }

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	Tue Mar  3 19:46:30 2015
@@ -14,10 +14,14 @@
  */
 public class SettingsDialog extends JDialog {
 
-    final SettingsPanel settingsPanel = new SettingsPanel(this);
+    final SettingsPanel settingsPanel;
 
-    public SettingsDialog() {
+    public SettingsDialog(ConfigurationModel configurationModel, ActionListener listener) {
 
+        // Initialize the GUI panel.
+        settingsPanel = new SettingsPanel(this, configurationModel, listener);
+        
+        // Configure the frame.
         setTitle("Settings");
         setContentPane(settingsPanel);
         setResizable(false);
@@ -25,26 +29,11 @@
         setModalityType(ModalityType.APPLICATION_MODAL);
         pack();
 
+        // Add window listener for turning invisible when closing.
         addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent e) {
                 setVisible(false);
             }
-        });
+        });        
     }
-
-    public SettingsPanel getSettingsPanel() {
-        return settingsPanel;
-    }
-    
-    void addActionListener(ActionListener listener) {
-        settingsPanel.addActionListener(listener);
-        settingsPanel.getJobSettingsPanel().addActionListener(listener);
-        settingsPanel.getDataSourcePanel().addActionListener(listener);
-    }
-    
-    void setConfigurationModel(ConfigurationModel model) {
-        settingsPanel.getJobSettingsPanel().setConfigurationModel(model);
-        settingsPanel.getConnectionPanel().setConfigurationModel(model);
-        settingsPanel.getDataSourcePanel().setConfigurationModel(model);
-    }    
 }

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	Tue Mar  3 19:46:30 2015
@@ -12,25 +12,41 @@
 import javax.swing.JPanel;
 import javax.swing.JTabbedPane;
 
+import org.hps.monitoring.application.model.ConfigurationModel;
+
 /**
  * The container component with the tabs that have job and connection settings.
  */
 public class SettingsPanel extends JPanel implements ActionListener {
 
     JTabbedPane tabs;
-    JobSettingsPanel jobPanel = new JobSettingsPanel();
-    ConnectionSettingsPanel connectionPanel = new ConnectionSettingsPanel();
-    DataSourcePanel dataSourcePanel = new DataSourcePanel();
+    JobSettingsPanel jobPanel;
+    ConnectionSettingsPanel connectionPanel;
+    DataSourcePanel dataSourcePanel;
     static final String OKAY_COMMAND = "settingsOkay";
 
-    JButton defaultsButton;
+    //JButton defaultsButton;
 
     JDialog parent;
 
-    SettingsPanel(JDialog parent) {
+    SettingsPanel(JDialog parent, ConfigurationModel configurationModel, ActionListener listener) {
 
         this.parent = parent;
-
+        
+        connectionPanel = new ConnectionSettingsPanel();        
+        jobPanel = new JobSettingsPanel();
+        dataSourcePanel = new DataSourcePanel();
+        
+        // Push configuration to sub-components.
+        connectionPanel.setConfigurationModel(configurationModel);
+        jobPanel.setConfigurationModel(configurationModel);
+        dataSourcePanel.setConfigurationModel(configurationModel);
+        
+        // Add ActionListener to sub-components.
+        connectionPanel.addActionListener(listener);
+        jobPanel.addActionListener(listener);
+        dataSourcePanel.addActionListener(listener);
+               
         this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
 
         tabs = new JTabbedPane();
@@ -43,14 +59,14 @@
         okayButton.setActionCommand(OKAY_COMMAND);
         okayButton.addActionListener(this);
 
-        defaultsButton = new JButton("Defaults");
-        defaultsButton.setActionCommand(Commands.LOAD_DEFAULT_CONFIG_FILE);
-        defaultsButton.addActionListener(this);
+        //defaultsButton = new JButton("Defaults");
+        //defaultsButton.setActionCommand(Commands.LOAD_DEFAULT_SETTINGS);
+        //defaultsButton.addActionListener(this);
 
         add(Box.createRigidArea(new Dimension(1, 5)));
         JPanel buttonsPanel = new JPanel();
         buttonsPanel.add(okayButton);
-        buttonsPanel.add(defaultsButton);
+        //buttonsPanel.add(defaultsButton);
         buttonsPanel.setLayout(new FlowLayout());
         add(buttonsPanel);
         add(Box.createRigidArea(new Dimension(1, 5)));
@@ -80,7 +96,7 @@
      * the default configuration when the "Defaults" button is pushed from the settings panel.
      * @param listener
      */
-    void addActionListener(ActionListener listener) {
-        defaultsButton.addActionListener(listener);
-    }
+    //void addActionListener(ActionListener listener) {
+    //    defaultsButton.addActionListener(listener);
+    //}
 }

Modified: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/AbstractModel.java
 =============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/AbstractModel.java	(original)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/AbstractModel.java	Tue Mar  3 19:46:30 2015
@@ -35,26 +35,27 @@
     public void removePropertyChangeListener(PropertyChangeListener listener) {
         propertyChangeSupport.removePropertyChangeListener(listener);
     }
-
+       
     protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
-        if (listenersEnabled)
+        System.out.println("AbstractModel.firePropertyChange");
+        System.out.println("  propName: " + propertyName);
+        System.out.println("  oldValue: " + oldValue);
+        System.out.println("  newValue: " + newValue);
+        if (listenersEnabled) {
             propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
-        // System.out.println("firePropertyChange");
-        // System.out.println("  name: " + propertyName);
-        // System.out.println("  old value: " + oldValue);
-        // System.out.println("  new value: " + newValue);
+        }
     }
 
     protected void firePropertyChange(PropertyChangeEvent evt) {
-        if (listenersEnabled)
+        if (listenersEnabled) {
             propertyChangeSupport.firePropertyChange(evt);
+        }
     }
 
     abstract public String[] getPropertyNames();
 
-    // FIXME: This method is kind of a hack. Any other good way to do this?
-    public void fireAllChanged() {
-        // System.out.println("AbstractModel.fireAllChanged");
+    public void fireModelChanged() {
+        //System.out.println("AbstractModel.fireModelChanged");
         if (!listenersEnabled)
             return;
         propertyLoop: for (String property : getPropertyNames()) {
@@ -76,7 +77,7 @@
                     throw new RuntimeException("Property " + property + " is missing a get method.", e);
                 } catch (InvocationTargetException e) {
                     // Is the cause of the problem an illegal argument to the method?
-                    System.out.println("cause: " + e.getCause().getMessage());
+                    //System.out.println("cause: " + e.getCause().getMessage());
                     if (e.getCause() instanceof IllegalArgumentException) {
                         // For this error, assume that the key itself is missing from the configuration which is a warning.
                         System.err.println("The key " + property + " is not set in the configuration.");
@@ -100,7 +101,8 @@
     }
 
     /**
-     * This method will statically extract property names from a class, which in this package's conventions are statically declared, public strings that end with "_PROPERTY".
+     * This method will statically extract property names from a class, which in this package's conventions are statically declared, 
+     * public strings that end with "_PROPERTY".
      * 
      * @param type The class with the properties.
      * @return The list of property names.

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	Tue Mar  3 19:46:30 2015
@@ -1,10 +1,7 @@
 package org.hps.monitoring.application.model;
 
 import java.io.File;
-import java.lang.reflect.Field;
 import java.util.logging.Level;
-
-import javassist.Modifier;
 
 import org.hps.monitoring.application.SteeringType;
 import org.hps.record.enums.DataSourceType;
@@ -15,12 +12,9 @@
  * A model of the global configuration parameters that can be used to automatically update the GUI
  * from a configuration or push changes from GUI components into the current configuration.
  */
-// FIXME: When the set methods are called, e.g. from GUI updates, this triggers
-//        a property change event that pushes the values back to the GUI again.
-// FIXME: Should check if property exists in set methods before retrieving old value for all set methods.
 public final class ConfigurationModel extends AbstractModel {
 
-    Configuration config;
+    Configuration configuration;
 
     // Job setting properties.
     public static final String AIDA_AUTO_SAVE_PROPERTY = "AidaAutoSave";
@@ -35,10 +29,6 @@
     public static final String LOG_LEVEL_PROPERTY = "LogLevel";
     public static final String LOG_TO_FILE_PROPERTY = "LogToFile";
     public static final String MAX_EVENTS_PROPERTY = "MaxEvents";
-    public static final String MONITORING_APPLICATION_LAYOUT_PROPERTY = "MonitoringApplicationLayout";
-    public static final String PLOT_FRAME_LAYOUT_PROPERTY = "PlotFrameLayout";
-    public static final String SAVE_LAYOUT_PROPERTY = "SaveLayout";
-    public static final String SYSTEM_STATUS_FRAME_LAYOUT_PROPERTY = "SystemStatusFrameLayout";
     public static final String STEERING_TYPE_PROPERTY = "SteeringType";
     public static final String STEERING_FILE_PROPERTY = "SteeringFile";
     public static final String STEERING_RESOURCE_PROPERTY = "SteeringResource";
@@ -66,77 +56,89 @@
     static final String[] CONFIG_PROPERTIES = AbstractModel.getPropertyNames(ConfigurationModel.class);
         
     public ConfigurationModel() {
-        this.config = new Configuration();
-    }
-
-    public ConfigurationModel(Configuration config) {
-        this.config = config;
-    }
-
-    public void setConfiguration(Configuration config) {
-        this.config = config;
-        fireAllChanged();
+        this.configuration = new Configuration();
+    }
+
+    public ConfigurationModel(Configuration configuration) {
+        this.configuration = configuration;
+        fireModelChanged();
+    }
+
+    public void setConfiguration(Configuration configuration) {
+        this.configuration = configuration;
+        fireModelChanged();
     }
 
     public Configuration getConfiguration() {
-        return this.config;
+        return this.configuration;
     }
 
     public Level getLogLevel() {
-        return Level.parse(config.get(LOG_LEVEL_PROPERTY));
+        return Level.parse(configuration.get(LOG_LEVEL_PROPERTY));
     }
 
     public void setLogLevel(Level level) {
         Level oldValue = getLogLevel();
-        config.set(LOG_LEVEL_PROPERTY, level.getName());
-        firePropertyChange(LOG_LEVEL_PROPERTY, oldValue, getLogLevel());
+        if (!oldValue.equals(level)) {
+            configuration.set(LOG_LEVEL_PROPERTY, level.getName());
+            firePropertyChange(LOG_LEVEL_PROPERTY, oldValue, getLogLevel());
+        }
     }
 
     public SteeringType getSteeringType() {
-        return SteeringType.valueOf(config.get(STEERING_TYPE_PROPERTY));
+        return SteeringType.valueOf(configuration.get(STEERING_TYPE_PROPERTY));
     }
 
     public void setSteeringType(SteeringType steeringType) {
         SteeringType oldValue = getSteeringType();
-        config.set(STEERING_TYPE_PROPERTY, steeringType.name());
-        firePropertyChange(STEERING_TYPE_PROPERTY, oldValue, getSteeringType());
+        if (!steeringType.equals(oldValue)) {
+            configuration.set(STEERING_TYPE_PROPERTY, steeringType.name());
+            firePropertyChange(STEERING_TYPE_PROPERTY, oldValue, getSteeringType());
+        }
     }
 
     public File getSteeringFile() {
-        if (config.hasKey(STEERING_FILE_PROPERTY))
-            return new File(config.get(STEERING_FILE_PROPERTY));
-        else
+        if (configuration.hasKey(STEERING_FILE_PROPERTY)) {
+            return new File(configuration.get(STEERING_FILE_PROPERTY));
+        } else {
             return null;
+        }
     }
 
     public void setSteeringFile(String steeringFile) {
         File oldValue = getSteeringFile();
-        config.set(STEERING_FILE_PROPERTY, steeringFile);
-        firePropertyChange(STEERING_FILE_PROPERTY, oldValue, getSteeringFile().getPath());
+        if (!steeringFile.equals(oldValue)) {
+            configuration.set(STEERING_FILE_PROPERTY, steeringFile);
+            firePropertyChange(STEERING_FILE_PROPERTY, oldValue, getSteeringFile().getPath());
+        }
     }
 
     public String getSteeringResource() {
-        return config.get(STEERING_RESOURCE_PROPERTY);
+        return configuration.get(STEERING_RESOURCE_PROPERTY);
     }
 
     public void setSteeringResource(String steeringResource) {
         String oldValue = getSteeringResource();
-        config.set(STEERING_RESOURCE_PROPERTY, steeringResource);
-        firePropertyChange(STEERING_RESOURCE_PROPERTY, oldValue, steeringResource);
+        if (!steeringResource.equals(oldValue)) {
+            configuration.set(STEERING_RESOURCE_PROPERTY, steeringResource);
+            firePropertyChange(STEERING_RESOURCE_PROPERTY, oldValue, steeringResource);
+        }
     }
 
     public String getDetectorName() {
-        return config.get(DETECTOR_NAME_PROPERTY);
+        return configuration.get(DETECTOR_NAME_PROPERTY);
     }
 
     public void setDetectorName(String detectorName) {
         String oldValue = getDetectorName();
-        config.set(DETECTOR_NAME_PROPERTY, detectorName);
-        firePropertyChange(DETECTOR_NAME_PROPERTY, oldValue, getDetectorName());
+        if (!detectorName.equals(oldValue)) {
+            configuration.set(DETECTOR_NAME_PROPERTY, detectorName);
+            firePropertyChange(DETECTOR_NAME_PROPERTY, oldValue, getDetectorName());
+        }
     }
     
     public String getDetectorAlias() {
-        return config.get(DETECTOR_ALIAS_PROPERTY);
+        return configuration.get(DETECTOR_ALIAS_PROPERTY);
     }
     
     public void setDetectorAlias(String detectorAlias) {
@@ -144,231 +146,277 @@
         if (hasPropertyKey(DETECTOR_ALIAS_PROPERTY)) {
             oldValue = getDetectorAlias();
         }
-        config.set(DETECTOR_ALIAS_PROPERTY, detectorAlias);
-        firePropertyChange(DETECTOR_ALIAS_PROPERTY, oldValue, getDetectorAlias());
+        if (!detectorAlias.equals(oldValue)) {
+            configuration.set(DETECTOR_ALIAS_PROPERTY, detectorAlias);
+            firePropertyChange(DETECTOR_ALIAS_PROPERTY, oldValue, getDetectorAlias());
+        }
     }
     
 
     public String getEventBuilderClassName() {
-        return config.get(EVENT_BUILDER_PROPERTY);
+        return configuration.get(EVENT_BUILDER_PROPERTY);
     }
 
     public void setEventBuilderClassName(String eventBuilderClassName) {
         String oldValue = getEventBuilderClassName();
-        config.set(EVENT_BUILDER_PROPERTY, eventBuilderClassName);
-        firePropertyChange(EVENT_BUILDER_PROPERTY, oldValue, getEventBuilderClassName());
+        if (!eventBuilderClassName.equals(oldValue)) {
+            configuration.set(EVENT_BUILDER_PROPERTY, eventBuilderClassName);
+            firePropertyChange(EVENT_BUILDER_PROPERTY, oldValue, getEventBuilderClassName());
+        }
     }
 
     public Boolean getLogToFile() {
-        return config.getBoolean(LOG_TO_FILE_PROPERTY);
-    }
-
-    public void setLogToFile(boolean logToFile) {
+        return configuration.getBoolean(LOG_TO_FILE_PROPERTY);
+    }
+
+    public void setLogToFile(Boolean logToFile) {
         Boolean oldValue = getLogToFile();
-        config.set(LOG_TO_FILE_PROPERTY, logToFile);
-        firePropertyChange(LOG_TO_FILE_PROPERTY, oldValue, getLogToFile());
+        if (!oldValue.equals(logToFile)) {
+            configuration.set(LOG_TO_FILE_PROPERTY, logToFile);
+            firePropertyChange(LOG_TO_FILE_PROPERTY, oldValue, getLogToFile());
+        }
     }
 
     public String getLogFileName() {
-        return config.get(LOG_FILE_NAME_PROPERTY);
+        return configuration.get(LOG_FILE_NAME_PROPERTY);
     }
 
     public void setLogFileName(String logFileName) {
         String oldValue = getLogFileName();
-        config.set(LOG_FILE_NAME_PROPERTY, logFileName);
-        firePropertyChange(LOG_FILE_NAME_PROPERTY, oldValue, getLogFileName());
+        if (!logFileName.equals(oldValue)) {
+            configuration.set(LOG_FILE_NAME_PROPERTY, logFileName);
+            firePropertyChange(LOG_FILE_NAME_PROPERTY, oldValue, getLogFileName());
+        }
     }
 
     public Boolean getAidaAutoSave() {
-        return config.equals(AIDA_AUTO_SAVE_PROPERTY);
-    }
-
-    public void setAidaAutoSave(boolean aidaAutoSave) {
+        return configuration.equals(AIDA_AUTO_SAVE_PROPERTY);
+    }
+
+    public void setAidaAutoSave(Boolean aidaAutoSave) {
         Boolean oldValue = getAidaAutoSave();
-        config.set(AIDA_AUTO_SAVE_PROPERTY, aidaAutoSave);
-        firePropertyChange(AIDA_AUTO_SAVE_PROPERTY, oldValue, aidaAutoSave);
+        if (!aidaAutoSave.equals(oldValue)) {
+            configuration.set(AIDA_AUTO_SAVE_PROPERTY, aidaAutoSave);
+            firePropertyChange(AIDA_AUTO_SAVE_PROPERTY, oldValue, aidaAutoSave);
+        }
     }
 
     public String getAidaFileName() {
-        return config.get(AIDA_FILE_NAME_PROPERTY);
+        return configuration.get(AIDA_FILE_NAME_PROPERTY);
     }
 
     public void setAidaFileName(String aidaFileName) {
         String oldValue = getAidaFileName();
-        config.set(AIDA_FILE_NAME_PROPERTY, aidaFileName);
-        firePropertyChange(AIDA_FILE_NAME_PROPERTY, oldValue, aidaFileName);
+        if (!aidaFileName.equals(oldValue)) {
+            configuration.set(AIDA_FILE_NAME_PROPERTY, aidaFileName);
+            firePropertyChange(AIDA_FILE_NAME_PROPERTY, oldValue, aidaFileName);
+        }
     }
 
     public Boolean getDisconnectOnError() {
-        return config.getBoolean(DISCONNECT_ON_ERROR_PROPERTY);
-    }
-
-    public void setDisconnectOnError(boolean disconnectOnError) {
+        return configuration.getBoolean(DISCONNECT_ON_ERROR_PROPERTY);
+    }
+
+    public void setDisconnectOnError(Boolean disconnectOnError) {
         Boolean oldValue = getDisconnectOnError();
-        config.set(DISCONNECT_ON_ERROR_PROPERTY, disconnectOnError);
-        firePropertyChange(DISCONNECT_ON_ERROR_PROPERTY, oldValue, getDisconnectOnError());
+        if (!disconnectOnError.equals(oldValue)) {
+            configuration.set(DISCONNECT_ON_ERROR_PROPERTY, disconnectOnError);
+            firePropertyChange(DISCONNECT_ON_ERROR_PROPERTY, oldValue, getDisconnectOnError());
+        }
     }
 
     public Boolean getDisconnectOnEndRun() {
-        return config.getBoolean(DISCONNECT_ON_END_RUN_PROPERTY);
-    }
-
-    public void setDisconnectOnEndRun(boolean disconnectOnEndRun) {
+        return configuration.getBoolean(DISCONNECT_ON_END_RUN_PROPERTY);
+    }
+
+    public void setDisconnectOnEndRun(Boolean disconnectOnEndRun) {
         Boolean oldValue = getDisconnectOnEndRun();
-        config.set(DISCONNECT_ON_END_RUN_PROPERTY, disconnectOnEndRun);
-        firePropertyChange(DISCONNECT_ON_END_RUN_PROPERTY, oldValue, getDisconnectOnEndRun());
+        if (!disconnectOnEndRun.equals(oldValue)) {
+            configuration.set(DISCONNECT_ON_END_RUN_PROPERTY, disconnectOnEndRun);
+            firePropertyChange(DISCONNECT_ON_END_RUN_PROPERTY, oldValue, getDisconnectOnEndRun());
+        }
     }
 
     public DataSourceType getDataSourceType() {
-        return DataSourceType.valueOf(config.get(DATA_SOURCE_TYPE_PROPERTY));
+        return DataSourceType.valueOf(configuration.get(DATA_SOURCE_TYPE_PROPERTY));
     }
 
     public void setDataSourceType(DataSourceType dataSourceType) {
         DataSourceType oldValue = getDataSourceType();
-        config.set(DATA_SOURCE_TYPE_PROPERTY, dataSourceType);
-        firePropertyChange(DATA_SOURCE_TYPE_PROPERTY, oldValue, getDataSourceType());
+        if (!dataSourceType.equals(oldValue)) {
+            configuration.set(DATA_SOURCE_TYPE_PROPERTY, dataSourceType);
+            firePropertyChange(DATA_SOURCE_TYPE_PROPERTY, oldValue, getDataSourceType());
+        }
     }
 
     public String getDataSourcePath() {
-        return config.get(DATA_SOURCE_PATH_PROPERTY);
+        return configuration.get(DATA_SOURCE_PATH_PROPERTY);
     }
 
     public void setDataSourcePath(String dataSourcePath) {
         String oldValue = getDataSourcePath();
-        config.set(DATA_SOURCE_PATH_PROPERTY, dataSourcePath);
-        firePropertyChange(DATA_SOURCE_PATH_PROPERTY, oldValue, getDataSourcePath());
+        if (!dataSourcePath.equals(oldValue)) {
+            configuration.set(DATA_SOURCE_PATH_PROPERTY, dataSourcePath);
+            firePropertyChange(DATA_SOURCE_PATH_PROPERTY, oldValue, getDataSourcePath());
+        }
     }
 
     public ProcessingStage getProcessingStage() {
-        if (config.get(PROCESSING_STAGE_PROPERTY) == null)
+        if (configuration.get(PROCESSING_STAGE_PROPERTY) == null)
             throw new RuntimeException(PROCESSING_STAGE_PROPERTY + " is null!!!");
-        return ProcessingStage.valueOf(config.get(PROCESSING_STAGE_PROPERTY));
+        return ProcessingStage.valueOf(configuration.get(PROCESSING_STAGE_PROPERTY));
     }
 
     public void setProcessingStage(ProcessingStage processingStage) {
         ProcessingStage oldValue = getProcessingStage();
-        config.set(PROCESSING_STAGE_PROPERTY, processingStage);
-        firePropertyChange(PROCESSING_STAGE_PROPERTY, oldValue, getProcessingStage());
+        if (!processingStage.equals(oldValue)) {
+            configuration.set(PROCESSING_STAGE_PROPERTY, processingStage);
+            firePropertyChange(PROCESSING_STAGE_PROPERTY, oldValue, getProcessingStage());
+        }
     }
 
     public String getEtName() {
-        return config.get(ET_NAME_PROPERTY);
+        return configuration.get(ET_NAME_PROPERTY);
     }
 
     public void setEtName(String etName) {
         String oldValue = getEtName();
-        config.set(ET_NAME_PROPERTY, etName);
-        firePropertyChange(ET_NAME_PROPERTY, oldValue, getEtName());
+        if (!etName.equals(oldValue)) {
+            configuration.set(ET_NAME_PROPERTY, etName);
+            firePropertyChange(ET_NAME_PROPERTY, oldValue, getEtName());
+        }
     }
 
     public String getHost() {
-        return config.get(HOST_PROPERTY);
+        return configuration.get(HOST_PROPERTY);
     }
 
     public void setHost(String host) {
         String oldValue = getHost();
-        config.set(HOST_PROPERTY, host);
-        firePropertyChange(HOST_PROPERTY, oldValue, getHost());
+        if (!host.equals(oldValue)) {
+            configuration.set(HOST_PROPERTY, host);
+            firePropertyChange(HOST_PROPERTY, oldValue, getHost());
+        }
     }
 
     public Integer getPort() {
-        return config.getInteger(PORT_PROPERTY);
-    }
-
-    public void setPort(int port) {
+        return configuration.getInteger(PORT_PROPERTY);
+    }
+
+    public void setPort(Integer port) {
         Integer oldValue = getPort();
-        config.set(PORT_PROPERTY, port);
-        firePropertyChange(PORT_PROPERTY, oldValue, getPort());
+        if (!port.equals(oldValue)) {
+            configuration.set(PORT_PROPERTY, port);
+            firePropertyChange(PORT_PROPERTY, oldValue, getPort());
+        }
     }
 
     public Boolean getBlocking() {
-        return config.getBoolean(BLOCKING_PROPERTY);
-    }
-
-    public void setBlocking(boolean blocking) {
+        return configuration.getBoolean(BLOCKING_PROPERTY);
+    }
+
+    public void setBlocking(Boolean blocking) {
         Boolean oldValue = getBlocking();
-        config.set(BLOCKING_PROPERTY, blocking);
-        firePropertyChange(BLOCKING_PROPERTY, oldValue, getBlocking());
+        if (!blocking.equals(oldValue)) {
+            configuration.set(BLOCKING_PROPERTY, blocking);
+            firePropertyChange(BLOCKING_PROPERTY, oldValue, getBlocking());
+        }
     }
 
     public Boolean getVerbose() {
-        return config.getBoolean(VERBOSE_PROPERTY);
-    }
-
-    public void setVerbose(boolean verbose) {
+        return configuration.getBoolean(VERBOSE_PROPERTY);
+    }
+
+    public void setVerbose(Boolean verbose) {
         Boolean oldValue = getVerbose();
-        config.set(VERBOSE_PROPERTY, verbose);
-        firePropertyChange(VERBOSE_PROPERTY, oldValue, getVerbose());
+        if (!verbose.equals(oldValue)) {
+            configuration.set(VERBOSE_PROPERTY, verbose);
+            firePropertyChange(VERBOSE_PROPERTY, oldValue, getVerbose());
+        }
     }
 
     public String getStationName() {
-        return config.get(STATION_NAME_PROPERTY);
+        return configuration.get(STATION_NAME_PROPERTY);
     }
 
     public void setStationName(String stationName) {
         String oldValue = getStationName();
-        config.set(STATION_NAME_PROPERTY, stationName);
-        firePropertyChange(STATION_NAME_PROPERTY, oldValue, getStationName());
+        if (!stationName.equals(oldValue)) {
+            configuration.set(STATION_NAME_PROPERTY, stationName);
+            firePropertyChange(STATION_NAME_PROPERTY, oldValue, getStationName());
+        }
     }
 
     public Integer getChunkSize() {
-        return config.getInteger(CHUNK_SIZE_PROPERTY);
-    }
-
-    public void setChunkSize(int chunkSize) {
+        return configuration.getInteger(CHUNK_SIZE_PROPERTY);
+    }
+
+    public void setChunkSize(Integer chunkSize) {
         Integer oldValue = getChunkSize();
-        config.set(CHUNK_SIZE_PROPERTY, chunkSize);
-        firePropertyChange(CHUNK_SIZE_PROPERTY, oldValue, getChunkSize());
+        if (!chunkSize.equals(oldValue)) {
+            configuration.set(CHUNK_SIZE_PROPERTY, chunkSize);
+            firePropertyChange(CHUNK_SIZE_PROPERTY, oldValue, getChunkSize());
+        }
     }
 
     public Integer getQueueSize() {
-        return config.getInteger(QUEUE_SIZE_PROPERTY);
-    }
-
-    public void setQueueSize(int queueSize) {
+        return configuration.getInteger(QUEUE_SIZE_PROPERTY);
+    }
+
+    public void setQueueSize(Integer queueSize) {
         Integer oldValue = getQueueSize();
-        config.set(QUEUE_SIZE_PROPERTY, queueSize);
-        firePropertyChange(QUEUE_SIZE_PROPERTY, oldValue, getQueueSize());
+        if (!queueSize.equals(oldValue)) {
+            configuration.set(QUEUE_SIZE_PROPERTY, queueSize);
+            firePropertyChange(QUEUE_SIZE_PROPERTY, oldValue, getQueueSize());
+        }
     }
 
     public Integer getStationPosition() {
-        return config.getInteger(STATION_POSITION_PROPERTY);
-    }
-
-    public void setStationPosition(int stationPosition) {
+        return configuration.getInteger(STATION_POSITION_PROPERTY);
+    }
+
+    public void setStationPosition(Integer stationPosition) {
         Integer oldValue = getStationPosition();
-        config.set(STATION_POSITION_PROPERTY, stationPosition);
-        firePropertyChange(STATION_POSITION_PROPERTY, oldValue, getStationPosition());
+        if (!stationPosition.equals(oldValue)) {
+            configuration.set(STATION_POSITION_PROPERTY, stationPosition);
+            firePropertyChange(STATION_POSITION_PROPERTY, oldValue, getStationPosition());
+        }
     }
 
     public Mode getWaitMode() {
-        return Mode.valueOf(config.get(WAIT_MODE_PROPERTY));
+        return Mode.valueOf(configuration.get(WAIT_MODE_PROPERTY));
     }
 
     public void setWaitMode(Mode waitMode) {
         Mode oldValue = getWaitMode();
-        config.set(WAIT_MODE_PROPERTY, waitMode.name());
-        firePropertyChange(WAIT_MODE_PROPERTY, oldValue, getWaitMode());
+        if (!waitMode.equals(oldValue)) {
+            configuration.set(WAIT_MODE_PROPERTY, waitMode.name());
+            firePropertyChange(WAIT_MODE_PROPERTY, oldValue, getWaitMode());
+        }
     }
 
     public Integer getWaitTime() {
-        return config.getInteger(WAIT_TIME_PROPERTY);
-    }
-
-    public void setWaitTime(int waitTime) {
+        return configuration.getInteger(WAIT_TIME_PROPERTY);
+    }
+
+    public void setWaitTime(Integer waitTime) {
         Integer oldValue = getWaitTime();
-        config.set(WAIT_TIME_PROPERTY, waitTime);
-        firePropertyChange(WAIT_TIME_PROPERTY, oldValue, getWaitTime());
+        if (!waitTime.equals(oldValue)) {
+            configuration.set(WAIT_TIME_PROPERTY, waitTime);
+            firePropertyChange(WAIT_TIME_PROPERTY, oldValue, getWaitTime());
+        }
     }
 
     public Integer getPrescale() {
-        return config.getInteger(PRESCALE_PROPERTY);
-    }
-
-    public void setPrescale(int prescale) {
+        return configuration.getInteger(PRESCALE_PROPERTY);
+    }
+
+    public void setPrescale(Integer prescale) {
         Integer oldValue = getPrescale();
-        config.set(PRESCALE_PROPERTY, prescale);
-        firePropertyChange(PRESCALE_PROPERTY, oldValue, getPrescale());
+        if (!prescale.equals(oldValue)) {
+            configuration.set(PRESCALE_PROPERTY, prescale);
+            firePropertyChange(PRESCALE_PROPERTY, oldValue, getPrescale());
+        }
     }
     
     public void setUserRunNumber(Integer userRunNumber) {
@@ -376,98 +424,64 @@
         if (hasPropertyKey(USER_RUN_NUMBER_PROPERTY)) {
             oldValue = getUserRunNumber();
         }
-        config.set(USER_RUN_NUMBER_PROPERTY, userRunNumber);
-        firePropertyChange(USER_RUN_NUMBER_PROPERTY, oldValue, getUserRunNumber());
+        if (!userRunNumber.equals(oldValue)) {                   
+            configuration.set(USER_RUN_NUMBER_PROPERTY, userRunNumber);
+            firePropertyChange(USER_RUN_NUMBER_PROPERTY, oldValue, getUserRunNumber());
+        }
     }
     
     public Integer getUserRunNumber() {
-        return config.getInteger(USER_RUN_NUMBER_PROPERTY);
-    }
-    
-    public void setFreezeConditions(boolean freezeConditions) {
+        return configuration.getInteger(USER_RUN_NUMBER_PROPERTY);
+    }
+    
+    public void setFreezeConditions(Boolean freezeConditions) {
         Boolean oldValue = null;
         if (hasPropertyKey(FREEZE_CONDITIONS_PROPERTY)) {
             oldValue = getFreezeConditions();
         }
-        config.set(FREEZE_CONDITIONS_PROPERTY, freezeConditions);
-        firePropertyChange(FREEZE_CONDITIONS_PROPERTY, oldValue, freezeConditions);
+        if (!freezeConditions.equals(oldValue)) {
+            configuration.set(FREEZE_CONDITIONS_PROPERTY, freezeConditions);
+            firePropertyChange(FREEZE_CONDITIONS_PROPERTY, oldValue, freezeConditions);
+        }
     }
     
     public Boolean getFreezeConditions() {
-        return config.getBoolean(FREEZE_CONDITIONS_PROPERTY);
-    }
-
-    public Boolean getSaveLayout() {
-        return config.getBoolean(SAVE_LAYOUT_PROPERTY);
-    }
-
-    public void setSaveLayout(boolean saveLayout) {
-        Boolean oldValue = getSaveLayout();
-        config.set(SAVE_LAYOUT_PROPERTY, saveLayout);
-        firePropertyChange(SAVE_LAYOUT_PROPERTY, oldValue, getSaveLayout());
-    }
-
-    public String getMonitoringApplicationLayout() {
-        return config.get(MONITORING_APPLICATION_LAYOUT_PROPERTY);
-    }
-
-    public void setMonitoringApplicationLayout(String layout) {
-        String oldValue = getMonitoringApplicationLayout();
-        config.set(MONITORING_APPLICATION_LAYOUT_PROPERTY, layout);
-        firePropertyChange(MONITORING_APPLICATION_LAYOUT_PROPERTY, oldValue, getMonitoringApplicationLayout());
-    }
-
-    public String getSystemStatusFrameLayout() {
-        return config.get(SYSTEM_STATUS_FRAME_LAYOUT_PROPERTY);
-    }
-
-    public void setSystemStatusFrameLayout(String layout) {
-        String oldValue = getSystemStatusFrameLayout();
-        config.set(SYSTEM_STATUS_FRAME_LAYOUT_PROPERTY, layout);
-        firePropertyChange(SYSTEM_STATUS_FRAME_LAYOUT_PROPERTY, oldValue, getSystemStatusFrameLayout());
-    }
-
-    public String getPlotFrameLayout() {
-        return config.get(PLOT_FRAME_LAYOUT_PROPERTY);
-    }
-
-    public void setPlotFrameLayout(String layout) {
-        String oldValue = getPlotFrameLayout();
-        config.set(PLOT_FRAME_LAYOUT_PROPERTY, layout);
-        firePropertyChange(PLOT_FRAME_LAYOUT_PROPERTY, oldValue, getPlotFrameLayout());
-    }
-    
-    public void setMaxEvents(long maxEvents) {
-        //System.out.println("ConfigurationModel.setMaxEvents - " + maxEvents);
+        return configuration.getBoolean(FREEZE_CONDITIONS_PROPERTY);
+    }
+    
+    public void setMaxEvents(Long maxEvents) {
         Long oldValue = getMaxEvents();
-        config.set(MAX_EVENTS_PROPERTY, maxEvents);
-        firePropertyChange(MAX_EVENTS_PROPERTY, oldValue, getMaxEvents());
+        if (!maxEvents.equals(oldValue)) {
+            configuration.set(MAX_EVENTS_PROPERTY, maxEvents);
+            firePropertyChange(MAX_EVENTS_PROPERTY, oldValue, getMaxEvents());
+        }
     }
     
     public Long getMaxEvents() {
-        return config.getLong(MAX_EVENTS_PROPERTY);
+        return configuration.getLong(MAX_EVENTS_PROPERTY);
     }
 
     public void remove(String property) {
         if (hasPropertyKey(property)) {
-            Object oldValue = config.get(property);
+            Object oldValue = configuration.get(property);
             if (oldValue != null) {
-                config.remove(property);
+                configuration.remove(property);
                 firePropertyChange(property, oldValue, null);
             }
         }
     }
     
     public boolean hasPropertyKey(String key) {
-        return config.hasKey(key);
+        return configuration.hasKey(key);
     }
     
     public boolean hasValidProperty(String key) {
-        return config.hasKey(key) && config.get(key) != null;
+        return configuration.hasKey(key) && configuration.get(key) != null;
     }
         
     @Override
     public String[] getPropertyNames() {
         return CONFIG_PROPERTIES;
     }
-}
+}
+    

Added: 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	(added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java	Tue Mar  3 19:46:30 2015
@@ -0,0 +1,50 @@
+package org.hps.monitoring.application.model;
+
+import org.hps.monitoring.application.ConnectionStatus;
+
+/**
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ *
+ */
+public class ConnectionStatusModel extends AbstractModel {
+    
+    public static final String CONNECTION_STATUS_PROPERTY = "ConnectionStatus";
+    public static final String PAUSED_PROPERTY = "ConnectionStatus";
+    
+    static final String[] propertyNames = new String[] { 
+        CONNECTION_STATUS_PROPERTY, 
+        PAUSED_PROPERTY 
+    };
+
+    ConnectionStatus connectionStatus = ConnectionStatus.DISCONNECTED;
+    boolean paused = false;
+    
+    public String[] getPropertyNames() {
+        return propertyNames;
+    }
+    
+    public ConnectionStatus getConnectionStatus() {
+        return connectionStatus;
+    }
+    
+    public void setConnectionStatus(ConnectionStatus connectionStatus) {
+        if (connectionStatus != this.connectionStatus) {
+            ConnectionStatus oldValue = connectionStatus;
+            this.connectionStatus = connectionStatus;
+            firePropertyChange(CONNECTION_STATUS_PROPERTY, oldValue, this.connectionStatus);
+        }
+    }        
+    
+    public boolean getPaused() {
+        return paused;
+    }
+    
+    public void setPaused(boolean paused) {
+        if (paused != this.paused) {
+            boolean oldValue = this.paused;
+            this.paused = paused;
+            firePropertyChange(PAUSED_PROPERTY, oldValue, paused);
+        }
+    }
+}

Added: java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/util/ResourceUtil.java
 =============================================================================
--- java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/util/ResourceUtil.java	(added)
+++ java/branches/monitoring-app-HPSJAVA-442/src/main/java/org/hps/monitoring/application/util/ResourceUtil.java	Tue Mar  3 19:46:30 2015
@@ -0,0 +1,119 @@
+package org.hps.monitoring.application.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.hps.record.LCSimEventBuilder;
+import org.reflections.Reflections;
+
+/**
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ *
+ */
+public class ResourceUtil {
+
+    private ResourceUtil() {        
+    }
+    
+    /**
+     * Get the files with extension 'lcsim' from all loaded jar files.
+     * @param packageName The package name for filtering the resources.
+     * @return A list of embedded steering file resources.
+     */
+    public static String[] findSteeringResources(String packageName) {
+        List<String> resources = new ArrayList<String>();
+        URL url = ResourceUtil.class.getResource("ResourceUtil.class");
+        String scheme = url.getProtocol();
+        if (!"jar".equals(scheme)) {
+            throw new IllegalArgumentException("Unsupported scheme.  Only jar is allowed.");
+        }
+        try {
+            JarURLConnection con = (JarURLConnection) url.openConnection();
+            JarFile archive = con.getJarFile();
+            Enumeration<JarEntry> entries = archive.entries();
+            while (entries.hasMoreElements()) {
+                JarEntry entry = entries.nextElement();
+                if (entry.getName().endsWith(".lcsim") && entry.getName().contains(packageName)) {
+                    resources.add(entry.getName());
+                }
+            }
+            archive.close();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        java.util.Collections.sort(resources);
+        String[] arr = new String[resources.size()];
+        for (int i = 0; i < arr.length; i++) {
+            arr[i] = resources.get(i);
+        }
+        return arr;
+    }
+    
+    /**
+     * Find all classes that implement {@link org.hps.record.LCSimEventBuilder} and return
+     * a list of their canonical names.
+     * @return The list of classes implementing LCSimEventBuilder.
+     */
+    public static String[] findEventBuilderClassNames() {
+        Reflections reflections = new Reflections("org.hps");
+        Set<Class<? extends LCSimEventBuilder>> subTypes = reflections.getSubTypesOf(LCSimEventBuilder.class);
+        Set<String> classNames = new HashSet<String>();
+        for (Class<? extends LCSimEventBuilder> type : subTypes) {
+            classNames.add(type.getCanonicalName());
+        }
+        return classNames.toArray(new String[classNames.size()]);        
+    }
+ 
+    /**
+     * Find a list of available detector names.
+     * Only those detectors that have names starting with "HPS" in their
+     * detector.properties files will be returned.
+     * @return The list of available detector names.
+     */
+    public static String[] findDetectorNames() {
+        ClassLoader classLoader = ResourceUtil.class.getClassLoader();
+        List<String> detectorNames = new ArrayList<String>();
+        URL url = ResourceUtil.class.getResource("ResourceUtil.class");
+        String protocol = url.getProtocol();
+        if (!"jar".equals(protocol)) {
+            throw new RuntimeException("Unsupported URL protocol: " + url.getProtocol());
+        }
+        try {
+            JarURLConnection con = (JarURLConnection) url.openConnection();
+            JarFile archive = con.getJarFile();
+            Enumeration<JarEntry> entries = archive.entries();
+            while (entries.hasMoreElements()) {
+                JarEntry entry = entries.nextElement();
+                if (entry.getName().endsWith("detector.properties")) {
+                    InputStream inputStream = classLoader.getResourceAsStream(entry.getName());
+                    if (inputStream == null) {
+                        throw new RuntimeException("Failed to load jar entry: " + entry.getName());
+                    }
+                    Properties properties = new Properties();
+                    properties.load(inputStream);
+                    String detectorName = properties.getProperty("name");
+                    if (detectorName.startsWith("HPS")) {
+                        detectorNames.add(detectorName);
+                    }
+                }
+            }
+            archive.close();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        Collections.sort(detectorNames);
+        return detectorNames.toArray(new String[detectorNames.size()]);
+    }        
+}

Added: java/branches/monitoring-app-HPSJAVA-442/src/main/resources/monitoringButtonGraphics/connected-128.png
 =============================================================================
Binary file - no diff available.

Added: java/branches/monitoring-app-HPSJAVA-442/src/main/resources/monitoringButtonGraphics/disconnected-128.png
 =============================================================================
Binary file - no diff available.