Print

Print


Author: [log in to unmask]
Date: Thu Apr  9 13:15:57 2015
New Revision: 2669

Log:
Cleanup to monitoring-app code (work in progress).

Modified:
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/AddActionListener.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsPanel.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java
    java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java	Thu Apr  9 13:15:57 2015
@@ -21,59 +21,315 @@
 import org.hps.monitoring.application.model.HasConfigurationModel;
 
 /**
- * A <code>JPanel</code> which has a number of fields with the labels in the first column and the
- * components for showing/editing the fields in the second. It uses <code>GridBagConstraints</code>
- * for layout.
+ * A <code>JPanel</code> which has a number of fields with the labels in the first column and the components for
+ * showing/editing the fields in the second. It uses <code>GridBagConstraints</code> for layout.
  */
-// TODO: This should use features of JFormattedTextField instead of plain JTextField.
-abstract class AbstractFieldsPanel extends JPanel implements PropertyChangeListener, HasConfigurationModel, ActionListener, AddActionListener {
-
-    private int currY = 0;
-    private Insets insets;
+@SuppressWarnings("serial")
+abstract class AbstractFieldsPanel extends JPanel implements PropertyChangeListener, HasConfigurationModel,
+        ActionListener, AddActionListener {
+
+    /**
+     * Default button height in pixels.
+     */
+    private static final int DEFAULT_BUTTON_HEIGHT = 50;
+
+    /**
+     * Default button width in pixels.
+     */
+    private static final int DEFAULT_BUTTON_WIDTH = 100;
+
+    /**
+     * The configuration model for the component.
+     */
+    private ConfigurationModel configurationModel;
+
+    /**
+     * Grid Y which is incremented as components are added.
+     */
+    private int currentGridY = 0;
+
+    /**
+     * Flag which sets if this component and its children are editable.
+     */
     private boolean editable = false;
-    
-    protected ConfigurationModel configurationModel;
+
+    /**
+     * The default insets used for all internal <code>GridBagConstraints</code>.
+     */
+    private final Insets insets;
 
     /**
      * Class constructor.
+     */
+    protected AbstractFieldsPanel() {
+        this.insets = new Insets(1, 1, 1, 1);
+    }
+
+    /**
+     * Class constructor.
+     *
      * @param insets The insets for the panel.
      * @param editable Editable setting.
      */
-    protected AbstractFieldsPanel(Insets insets, boolean editable) {
+    protected AbstractFieldsPanel(final Insets insets, final boolean editable) {
         this.insets = insets;
         this.editable = editable;
     }
 
     /**
-     * Class constructor.
-     */
-    protected AbstractFieldsPanel() {
-        this.insets = new Insets(1, 1, 1, 1);
+     * True if property change event should be accepted.
+     *
+     * @param evt the property change event
+     * @return <code>true</code> if property change event should be accepted
+     */
+    boolean accept(final PropertyChangeEvent evt) {
+        if (evt.getPropertyName().equals("ancestor")) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Add an ActionListener to this component. By default this does nothing, but individual sub-components should
+     * attach this to individual components.
+     *
+     * @param listener The AcitonListener to add.
+     */
+    @Override
+    public void addActionListener(final ActionListener listener) {
+        // Sub-classes should add the listener to the appropriate child components.
+    }
+
+    /**
+     * Add a button with text.
+     *
+     * @param text the text in the button
+     * @return the button component
+     */
+    protected final JButton addButton(final String text) {
+        final GridBagConstraints c = new GridBagConstraints();
+        c.gridx = 0;
+        c.gridy = this.currentGridY;
+        c.insets = this.insets;
+        c.anchor = GridBagConstraints.WEST;
+        c.gridwidth = 2;
+        final JButton button = new JButton(text);
+        button.setSize(new Dimension(DEFAULT_BUTTON_WIDTH, DEFAULT_BUTTON_HEIGHT));
+        this.add(button, c);
+        ++this.currentGridY;
+        return button;
+    }
+
+    /**
+     * Add a check box.
+     *
+     * @param name The name of the check box.
+     * @param selected Whether the check box is selected or not.
+     * @param enabled Whether it is enabled or not.
+     * @return The JCheckBox component.
+     */
+    protected final JCheckBox addCheckBox(final String name, final boolean selected, final boolean enabled) {
+
+        GridBagConstraints c = new GridBagConstraints();
+        c.gridx = 0;
+        c.gridy = this.currentGridY;
+        c.insets = this.insets;
+        c.anchor = GridBagConstraints.WEST;
+        final JLabel label = new JLabel(name + ":");
+        this.add(label, c);
+
+        c = new GridBagConstraints();
+        c.gridx = 1;
+        c.gridy = this.currentGridY;
+        c.insets = this.insets;
+        c.anchor = GridBagConstraints.EAST;
+        final JCheckBox checkbox = new JCheckBox();
+        checkbox.setSelected(selected);
+        checkbox.setEnabled(enabled);
+        this.add(checkbox, c);
+
+        ++this.currentGridY;
+
+        return checkbox;
+    }
+
+    /**
+     * Add a check box.
+     *
+     * @param name The name of the check box.
+     * @param tooltip The tooltip text.
+     * @param selected Whether the box is selected or not.
+     * @param enabled Whether it is enabled or not.
+     * @return The JCheckBox component.
+     */
+    protected final JCheckBox addCheckBox(final String name, final String tooltip, final boolean selected,
+            final boolean enabled) {
+        final JCheckBox c = this.addCheckBox(name, selected, enabled);
+        c.setToolTipText(tooltip);
+        return c;
+    }
+
+    /**
+     * Add a combo box.
+     *
+     * @param name The name of the combo box.
+     * @param values The set of values for the combo box.
+     * @return The JComboBox component.
+     */
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    protected final JComboBox addComboBox(final String name, final String[] values) {
+
+        GridBagConstraints c = new GridBagConstraints();
+        c.gridx = 0;
+        c.gridy = this.currentGridY;
+        c.insets = this.insets;
+        c.anchor = GridBagConstraints.WEST;
+        final JLabel waitModeLabel = new JLabel(name);
+        waitModeLabel.setHorizontalAlignment(JLabel.LEFT);
+        this.add(waitModeLabel, c);
+
+        c = new GridBagConstraints();
+        c.gridx = 1;
+        c.gridy = this.currentGridY;
+        c.insets = this.insets;
+        c.anchor = GridBagConstraints.EAST;
+        final JComboBox combo = new JComboBox(values);
+        combo.setEditable(this.editable);
+        this.add(combo, c);
+
+        ++this.currentGridY;
+
+        return combo;
+    }
+
+    /**
+     * Add a multiline combo box.
+     *
+     * @param name The name of the combo box.
+     * @param values The values for the combo box.
+     * @return The JComboBox component.
+     */
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    protected final JComboBox addComboBoxMultiline(final String name, final String[] values) {
+
+        GridBagConstraints c = new GridBagConstraints();
+        c.gridx = 0;
+        c.gridwidth = GridBagConstraints.REMAINDER;
+        c.gridy = this.currentGridY;
+        c.insets = this.insets;
+        c.anchor = GridBagConstraints.WEST;
+        final JLabel waitModeLabel = new JLabel(name + ":");
+        waitModeLabel.setHorizontalAlignment(JLabel.LEFT);
+        this.add(waitModeLabel, c);
+        ++this.currentGridY;
+
+        c = new GridBagConstraints();
+        c.gridx = 0;
+        c.gridwidth = GridBagConstraints.REMAINDER;
+        c.gridy = this.currentGridY;
+        c.insets = this.insets;
+        c.anchor = GridBagConstraints.WEST;
+        final JComboBox combo = new JComboBox(values);
+        combo.setEditable(this.editable);
+        this.add(combo, c);
+
+        ++this.currentGridY;
+
+        return combo;
+    }
+
+    /**
+     * Add a labeled JComponent to the panel.
+     *
+     * @param name The label text.
+     * @param component The component to add.
+     */
+    void addComponent(final String name, final JComponent component) {
+
+        // Add the label.
+        GridBagConstraints c = new GridBagConstraints();
+        c.gridx = 0;
+        c.gridy = this.currentGridY;
+        c.insets = this.insets;
+        c.anchor = GridBagConstraints.WEST;
+        final JLabel label = new JLabel(name + ":");
+        this.add(label, c);
+
+        // Add the component.
+        c = new GridBagConstraints();
+        c.gridx = 1;
+        c.gridy = this.currentGridY;
+        c.insets = this.insets;
+        c.anchor = GridBagConstraints.EAST;
+        this.add(component, c);
+
+        ++this.currentGridY;
     }
 
     /**
      * Add a field.
+     *
      * @param name The name of the field.
      * @param size The size of the field.
      * @return The JTextField component.
      */
-    protected final JTextField addField(String name, int size) {
-        return addField(name, "", size, this.editable);
+    protected final JTextField addField(final String name, final int size) {
+        return this.addField(name, "", size, this.editable);
     }
 
     /**
      * Add a field.
+     *
      * @param name The name of the field.
      * @param value The default value of the field.
      * @param size The size of the field.
      * @return The JTextField component.
      */
-    protected final JTextField addField(String name, String value, int size) {
-        return addField(name, value, size, this.editable);
+    protected final JTextField addField(final String name, final String value, final int size) {
+        return this.addField(name, value, size, this.editable);
     }
 
     /**
      * Add a field.
+     *
+     * @param name The name of the field.
+     * @param value The default value of the field.
+     * @param size The size of the field.
+     * @param editable The editable setting.
+     * @return The JTextField component.
+     */
+    protected final JFormattedTextField addField(final String name, final String value, final int size,
+            final boolean editable) {
+        GridBagConstraints c = new GridBagConstraints();
+        c.gridx = 0;
+        c.gridy = this.currentGridY;
+        c.insets = this.insets;
+        c.anchor = GridBagConstraints.WEST;
+        final JLabel label = new JLabel(name + ":");
+        this.add(label, c);
+
+        c = new GridBagConstraints();
+        c.gridx = 1;
+        c.gridy = this.currentGridY;
+        c.insets = this.insets;
+        c.anchor = GridBagConstraints.EAST;
+        // JFormattedTextField field = new JFormattedTextField(value, size);
+        final JFormattedTextField field = new JFormattedTextField(value);
+        field.setColumns(size);
+        field.setHorizontalAlignment(JTextField.RIGHT);
+        field.setEditable(editable);
+        field.setBackground(Color.WHITE);
+        this.add(field, c);
+
+        ++this.currentGridY;
+
+        return field;
+    }
+
+    /**
+     * Add a field.
+     *
      * @param name The name of the field.
      * @param value The default value of the field.
      * @param tooltip The tooltip text.
@@ -81,240 +337,42 @@
      * @param editable The editable setting.
      * @return The JTextField component.
      */
-    protected final JFormattedTextField addField(String name, String value, String tooltip, int size, boolean editable) {
-        JFormattedTextField f = addField(name, value, size, editable);
+    protected final JFormattedTextField addField(final String name, final String value, final String tooltip,
+            final int size, final boolean editable) {
+        final JFormattedTextField f = this.addField(name, value, size, editable);
         f.setToolTipText(tooltip);
         return f;
     }
 
     /**
-     * Add a field.
-     * @param name The name of the field.
-     * @param value The default value of the field.
-     * @param size The size of the field.
-     * @param editable The editable setting.
-     * @return The JTextField component.
-     */
-    protected final JFormattedTextField addField(String name, String value, int size, boolean editable) {
-        GridBagConstraints c = new GridBagConstraints();
-        c.gridx = 0;
-        c.gridy = currY;
-        c.insets = insets;
-        c.anchor = GridBagConstraints.WEST;
-        JLabel label = new JLabel(name + ":");
-        add(label, c);
-
-        c = new GridBagConstraints();
-        c.gridx = 1;
-        c.gridy = currY;
-        c.insets = insets;
-        c.anchor = GridBagConstraints.EAST;
-        // JFormattedTextField field = new JFormattedTextField(value, size);
-        JFormattedTextField field = new JFormattedTextField(value);
-        field.setColumns(size);
-        field.setHorizontalAlignment(JTextField.RIGHT);
-        field.setEditable(editable);
-        field.setBackground(Color.WHITE);
-        add(field, c);
-
-        ++currY;
-
-        return field;
-    }
-
-    /**
-     * Add a combo box.
-     * @param name The name of the combo box.
-     * @param values The set of values for the combo box.
-     * @return The JComboBox component.
-     */
-    protected final JComboBox addComboBox(String name, String[] values) {
-
-        // System.out.println("addComboBox = " + name);
-
-        GridBagConstraints c = new GridBagConstraints();
-        c.gridx = 0;
-        c.gridy = currY;
-        c.insets = insets;
-        c.anchor = GridBagConstraints.WEST;
-        JLabel waitModeLabel = new JLabel(name);
-        waitModeLabel.setHorizontalAlignment(JLabel.LEFT);
-        add(waitModeLabel, c);
-
-        c = new GridBagConstraints();
-        c.gridx = 1;
-        c.gridy = currY;
-        c.insets = insets;
-        c.anchor = GridBagConstraints.EAST;
-        JComboBox combo = new JComboBox(values);
-        // System.out.println("combo width = " + combo.getWidth());
-        // System.out.println("combo width = " + combo.getSize().getWidth());
-        combo.setEditable(editable);
-        add(combo, c);
-
-        ++currY;
-
-        return combo;
-    }
-
-    /**
-     * Add a multiline combo box.
-     * @param name The name of the combo box.
-     * @param values The values for the combo box.
-     * @return The JComboBox component.
-     */
-    protected final JComboBox addComboBoxMultiline(String name, String[] values) {
-
-        GridBagConstraints c = new GridBagConstraints();
-        c.gridx = 0;
-        c.gridwidth = GridBagConstraints.REMAINDER;
-        c.gridy = currY;
-        c.insets = insets;
-        c.anchor = GridBagConstraints.WEST;
-        JLabel waitModeLabel = new JLabel(name + ":");
-        waitModeLabel.setHorizontalAlignment(JLabel.LEFT);
-        add(waitModeLabel, c);
-        ++currY;
-
-        c = new GridBagConstraints();
-        c.gridx = 0;
-        c.gridwidth = GridBagConstraints.REMAINDER;
-        c.gridy = currY;
-        c.insets = insets;
-        c.anchor = GridBagConstraints.WEST;
-        JComboBox combo = new JComboBox(values);
-        // System.out.println("combo width = " + combo.getWidth());
-        // System.out.println("combo width = " + combo.getSize().getWidth());
-        combo.setEditable(editable);
-        add(combo, c);
-
-        ++currY;
-
-        return combo;
-    }
-
-    /**
-     * Add a check box.
-     * @param name The name of the check box.
-     * @param tooltip The tooltip text.
-     * @param selected Whether the box is selected or not.
-     * @param enabled Whether it is enabled or not.
-     * @return The JCheckBox component.
-     */
-    protected final JCheckBox addCheckBox(String name, String tooltip, boolean selected, boolean enabled) {
-        JCheckBox c = addCheckBox(name, selected, enabled);
-        c.setToolTipText(tooltip);
-        return c;
-    }
-
-    /**
-     * Add a check box.
-     * @param name The name of the check box.
-     * @param selected Whether the check box is selected or not.
-     * @param enabled Whether it is enabled or not.
-     * @return The JCheckBox component.
-     */
-    protected final JCheckBox addCheckBox(String name, boolean selected, boolean enabled) {
-
-        GridBagConstraints c = new GridBagConstraints();
-        c.gridx = 0;
-        c.gridy = currY;
-        c.insets = insets;
-        c.anchor = GridBagConstraints.WEST;
-        JLabel label = new JLabel(name + ":");
-        add(label, c);
-
-        c = new GridBagConstraints();
-        c.gridx = 1;
-        c.gridy = currY;
-        c.insets = insets;
-        c.anchor = GridBagConstraints.EAST;
-        JCheckBox checkbox = new JCheckBox();
-        checkbox.setSelected(selected);
-        checkbox.setEnabled(enabled);
-        add(checkbox, c);
-
-        ++currY;
-
-        return checkbox;
-    }
-
-    protected final JButton addButton(String text) {
-        GridBagConstraints c = new GridBagConstraints();
-        c.gridx = 0;
-        c.gridy = currY;
-        c.insets = insets;
-        c.anchor = GridBagConstraints.WEST;
-        c.gridwidth = 2;
-        JButton button = new JButton(text);
-        button.setSize(new Dimension(100, 50));
-        add(button, c);
-        ++currY;
-        return button;
-    }
-
-    /**
-     * Add an ActionListener to this component. By default this does nothing, but individual
-     * sub-components should attach this to individual components.
-     * @param listener The AcitonListener to add.
+     * Get the configuration model for this component.
+     * 
+     * @return the configuration model for the component
      */
     @Override
-    public void addActionListener(ActionListener listener) {
-        // Sub-classes should add the listener to the appropriate child components.
-    }
-    
+    public ConfigurationModel getConfigurationModel() {
+        return this.configurationModel;
+    }
+
+    /**
+     * Handle a property change event.
+     *
+     * @param evt the property change event
+     */
+    @Override
+    public void propertyChange(final PropertyChangeEvent evt) {
+    }
+
     /**
      * Sub-classes should override this method to add their own listeners to update from the model.
+     *
+     * @param model the configuration model
      */
     @Override
-    public void setConfigurationModel(ConfigurationModel model) {
+    public void setConfigurationModel(final 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;
-    }
-    
-    /**
-     * Add a labeled JComponent to the panel.
-     * @param name The label text.
-     * @param component The component to add.
-     */
-    void addComponent(String name, JComponent component) {
-                
-        // Add the label.
-        GridBagConstraints c = new GridBagConstraints();
-        c.gridx = 0;
-        c.gridy = currY;
-        c.insets = insets;
-        c.anchor = GridBagConstraints.WEST;
-        JLabel label = new JLabel(name + ":");
-        add(label, c);
-
-        // Add the component.
-        c = new GridBagConstraints();
-        c.gridx = 1;
-        c.gridy = currY;
-        c.insets = insets;
-        c.anchor = GridBagConstraints.EAST;
-        add(component, c);
-
-        ++currY;
-    }
-    
-    boolean accept(PropertyChangeEvent evt) {
-        if (evt.getPropertyName().equals("ancestor")) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-    
-    @Override
-    public void propertyChange(PropertyChangeEvent evt) {        
-    }    
-}
+    }
+}

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/AddActionListener.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/AddActionListener.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/AddActionListener.java	Thu Apr  9 13:15:57 2015
@@ -2,7 +2,16 @@
 
 import java.awt.event.ActionListener;
 
+/**
+ * Mixin interface for components which can be assigned an external <code>ActionListener</code>.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
 interface AddActionListener {
 
+    /**
+     * Assign an <code>ActionListener</code> to this component which will assign to appropriate child components.
+     * @param listener the <code>ActionListener</code> to assign to this component
+     */
     void addActionListener(ActionListener listener);
 }

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java	Thu Apr  9 13:15:57 2015
@@ -1,85 +1,247 @@
 package org.hps.monitoring.application;
 
 /**
- * These strings are used to identify ActionEvents in the MonitoringApplication. 
- * A few commands handled only by sub-components are not listed here.
+ * These strings are used to identify ActionEvents in the MonitoringApplication. A few commands
+ * handled only by sub-components are not listed here.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
  */
 final class Commands {
 
-    // Settings
+    /**
+     * ET blocking setting changed.
+     */
+    static final String BLOCKING_CHANGED = "blockingChanged";
+
+    /**
+     * Choose a compact file for the detector description.
+     */
+    static final String CHOOSE_COMPACT_FILE = "chooseCompactFile";
+
+    /**
+     * Choose an LCSim job steering file.
+     */
+    static final String CHOOSE_STEERING_FILE = "chooseSteeringFile";
+
+    /**
+     * Clear the log table of all messages.
+     */
+    static final String CLEAR_LOG_TABLE = "clearLogTable";
+
+    /**
+     * Reset the underlying AIDA objects in the plot tree.
+     */
+    static final String CLEAR_PLOTS = "resetPlots";
+
+    /**
+     * Close the current input data file.
+     */
+    static final String CLOSE_FILE = "closeFile";
+
+    /**
+     * Change the current conditions tag.
+     */
+    static final String CONDITIONS_TAG_CHANGED = "conditionsTagChanged";
+
+    /**
+     * Connect to a new session.
+     */
+    static final String CONNECT = "connect";
+
+    /**
+     * Change the current data source.
+     */
+    static final String DATA_SOURCE_CHANGED = "dataSourceChanged";
+
+    /**
+     * Reset the application window to its default settings including scroll pane positions.
+     */
+    static final String DEFAULT_WINDOW = "defaultWindow";
+
+    /**
+     * Detector alias changed.
+     */
+    static final String DETECTOR_ALIAS_CHANGED = "detectorAliasChanged";
+
+    /**
+     * Name of detector changed.
+     */
+    static final String DETECTOR_NAME_CHANGED = "detectorNameChanged";
+
+    /**
+     * Disconnect the current session.
+     */
+    static final String DISCONNECT = "disconnect";
+
+    /**
+     * Disconnect on end run changed.
+     */
+    static final String DISCONNECT_ON_END_RUN_CHANGED = "disconnectOnEndRunChanged";
+
+    /**
+     * Disconnect on error changed.
+     */
+    static final String DISCONNECT_ON_ERROR_CHANGED = "disconnectOnErrorChanged";
+
+    /**
+     * Event builder setting changed.
+     */
+    static final String EVENT_BUILDER_CHANGED = "eventBuilderChanged";
+
+    /**
+     * Exit the application.
+     */
+    static final String EXIT = "exit";
+
+    /**
+     * Freeze conditions system after initialization.
+     */
+    static final String FREEZE_CONDITIONS_CHANGED = "freezeConditionsChanged";
+
+    /**
+     * Load the default properties file from a jar resource.
+     */
+    static final String LOAD_DEFAULT_SETTINGS = "loadDefaultSettings";
+
+    /**
+     * Load a settings properties file.
+     */
     static final String LOAD_SETTINGS = "loadSettings";
-    static final String LOAD_DEFAULT_SETTINGS = "loadDefaultSettings";
+
+    /**
+     * Global log level changed.
+     */
+    static final String LOG_LEVEL_CHANGED = "logLevelChanged";
+
+    /**
+     * Change the log level filter for showing messages in the log table.
+     */
+    static final String LOG_LEVEL_FILTER_CHANGED = "logLevelFilterChanged";
+
+    /**
+     * Send log messages to an output file.
+     */
+    static final String LOG_TO_FILE = "logToFile";
+
+    /**
+     * Send log messages to the terminal.
+     */
+    static final String LOG_TO_TERMINAL = "logToTerminal";
+
+    /**
+     * Maximize the application window.
+     */
+    static final String MAXIMIZE_WINDOW = "maximizeWindow";
+
+    /**
+     * Minimize the application window.
+     */
+    static final String MINIMIZE_WINDOW = "minimizeWindow";
+
+    /**
+     * Get the next event if paused.
+     */
+    static final String NEXT = "next";
+
+    /**
+     * Open an input data file.
+     */
+    static final String OPEN_FILE = "openFile";
+
+    /**
+     * Pause the event processing.
+     */
+    static final String PAUSE = "pause";
+
+    /**
+     * Processing stage changed.
+     */
+    static final String PROCESSING_STAGE_CHANGED = "processingStageChanged";
+
+    /**
+     * Select one of the items from the recent files list to be the current data source.
+     */
+    static final String RECENT_FILE_SELECTED = "recentFileSelected";
+
+    /**
+     * Resume event processing if paused.
+     */
+    static final String RESUME = "resume";
+
+    /**
+     * Save the log table to a text file.
+     */
+    static final String SAVE_LOG_TABLE = "saveLogTable";
+
+    /**
+     * Save the plots to a ROOT, AIDA or PDF file.
+     */
+    static final String SAVE_PLOTS = "savePlots";
+
+    /**
+     * Save a screenshot from the window graphics.
+     */
+    static final String SAVE_SCREENSHOT = "saveScreenshot";
+
+    /**
+     * Save the currently selected plots tab graphic to a PDF file.
+     */
+    static final String SAVE_SELECTED_PLOTS = "saveSelectedPlots";
+
+    /**
+     * Save settings to a properties file.
+     */
     static final String SAVE_SETTINGS = "saveSettings";
+
+    /**
+     * Set the steering resource.
+     */
+    static final String SET_STEERING_RESOURCE = "setSteeringResource";
+
+    /**
+     * Show the settings dialog.
+     */
     static final String SHOW_SETTINGS = "showSettings";
-    
-    // File open and close
-    static final String OPEN_FILE = "openFile";
-    static final String CLOSE_FILE = "closeFile"; 
-    static final String RECENT_FILE_SELECTED = "recentFileSelected";
-    
-    // Window
-    static final String MAXIMIZE_WINDOW = "maximizeWindow";
-    static final String MINIMIZE_WINDOW = "minimizeWindow";
-    static final String DEFAULT_WINDOW = "defaultWindow";
-    
-    // Data source
-    static final String DATA_SOURCE_CHANGED = "dataSourceChanged";
-
-    // Event commands
-    static final String CONNECT = "connect";
-    static final String DISCONNECT = "disconnect";
-    static final String NEXT = "next";
-    static final String PAUSE = "pause";
-    static final String RESUME = "resume";
-    
-    // Save a screenshot
-    static final String SAVE_SCREENSHOT = "saveScreenshot";
-    
-    // Plotting actions
-    static final String SAVE_PLOTS = "savePlots";
-    static final String CLEAR_PLOTS = "resetPlots";
-    static final String SAVE_SELECTED_PLOTS = "saveSelectedPlots";
-    
-    // Exit the application.
-    static final String EXIT = "exit";
-           
-    // Log to file or standard print stream.
-    static final String LOG_TO_FILE = "logToFile";
-    static final String LOG_TO_TERMINAL = "logToTerminal";
-    
-    static final String LOG_LEVEL_FILTER_CHANGED = "logLevelFilterChanged";    
-    
-    static final String CONDITIONS_TAG_CHANGED = "conditionsTagChanged";
-    
+
+    /**
+     * Start the AIDA server.
+     */
     static final String START_AIDA_SERVER = "startAIDAServer";
+
+    /**
+     * Steering resource changed.
+     */
+    static final String STEERING_RESOURCE_CHANGED = "steeringResourceChanged";
+
+    /**
+     * Steering type changed (file or resource).
+     */
+    static final String STEERING_TYPE_CHANGED = "steeringTypeChanged";
+
+    /**
+     * Stop the AIDA server.
+     */
     static final String STOP_AIDA_SERVER = "stopAIDAServer";
-    
-    ////////////////////////////////////////////    
-    static final String BLOCKING_CHANGED = "blockingChanged";
-    static final String CHOOSE_COMPACT_FILE = "chooseCompactFile";
-    static final String CHOOSE_LOG_FILE = "chooseLogFile";
-    
-    static final String CHOOSE_STEERING_FILE = "chooseSteeringFile";
-    static final String CLEAR_LOG_TABLE = "clearLogTable";
-    static final String DATA_SOURCE_TYPE_CHANGED = "dataSourceTypeChanged";
-    static final String DETECTOR_NAME_CHANGED = "detectorNameChanged";
-    static final String DETECTOR_ALIAS_CHANGED = "detectorAliasChanged";
-    
-    static final String DISCONNECT_ON_ERROR_CHANGED = "disconnectOnErrorChanged";
-    static final String DISCONNECT_ON_END_RUN_CHANGED = "disconnectOnEndRunChanged";
-    static final String EVENT_BUILDER_CHANGED = "eventBuilderChanged";
-    static final String FREEZE_CONDITIONS_CHANGED = "freezeConditionsChanged";
-    
-    static final String LOG_LEVEL_CHANGED = "logLevelChanged";
-    
-    static final String PROCESSING_STAGE_CHANGED = "processingStageChanged";    
-    static final String SAVE_LOG_TABLE = "saveLogTable";            
-    static final String SELECT_LOG_FILE = "logToFile";
-    static final String SET_STEERING_RESOURCE = "setSteeringResource";    
-    static final String STEERING_TYPE_CHANGED = "steeringTypeChanged";
-    static final String STEERING_RESOURCE_CHANGED = "steeringResourceChanged";
+
+    /**
+     * User run number in conditions system changed.
+     */
     static final String USER_RUN_NUMBER_CHANGED = "userRunNumberChanged";
+
+    /**
+     * Verbose setting changed.
+     */
     static final String VERBOSE_CHANGED = "verboseChanged";
-    static final String VALIDATE_DATA_FILE = "validateDataFile";
+
+    /**
+     * ET wait mode changed.
+     */
     static final String WAIT_MODE_CHANGED = "waitModeChanged";
-}
+
+    /**
+     * Do not allow class instantiation.
+     */
+    private Commands() {
+        throw new UnsupportedOperationException("Do no instantiate this class.");
+    }
+}

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java	Thu Apr  9 13:15:57 2015
@@ -9,67 +9,65 @@
 
 /**
  * This is a table model for a collection of conditions objects.
+ *
  * @author Jeremy McCormick <[log in to unmask]>
  *
  */
 class ConditionsCollectionTableModel extends DefaultTableModel {
 
-    ConditionsObjectCollection<?> collection;
-    int columnCount;
-    int rowCount;
-    String[] columnNames;
-    Class<?>[] columnTypes;
-    DatabaseConditionsManager manager;
-    
-    ConditionsCollectionTableModel(DatabaseConditionsManager manager, ConditionsObjectCollection<?> collection) {
-        
+    /**
+     * The {@link org.hps.conditions.api.ConditionsObjectCollection} for the model.
+     */
+    private final ConditionsObjectCollection<?> collection;
+
+    /**
+     * The number of columns.
+     */
+    private int columnCount;
+
+    /**
+     * The column names.
+     */
+    private String[] columnNames;
+
+    /**
+     * The column classes.
+     */
+    private Class<?>[] columnTypes;
+
+    /**
+     * The row count.
+     */
+    private final int rowCount;
+
+    /**
+     * Class constructor.
+     *
+     * @param manager the global conditions manager instance
+     * @param collection the {@link org.hps.conditions.api.ConditionsObjectCollection} providing data for the model
+     */
+    ConditionsCollectionTableModel(final DatabaseConditionsManager manager,
+            final ConditionsObjectCollection<?> collection) {
+
         // Set collection data.
         this.collection = collection;
-        rowCount = this.collection.size();
-        
-        String tableName = collection.getConditionsRecord().getTableName();                
-        TableMetaData tableInfo = manager.findTableMetaData(tableName);
+        this.rowCount = this.collection.size();
+
+        final String tableName = collection.getConditionsRecord().getTableName();
+        final TableMetaData tableInfo = manager.findTableMetaData(tableName);
 
         // Set column names and count from table meta data.
-        setupColumns(tableInfo);        
+        this.setupColumns(tableInfo);
     }
 
-    private void setupColumns(TableMetaData tableInfo) {
-
-        int fieldNameCount = tableInfo.getFieldNames().length;
-        columnCount = fieldNameCount + 1;
-        
-        columnTypes = new Class<?>[columnCount];                
-        columnNames = new String[columnCount];
-        
-        columnNames[0] = "id";
-        columnTypes[0] = int.class;
-        
-        for (int i = 0; i < fieldNameCount; i++) {
-            String fieldName = tableInfo.getFieldNames()[i];
-            columnNames[i + 1] = fieldName;
-            columnTypes[i + 1] = tableInfo.getFieldType(fieldName);
-        }
-    }
-
+    /**
+     * Get the class of a column.
+     *
+     * @param columnIndex the index of the column
+     */
     @Override
-    public int getRowCount() {
-        return rowCount;
-    }
-
-    @Override
-    public int getColumnCount() {
-        return columnCount;
-    }
-
-    @Override
-    public String getColumnName(int columnIndex) {
-        return columnNames[columnIndex];
-    }
-    
-    @Override
-    public Class<?> getColumnClass(int columnIndex) {
-        Class<?> columnClass = columnTypes[columnIndex];
+    public Class<?> getColumnClass(final int columnIndex) {
+        final Class<?> columnClass = this.columnTypes[columnIndex];
         if (columnClass.equals(int.class)) {
             return Integer.class;
         } else if (columnClass.equals(float.class)) {
@@ -81,13 +79,72 @@
         }
     }
 
+    /**
+     * Get the number of columns.
+     *
+     * @return the number of columns
+     */
     @Override
-    public Object getValueAt(int rowIndex, int columnIndex) {
-        ConditionsObject object = collection.get(rowIndex);
+    public int getColumnCount() {
+        return this.columnCount;
+    }
+
+    /**
+     * Get the name of the column.
+     *
+     * @return the name of the column
+     */
+    @Override
+    public String getColumnName(final int columnIndex) {
+        return this.columnNames[columnIndex];
+    }
+
+    /**
+     * Get the row count.
+     *
+     * @return the row count
+     */
+    @Override
+    public int getRowCount() {
+        return this.rowCount;
+    }
+
+    /**
+     * Get a cell value.
+     *
+     * @param rowIndex the row index
+     * @param columnIndex the column index
+     */
+    @Override
+    public Object getValueAt(final int rowIndex, final int columnIndex) {
+        final ConditionsObject object = this.collection.get(rowIndex);
         if (columnIndex == 0) {
             return object.getRowId();
         } else {
-            return object.getFieldValue(columnNames[columnIndex]);
+            return object.getFieldValue(this.columnNames[columnIndex]);
         }
     }
-}
+
+    /**
+     * Setup the columns from table meta data.
+     *
+     * @param tableInfo the {@link org.hps.conditions.database.TableMetaData} with table info
+     */
+    private void setupColumns(final TableMetaData tableInfo) {
+
+        final int fieldNameCount = tableInfo.getFieldNames().length;
+        this.columnCount = fieldNameCount + 1;
+
+        this.columnTypes = new Class<?>[this.columnCount];
+        this.columnNames = new String[this.columnCount];
+
+        this.columnNames[0] = "id";
+        this.columnTypes[0] = int.class;
+
+        for (int i = 0; i < fieldNameCount; i++) {
+            final String fieldName = tableInfo.getFieldNames()[i];
+            this.columnNames[i + 1] = fieldName;
+            this.columnTypes[i + 1] = tableInfo.getFieldType(fieldName);
+        }
+    }
+}

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsPanel.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsPanel.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsPanel.java	Thu Apr  9 13:15:57 2015
@@ -1,6 +1,3 @@
-/**
- * 
- */
 package org.hps.monitoring.application;
 
 import java.awt.BorderLayout;
@@ -29,65 +26,72 @@
 import org.lcsim.conditions.ConditionsListener;
 
 /**
+ * The component for showing conditions tables in the monitoring app.
+ *
  * @author Jeremy McCormick <[log in to unmask]>
- *
  */
 public class ConditionsPanel extends JPanel {
-    
-    JList<String> conditionsList = new JList<String>();
-    JTable conditionsTable = new JTable();
-    Map<String, ConditionsCollectionTableModel> tableModels;
-    
-    ConditionsPanel() {
-        super(new BorderLayout());
-        
-        conditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-        conditionsList.addListSelectionListener(new ListSelectionListener() {
-            @Override
-            public void valueChanged(ListSelectionEvent e) {
-                String tableName = (String) conditionsList.getSelectedValue();
-                TableModel model = tableModels.get(tableName);
-                conditionsTable.setModel(model);
-                conditionsTable.setRowSorter(new TableRowSorter(model));
-                conditionsTable.revalidate();
-            }            
-        });
-        
-        conditionsTable.setModel(new DefaultTableModel());
-               
-        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, conditionsList, new JScrollPane(conditionsTable));
-        splitPane.setResizeWeight(0.6);
-        
-        add(splitPane);
-    }
-    
+
+    /**
+     * The listener for updating the panel when conditions are changed.
+     */
     class ConditionsPanelListener implements ConditionsListener {
 
         @Override
-        public void conditionsChanged(ConditionsEvent event) {
+        public void conditionsChanged(final ConditionsEvent event) {
 
-            DatabaseConditionsManager manager = (DatabaseConditionsManager) event.getConditionsManager();
-            
-            tableModels = new LinkedHashMap<String, ConditionsCollectionTableModel>();            
-                         
+            final DatabaseConditionsManager manager = (DatabaseConditionsManager) event.getConditionsManager();
+
+            ConditionsPanel.this.tableModels = new LinkedHashMap<String, ConditionsCollectionTableModel>();
+
             // Set list of table names.
-            ConditionsRecordCollection records = 
-                    manager.getCachedConditions(ConditionsRecordCollection.class, "conditions").getCachedData();
+            final ConditionsRecordCollection records = manager.getCachedConditions(ConditionsRecordCollection.class,
+                    "conditions").getCachedData();
             records.sortByKey();
-            conditionsList.removeAll();
-            Set<String> tableNames = new LinkedHashSet<String>();
-            for (ConditionsRecord record : records) {                
+            ConditionsPanel.this.conditionsList.removeAll();
+            final Set<String> tableNames = new LinkedHashSet<String>();
+            for (final ConditionsRecord record : records) {
                 tableNames.add(record.getTableName());
-            }            
-            conditionsList.setListData(tableNames.toArray(new String[] {}));
-            
-            // Create list of table models.            
-            for (String tableName : tableNames) {
-                ConditionsObjectCollection<?> collection = manager.getCachedConditions(
-                                manager.findTableMetaData(tableName).getCollectionClass(), 
-                                tableName).getCachedData();
-                tableModels.put(tableName, new ConditionsCollectionTableModel(manager, collection));
+            }
+            ConditionsPanel.this.conditionsList.setListData(tableNames.toArray(new String[] {}));
+
+            // Create list of table models.
+            for (final String tableName : tableNames) {
+                final ConditionsObjectCollection<?> collection = manager.getCachedConditions(
+                        manager.findTableMetaData(tableName).getCollectionClass(), tableName).getCachedData();
+                ConditionsPanel.this.tableModels
+                .put(tableName, new ConditionsCollectionTableModel(manager, collection));
             }
         }
     }
+
+    private final JList<String> conditionsList = new JList<String>();
+
+    private final JTable conditionsTable = new JTable();
+
+    private Map<String, ConditionsCollectionTableModel> tableModels;
+
+    ConditionsPanel() {
+        super(new BorderLayout());
+
+        this.conditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        this.conditionsList.addListSelectionListener(new ListSelectionListener() {
+            @Override
+            public void valueChanged(final ListSelectionEvent e) {
+                final String tableName = ConditionsPanel.this.conditionsList.getSelectedValue();
+                final TableModel model = ConditionsPanel.this.tableModels.get(tableName);
+                ConditionsPanel.this.conditionsTable.setModel(model);
+                ConditionsPanel.this.conditionsTable.setRowSorter(new TableRowSorter(model));
+                ConditionsPanel.this.conditionsTable.revalidate();
+            }
+        });
+
+        this.conditionsTable.setModel(new DefaultTableModel());
+
+        final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, this.conditionsList, new JScrollPane(
+                this.conditionsTable));
+        splitPane.setResizeWeight(0.6);
+
+        this.add(splitPane);
+    }
 }

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java	Thu Apr  9 13:15:57 2015
@@ -18,186 +18,185 @@
  */
 class ConnectionSettingsPanel extends AbstractFieldsPanel {
 
-    private JTextField etNameField;
-    private JTextField hostField;
-    private JTextField portField;
-    private JCheckBox blockingCheckBox;
-    private JCheckBox verboseCheckBox;
-    private JTextField stationNameField;
-    private JTextField chunkSizeField;
-    private JTextField queueSizeField;
-    private JTextField stationPositionField;
-    private JComboBox<?> waitModeComboBox;
-    private JTextField waitTimeField;
-    private JTextField prescaleField;
-
-    static final String[] waitModes = { 
-        Mode.SLEEP.name(), 
-        Mode.TIMED.name(), 
-        Mode.ASYNC.name() 
-    };
-
-    /**
-     * Class constructor.
-     */
-    ConnectionSettingsPanel() {
-
-        super(new Insets(5, 5, 5, 5), true);
-                        
-        setLayout(new GridBagLayout());
-
-        etNameField = addField("ET Name", "", 20);
-        etNameField.addPropertyChangeListener("value", this);
-
-        hostField = addField("Host", 20);
-        hostField.addPropertyChangeListener("value", this);
-
-        portField = addField("Port", 5);
-        portField.addPropertyChangeListener("value", this);
-
-        blockingCheckBox = addCheckBox("Blocking", false, true);
-        blockingCheckBox.setActionCommand(Commands.BLOCKING_CHANGED);
-        blockingCheckBox.addActionListener(this);
-
-        verboseCheckBox = addCheckBox("Verbose", false, true);
-        verboseCheckBox.setActionCommand(Commands.VERBOSE_CHANGED);
-        verboseCheckBox.addActionListener(this);
-
-        stationNameField = addField("Station Name", 10);
-        stationNameField.addPropertyChangeListener("value", this);
-
-        chunkSizeField = addField("Chunk Size", 3);
-        chunkSizeField.addPropertyChangeListener("value", this);
-
-        queueSizeField = addField("Queue Size", 3);
-        queueSizeField.addPropertyChangeListener("value", this);
-
-        stationPositionField = addField("Station Position", 3);
-        stationPositionField.addPropertyChangeListener("value", this);
-
-        waitModeComboBox = addComboBox("Wait Mode", waitModes);
-        waitModeComboBox.setActionCommand(Commands.WAIT_MODE_CHANGED);
-        waitModeComboBox.addActionListener(this);
-
-        waitTimeField = addField("Wait Time [microseconds]", 8);
-        waitTimeField.addPropertyChangeListener(this);
-
-        prescaleField = addField("Prescale", 8);
-        prescaleField.addPropertyChangeListener(this);
-    }
-
-    /**
-     * Enable or disable the connection panel GUI elements.
-     * @param e Set to true for enabled; false to disable.
-     */
-    void enableConnectionPanel(boolean e) {
-        etNameField.setEnabled(e);
-        hostField.setEnabled(e);
-        portField.setEnabled(e);
-        blockingCheckBox.setEnabled(e);
-        verboseCheckBox.setEnabled(e);
-        stationNameField.setEnabled(e);
-        chunkSizeField.setEnabled(e);
-        queueSizeField.setEnabled(e);
-        stationPositionField.setEnabled(e);
-        waitModeComboBox.setEnabled(e);
-        waitTimeField.setEnabled(e);
-        prescaleField.setEnabled(e);
-    }
-
     /**
      * Updates the GUI from changes in the ConfigurationModel.
      */
     public class ConnectionSettingsChangeListener implements PropertyChangeListener {
         @Override
-        public void propertyChange(PropertyChangeEvent evt) {                       
-            configurationModel.removePropertyChangeListener(this);
+        public void propertyChange(final PropertyChangeEvent evt) {
+            ConnectionSettingsPanel.this.getConfigurationModel().removePropertyChangeListener(this);
             try {
-                Object value = evt.getNewValue();
+                final Object value = evt.getNewValue();
                 if (evt.getPropertyName().equals(ConfigurationModel.ET_NAME_PROPERTY)) {
-                    etNameField.setText((String) value);
+                    ConnectionSettingsPanel.this.etNameField.setText((String) value);
                 } else if (evt.getPropertyName().equals(ConfigurationModel.HOST_PROPERTY)) {
-                    hostField.setText((String) value);
+                    ConnectionSettingsPanel.this.hostField.setText((String) value);
                 } else if (evt.getPropertyName().equals(ConfigurationModel.PORT_PROPERTY)) {
-                    portField.setText(value.toString());
+                    ConnectionSettingsPanel.this.portField.setText(value.toString());
                 } else if (evt.getPropertyName().equals(ConfigurationModel.BLOCKING_PROPERTY)) {
-                    blockingCheckBox.setSelected((Boolean) value);
+                    ConnectionSettingsPanel.this.blockingCheckBox.setSelected((Boolean) value);
                 } else if (evt.getPropertyName().equals(ConfigurationModel.VERBOSE_PROPERTY)) {
-                    verboseCheckBox.setSelected((Boolean) value);
+                    ConnectionSettingsPanel.this.verboseCheckBox.setSelected((Boolean) value);
                 } else if (evt.getPropertyName().equals(ConfigurationModel.STATION_NAME_PROPERTY)) {
-                    stationNameField.setText((String) value);
+                    ConnectionSettingsPanel.this.stationNameField.setText((String) value);
                 } else if (evt.getPropertyName().equals(ConfigurationModel.CHUNK_SIZE_PROPERTY)) {
-                    chunkSizeField.setText(value.toString());
+                    ConnectionSettingsPanel.this.chunkSizeField.setText(value.toString());
                 } else if (evt.getPropertyName().equals(ConfigurationModel.QUEUE_SIZE_PROPERTY)) {
-                    queueSizeField.setText(value.toString());
+                    ConnectionSettingsPanel.this.queueSizeField.setText(value.toString());
                 } else if (evt.getPropertyName().equals(ConfigurationModel.STATION_POSITION_PROPERTY)) {
-                    stationPositionField.setText(value.toString());
+                    ConnectionSettingsPanel.this.stationPositionField.setText(value.toString());
                 } else if (evt.getPropertyName().equals(ConfigurationModel.WAIT_MODE_PROPERTY)) {
-                    waitModeComboBox.setSelectedItem(((Mode) value).name());
+                    ConnectionSettingsPanel.this.waitModeComboBox.setSelectedItem(((Mode) value).name());
                 } else if (evt.getPropertyName().equals(ConfigurationModel.WAIT_TIME_PROPERTY)) {
-                    waitTimeField.setText(value.toString());
+                    ConnectionSettingsPanel.this.waitTimeField.setText(value.toString());
                 } else if (evt.getPropertyName().equals(ConfigurationModel.PRESCALE_PROPERTY)) {
-                    prescaleField.setText(value.toString());
+                    ConnectionSettingsPanel.this.prescaleField.setText(value.toString());
                 }
             } finally {
-                configurationModel.addPropertyChangeListener(this);
+                ConnectionSettingsPanel.this.getConfigurationModel().addPropertyChangeListener(this);
             }
         }
     }
 
+    static final String[] waitModes = { Mode.SLEEP.name(), Mode.TIMED.name(), Mode.ASYNC.name() };
+    private final JCheckBox blockingCheckBox;
+    private final JTextField chunkSizeField;
+    private final JTextField etNameField;
+    private final JTextField hostField;
+    private final JTextField portField;
+    private final JTextField prescaleField;
+    private final JTextField queueSizeField;
+    private final JTextField stationNameField;
+    private final JTextField stationPositionField;
+    private final JCheckBox verboseCheckBox;
+
+    private final JComboBox<?> waitModeComboBox;
+
+    private final JTextField waitTimeField;
+
+    /**
+     * Class constructor.
+     */
+    ConnectionSettingsPanel() {
+
+        super(new Insets(5, 5, 5, 5), true);
+
+        this.setLayout(new GridBagLayout());
+
+        this.etNameField = this.addField("ET Name", "", 20);
+        this.etNameField.addPropertyChangeListener("value", this);
+
+        this.hostField = this.addField("Host", 20);
+        this.hostField.addPropertyChangeListener("value", this);
+
+        this.portField = this.addField("Port", 5);
+        this.portField.addPropertyChangeListener("value", this);
+
+        this.blockingCheckBox = this.addCheckBox("Blocking", false, true);
+        this.blockingCheckBox.setActionCommand(Commands.BLOCKING_CHANGED);
+        this.blockingCheckBox.addActionListener(this);
+
+        this.verboseCheckBox = this.addCheckBox("Verbose", false, true);
+        this.verboseCheckBox.setActionCommand(Commands.VERBOSE_CHANGED);
+        this.verboseCheckBox.addActionListener(this);
+
+        this.stationNameField = this.addField("Station Name", 10);
+        this.stationNameField.addPropertyChangeListener("value", this);
+
+        this.chunkSizeField = this.addField("Chunk Size", 3);
+        this.chunkSizeField.addPropertyChangeListener("value", this);
+
+        this.queueSizeField = this.addField("Queue Size", 3);
+        this.queueSizeField.addPropertyChangeListener("value", this);
+
+        this.stationPositionField = this.addField("Station Position", 3);
+        this.stationPositionField.addPropertyChangeListener("value", this);
+
+        this.waitModeComboBox = this.addComboBox("Wait Mode", waitModes);
+        this.waitModeComboBox.setActionCommand(Commands.WAIT_MODE_CHANGED);
+        this.waitModeComboBox.addActionListener(this);
+
+        this.waitTimeField = this.addField("Wait Time [microseconds]", 8);
+        this.waitTimeField.addPropertyChangeListener(this);
+
+        this.prescaleField = this.addField("Prescale", 8);
+        this.prescaleField.addPropertyChangeListener(this);
+    }
+
+    /**
+     * Used to update the ConfigurationModel from GUI components.
+     */
+    @Override
+    public void actionPerformed(final ActionEvent e) {
+        if (Commands.WAIT_MODE_CHANGED.equals(e.getActionCommand())) {
+            this.getConfigurationModel().setWaitMode(Mode.valueOf((String) this.waitModeComboBox.getSelectedItem()));
+        } else if (Commands.BLOCKING_CHANGED.equals(e.getActionCommand())) {
+            this.getConfigurationModel().setBlocking(this.blockingCheckBox.isSelected());
+        } else if (Commands.VERBOSE_CHANGED.equals(e.getActionCommand())) {
+            this.getConfigurationModel().setVerbose(this.verboseCheckBox.isSelected());
+        }
+    }
+
+    /**
+     * Enable or disable the connection panel GUI elements.
+     * 
+     * @param e Set to true for enabled; false to disable.
+     */
+    void enableConnectionPanel(final boolean e) {
+        this.etNameField.setEnabled(e);
+        this.hostField.setEnabled(e);
+        this.portField.setEnabled(e);
+        this.blockingCheckBox.setEnabled(e);
+        this.verboseCheckBox.setEnabled(e);
+        this.stationNameField.setEnabled(e);
+        this.chunkSizeField.setEnabled(e);
+        this.queueSizeField.setEnabled(e);
+        this.stationPositionField.setEnabled(e);
+        this.waitModeComboBox.setEnabled(e);
+        this.waitTimeField.setEnabled(e);
+        this.prescaleField.setEnabled(e);
+    }
+
     /**
      * Updates ConfigurationModel from changes in the GUI components.
      */
     @Override
-    public void propertyChange(PropertyChangeEvent evt) {
-        if (!accept(evt)) {
+    public void propertyChange(final PropertyChangeEvent evt) {
+        if (!this.accept(evt)) {
             return;
-        }               
-        Object source = evt.getSource();
-        configurationModel.removePropertyChangeListener(this);
+        }
+        final Object source = evt.getSource();
+        this.getConfigurationModel().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()));
+            if (source.equals(this.etNameField)) {
+                this.getConfigurationModel().setEtName(this.etNameField.getText());
+            } else if (source.equals(this.hostField)) {
+                this.getConfigurationModel().setHost(this.hostField.getText());
+            } else if (source.equals(this.portField)) {
+                this.getConfigurationModel().setPort(Integer.parseInt(this.portField.getText()));
+            } else if (source.equals(this.stationNameField)) {
+                this.getConfigurationModel().setStationName(this.stationNameField.getText());
+            } else if (source.equals(this.chunkSizeField)) {
+                this.getConfigurationModel().setChunkSize(Integer.parseInt(this.chunkSizeField.getText()));
+            } else if (source.equals(this.queueSizeField)) {
+                this.getConfigurationModel().setQueueSize(Integer.parseInt(this.queueSizeField.getText()));
+            } else if (source.equals(this.stationPositionField)) {
+                this.getConfigurationModel().setStationPosition(Integer.parseInt(this.stationPositionField.getText()));
+            } else if (source.equals(this.waitTimeField)) {
+                this.getConfigurationModel().setWaitTime(Integer.parseInt(this.waitTimeField.getText()));
+            } else if (source.equals(this.prescaleField)) {
+                this.getConfigurationModel().setPrescale(Integer.parseInt(this.prescaleField.getText()));
             }
         } finally {
-            configurationModel.addPropertyChangeListener(this);
-        }
-    }
-
-    /**
-     * Used to update the ConfigurationModel from GUI components.
-     */
+            this.getConfigurationModel().addPropertyChangeListener(this);
+        }
+    }
+
     @Override
-    public void actionPerformed(ActionEvent e) {
-        if (Commands.WAIT_MODE_CHANGED.equals(e.getActionCommand())) {
-            configurationModel.setWaitMode(Mode.valueOf((String) waitModeComboBox.getSelectedItem()));
-        } else if (Commands.BLOCKING_CHANGED.equals(e.getActionCommand())) {
-            configurationModel.setBlocking(blockingCheckBox.isSelected());
-        } else if (Commands.VERBOSE_CHANGED.equals(e.getActionCommand())) {
-            configurationModel.setVerbose(verboseCheckBox.isSelected());
-        }
-    }
-    
-    public void setConfigurationModel(ConfigurationModel model) {
+    public void setConfigurationModel(final ConfigurationModel model) {
         super.setConfigurationModel(model);
-        
+
         // This listener updates the GUI from changes in the configuration.
-        this.configurationModel.addPropertyChangeListener(new ConnectionSettingsChangeListener());
+        this.getConfigurationModel().addPropertyChangeListener(new ConnectionSettingsChangeListener());
     }
 }

Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java
 =============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java	(original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java	Thu Apr  9 13:15:57 2015
@@ -28,399 +28,398 @@
 import org.jdom.input.SAXBuilder;
 
 /**
- * This is the GUI panel for setting job parameters. It is connected to the global configuration via
- * a {@link org.hps.monitoring.model.ConfigurationModel} object.
+ * This is the GUI panel for setting job parameters. It is connected to the global configuration via a
+ * {@link org.hps.monitoring.model.ConfigurationModel} object.
  */
 // FIXME: Combo boxes should use explicit types.
 class JobSettingsPanel extends AbstractFieldsPanel {
 
-    private JComboBox<?> steeringResourcesComboBox;
-    private JTextField steeringFileField;
-    private JComboBox<?> steeringTypeComboBox;
-    private JComboBox<ProcessingStage> processingStageComboBox;
-    private JComboBox<String> detectorNameComboBox;
-    private JTextField detectorAliasField;
-    private JComboBox<String> conditionsTagComboBox;
-    private JComboBox<String> eventBuilderComboBox;
-    private JTextField userRunNumberField;
-    private JCheckBox freezeConditionsCheckBox;    
-    private JTextField maxEventsField;
-    private JCheckBox disconnectOnErrorCheckBox;
-    private JCheckBox disconnectOnEndRunCheckBox;    
-    private JComboBox<?> logLevelComboBox;
-    private JCheckBox logToFileCheckbox;
-    private JTextField logFileNameField;
-    private JTextField aidaServerNameField;
-           
-    // The package where steering resources must be located.
-    static final String STEERING_PACKAGE = "org/hps/steering/monitoring/";
-
-    // The available LogLevel settings as an array of strings.
-    static final String[] LOG_LEVELS = new String[] { 
-        Level.ALL.toString(), 
-        Level.FINEST.toString(), 
-        Level.FINER.toString(), 
-        Level.FINE.toString(), 
-        Level.CONFIG.toString(), 
-        Level.INFO.toString(), 
-        Level.WARNING.toString(), 
-        Level.SEVERE.toString(), 
-        Level.OFF.toString() 
-    };
-
-    /**
-     * Class constructor.
-     */
-    JobSettingsPanel(ConfigurationModel model) {
-
-        super(new Insets(5, 3, 3, 5), true);
-        
-        setBorder(new EmptyBorder(10, 10, 10, 10));
-                
-        setLayout(new GridBagLayout());
-        
-        // Listen on changes to the configuration which will then be automatically pushed to the GUI.
-        model.addPropertyChangeListener(this);
-
-        steeringResourcesComboBox = addComboBoxMultiline("Steering File Resource", ResourceUtil.findSteeringResources(STEERING_PACKAGE));
-        steeringResourcesComboBox.setActionCommand(Commands.STEERING_RESOURCE_CHANGED);
-        steeringResourcesComboBox.addActionListener(this);
-        
-        steeringFileField = addField("Steering File", 50);
-        steeringFileField.addPropertyChangeListener("value", this);
-        
-        JButton steeringFileButton = addButton("Select Steering File");
-        steeringFileButton.setActionCommand(Commands.CHOOSE_STEERING_FILE);
-        steeringFileButton.addActionListener(this);
-        
-        steeringTypeComboBox = addComboBox("Steering Type", new String[] { SteeringType.RESOURCE.name(), SteeringType.FILE.name() });
-        steeringTypeComboBox.setActionCommand(Commands.STEERING_TYPE_CHANGED);
-        steeringTypeComboBox.addActionListener(this);
-        
-        processingStageComboBox = new JComboBox<ProcessingStage>(ProcessingStage.values());
-        addComponent("Processing Stage", processingStageComboBox);
-        processingStageComboBox.setActionCommand(Commands.PROCESSING_STAGE_CHANGED);
-        processingStageComboBox.addActionListener(this);
-        
-        detectorNameComboBox = addComboBox("Detector Name", ResourceUtil.findDetectorNames());
-        detectorNameComboBox.setActionCommand(Commands.DETECTOR_NAME_CHANGED);
-        detectorNameComboBox.addActionListener(this);
-        
-        detectorAliasField = addField("Detector Resources Directory", "", 35, true);
-        detectorAliasField.setActionCommand(Commands.DETECTOR_ALIAS_CHANGED);
-        detectorAliasField.addPropertyChangeListener("value", this);
-        detectorAliasField.addActionListener(this);
-        
-        JButton compactXmlButton = addButton("Select Compact Xml File");
-        compactXmlButton.setActionCommand(Commands.CHOOSE_COMPACT_FILE);
-        compactXmlButton.addActionListener(this);
-
-        userRunNumberField = addField("User Run Number", "", 10, true);
-        userRunNumberField.addPropertyChangeListener("value", this);
-        userRunNumberField.setActionCommand(Commands.USER_RUN_NUMBER_CHANGED);
-        userRunNumberField.setEnabled(true);
-        userRunNumberField.setEditable(true);
-                
-        conditionsTagComboBox = addComboBox("Conditions Tag", ResourceUtil.getConditionsTags());
-        conditionsTagComboBox.addItem("");
-        conditionsTagComboBox.setSelectedItem("");
-        conditionsTagComboBox.setActionCommand(Commands.CONDITIONS_TAG_CHANGED);
-        conditionsTagComboBox.addActionListener(this);
-        conditionsTagComboBox.setEditable(false);
-        conditionsTagComboBox.setEnabled(true);
-                
-        freezeConditionsCheckBox = addCheckBox("Freeze detector conditions", false, true);
-        freezeConditionsCheckBox.addActionListener(this);
-        freezeConditionsCheckBox.setActionCommand(Commands.FREEZE_CONDITIONS_CHANGED);
-        
-        maxEventsField = addField("Max Events", "-1", 10, false);
-        maxEventsField.addPropertyChangeListener("value", this);
-        maxEventsField.setEnabled(true);
-        maxEventsField.setEditable(true);
-        
-        eventBuilderComboBox = addComboBox("LCSim Event Builder", ResourceUtil.findEventBuilderClassNames());
-        eventBuilderComboBox.setSize(24, eventBuilderComboBox.getPreferredSize().height);
-        eventBuilderComboBox.setActionCommand(Commands.EVENT_BUILDER_CHANGED);
-        eventBuilderComboBox.addActionListener(this);
-        
-        disconnectOnErrorCheckBox = addCheckBox("Disconnect on error", false, true);
-        disconnectOnErrorCheckBox.setActionCommand(Commands.DISCONNECT_ON_ERROR_CHANGED);
-        disconnectOnErrorCheckBox.addActionListener(this);
-
-        disconnectOnEndRunCheckBox = addCheckBox("Disconnect on end run", false, true);
-        disconnectOnEndRunCheckBox.setActionCommand(Commands.DISCONNECT_ON_END_RUN_CHANGED);
-        disconnectOnEndRunCheckBox.addActionListener(this);
-
-        logLevelComboBox = addComboBox("Log Level", LOG_LEVELS);
-        logLevelComboBox.setActionCommand(Commands.LOG_LEVEL_CHANGED);
-        logLevelComboBox.addActionListener(this);
-                                            
-        logToFileCheckbox = addCheckBox("Log to File", false, false);
-        logToFileCheckbox.setEnabled(false);
-
-        logFileNameField = addField("Log File Name", "", "Full path to log file", 50, false);
-        logFileNameField.setEditable(false);
-        
-        aidaServerNameField = addField("AIDA Server Name", "", "Name of AIDA server", 30, true);
-        aidaServerNameField.addPropertyChangeListener("value", this);
-    }
-
-    @Override
-    public ConfigurationModel getConfigurationModel() {
-        return configurationModel;
-    }
-
-    /**
-     * Attaches the ActionListener from the main app to specific GUI components in this class.
-     */
-    public void addActionListener(ActionListener listener) {
-        steeringResourcesComboBox.addActionListener(listener);
-        freezeConditionsCheckBox.addActionListener(listener);
-    }
-
-    /**
-     * Choose an lcsim steering file.
-     */
-    void chooseSteeringFile() {
-        JFileChooser fc = new JFileChooser();
-        fc.setDialogTitle("Choose an LCSim Steering File");
-        fc.setCurrentDirectory(new File("."));
-        int r = fc.showDialog(this, "Select ...");
-        if (r == JFileChooser.APPROVE_OPTION) {
-            File file = fc.getSelectedFile();
-            try {
-                checkSteeringFile(file);
-                configurationModel.setSteeringFile(file.getCanonicalPath());
-                configurationModel.setSteeringType(SteeringType.FILE);
-            } catch (IOException | JDOMException e) {
-                throw new RuntimeException("Error parsing the selected steering file.", e);
-            }
-        }
-    }
-    
-    /**
-     * This filter will accept only files called compact.xml which
-     * should be an LCSim detector description file. 
+    /**
+     * This filter will accept only files called compact.xml which should be an LCSim detector description file.
      */
     static class CompactFileFilter extends FileFilter {
 
-        public CompactFileFilter() {            
-        }
-        
+        public CompactFileFilter() {
+        }
+
         @Override
-        public boolean accept(File pathname) {
+        public boolean accept(final File pathname) {
             if (pathname.getName().equals("compact.xml")) {
                 return true;
             } else {
                 return false;
             }
         }
-        
+
         @Override
         public String getDescription() {
             return "Compact XML files";
-        }        
-    }
-    
-    
+        }
+    }
+
+    /**
+     * 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(final PropertyChangeEvent evt) {
+            if (evt.getSource() instanceof ConfigurationModel) {
+                final Object value = evt.getNewValue();
+                final String property = evt.getPropertyName();
+                JobSettingsPanel.this.getConfigurationModel().removePropertyChangeListener(this);
+                try {
+                    if (property.equals(ConfigurationModel.DETECTOR_NAME_PROPERTY)) {
+                        JobSettingsPanel.this.detectorNameComboBox.setSelectedItem(value);
+                    } else if (property.equals(ConfigurationModel.DETECTOR_ALIAS_PROPERTY)) {
+                        JobSettingsPanel.this.detectorAliasField.setText((String) value);
+                    } else if (property.equals(ConfigurationModel.DISCONNECT_ON_ERROR_PROPERTY)) {
+                        JobSettingsPanel.this.disconnectOnErrorCheckBox.setSelected((Boolean) value);
+                    } else if (property.equals(ConfigurationModel.DISCONNECT_ON_END_RUN_PROPERTY)) {
+                        JobSettingsPanel.this.disconnectOnEndRunCheckBox.setSelected((Boolean) value);
+                    } else if (property.equals(ConfigurationModel.EVENT_BUILDER_PROPERTY)) {
+                        JobSettingsPanel.this.eventBuilderComboBox.setSelectedItem(value);
+                    } else if (property.equals(ConfigurationModel.LOG_FILE_NAME_PROPERTY)) {
+                        JobSettingsPanel.this.logFileNameField.setText((String) value);
+                    } else if (property.equals(ConfigurationModel.LOG_LEVEL_PROPERTY)) {
+                        JobSettingsPanel.this.logLevelComboBox.setSelectedItem(value.toString());
+                    } else if (property.equals(ConfigurationModel.LOG_TO_FILE_PROPERTY)) {
+                        JobSettingsPanel.this.logToFileCheckbox.setSelected((Boolean) value);
+                    } else if (property.equals(ConfigurationModel.STEERING_TYPE_PROPERTY)) {
+                        JobSettingsPanel.this.steeringTypeComboBox.setSelectedIndex(((SteeringType) value).ordinal());
+                    } else if (property.equals(ConfigurationModel.STEERING_FILE_PROPERTY)) {
+                        if (value != null) {
+                            JobSettingsPanel.this.steeringFileField.setText((String) evt.getNewValue());
+                        } else {
+                            // A null value here is actually okay and means this field should be reset to have no value.
+                            JobSettingsPanel.this.steeringFileField.setText(null);
+                        }
+                    } else if (property.equals(ConfigurationModel.STEERING_RESOURCE_PROPERTY)) {
+                        JobSettingsPanel.this.steeringResourcesComboBox.setSelectedItem(value);
+                    } else if (property.equals(ConfigurationModel.USER_RUN_NUMBER_PROPERTY)) {
+                        if (value != null) {
+                            JobSettingsPanel.this.userRunNumberField.setText(Integer.toString((int) value));
+                        } else {
+                            JobSettingsPanel.this.userRunNumberField.setText(null);
+                        }
+                    } else if (property.equals(ConfigurationModel.FREEZE_CONDITIONS_PROPERTY)) {
+                        if (value != null) {
+                            JobSettingsPanel.this.freezeConditionsCheckBox.setSelected((Boolean) value);
+                        }
+                    } else if (property.equals(ConfigurationModel.MAX_EVENTS_PROPERTY)) {
+                        if (value != null) {
+                            JobSettingsPanel.this.maxEventsField.setText(value.toString());
+                        }
+                    } else if (property.equals(ConfigurationModel.PROCESSING_STAGE_PROPERTY)) {
+                        JobSettingsPanel.this.processingStageComboBox.setSelectedItem(evt.getNewValue());
+                    } else if (property.equals(ConfigurationModel.AIDA_SERVER_NAME_PROPERTY)) {
+                        JobSettingsPanel.this.aidaServerNameField.setText((String) evt.getNewValue());
+                    }
+                } finally {
+                    JobSettingsPanel.this.getConfigurationModel().addPropertyChangeListener(this);
+                }
+            }
+        }
+    }
+
+    // The available LogLevel settings as an array of strings.
+    static final String[] LOG_LEVELS = new String[] { Level.ALL.toString(), Level.FINEST.toString(),
+        Level.FINER.toString(), Level.FINE.toString(), Level.CONFIG.toString(), Level.INFO.toString(),
+        Level.WARNING.toString(), Level.SEVERE.toString(), Level.OFF.toString() };
+    // The package where steering resources must be located.
+    static final String STEERING_PACKAGE = "org/hps/steering/monitoring/";
+    private final JTextField aidaServerNameField;
+    private final JComboBox<String> conditionsTagComboBox;
+    private final JTextField detectorAliasField;
+    private final JComboBox<String> detectorNameComboBox;
+    private final JCheckBox disconnectOnEndRunCheckBox;
+    private final JCheckBox disconnectOnErrorCheckBox;
+    private final JComboBox<String> eventBuilderComboBox;
+    private final JCheckBox freezeConditionsCheckBox;
+    private final JTextField logFileNameField;
+    private final JComboBox<?> logLevelComboBox;
+    private final JCheckBox logToFileCheckbox;
+    private final JTextField maxEventsField;
+    private final JComboBox<ProcessingStage> processingStageComboBox;
+
+    private final JTextField steeringFileField;
+
+    private final JComboBox<?> steeringResourcesComboBox;
+
+    private final JComboBox<?> steeringTypeComboBox;
+
+    private final JTextField userRunNumberField;
+
+    /**
+     * Class constructor.
+     */
+    JobSettingsPanel(final ConfigurationModel model) {
+
+        super(new Insets(5, 3, 3, 5), true);
+
+        this.setBorder(new EmptyBorder(10, 10, 10, 10));
+
+        this.setLayout(new GridBagLayout());
+
+        // Listen on changes to the configuration which will then be automatically pushed to the GUI.
+        model.addPropertyChangeListener(this);
+
+        this.steeringResourcesComboBox = this.addComboBoxMultiline("Steering File Resource",
+                ResourceUtil.findSteeringResources(STEERING_PACKAGE));
+        this.steeringResourcesComboBox.setActionCommand(Commands.STEERING_RESOURCE_CHANGED);
+        this.steeringResourcesComboBox.addActionListener(this);
+
+        this.steeringFileField = this.addField("Steering File", 50);
+        this.steeringFileField.addPropertyChangeListener("value", this);
+
+        final JButton steeringFileButton = this.addButton("Select Steering File");
+        steeringFileButton.setActionCommand(Commands.CHOOSE_STEERING_FILE);
+        steeringFileButton.addActionListener(this);
+
+        this.steeringTypeComboBox = this.addComboBox("Steering Type", new String[] { SteeringType.RESOURCE.name(),
+                SteeringType.FILE.name() });
+        this.steeringTypeComboBox.setActionCommand(Commands.STEERING_TYPE_CHANGED);
+        this.steeringTypeComboBox.addActionListener(this);
+
+        this.processingStageComboBox = new JComboBox<ProcessingStage>(ProcessingStage.values());
+        this.addComponent("Processing Stage", this.processingStageComboBox);
+        this.processingStageComboBox.setActionCommand(Commands.PROCESSING_STAGE_CHANGED);
+        this.processingStageComboBox.addActionListener(this);
+
+        this.detectorNameComboBox = this.addComboBox("Detector Name", ResourceUtil.findDetectorNames());
+        this.detectorNameComboBox.setActionCommand(Commands.DETECTOR_NAME_CHANGED);
+        this.detectorNameComboBox.addActionListener(this);
+
+        this.detectorAliasField = this.addField("Detector Resources Directory", "", 35, true);
+        this.detectorAliasField.setActionCommand(Commands.DETECTOR_ALIAS_CHANGED);
+        this.detectorAliasField.addPropertyChangeListener("value", this);
+        this.detectorAliasField.addActionListener(this);
+
+        final JButton compactXmlButton = this.addButton("Select Compact Xml File");
+        compactXmlButton.setActionCommand(Commands.CHOOSE_COMPACT_FILE);
+        compactXmlButton.addActionListener(this);
+
+        this.userRunNumberField = this.addField("User Run Number", "", 10, true);
+        this.userRunNumberField.addPropertyChangeListener("value", this);
+        this.userRunNumberField.setActionCommand(Commands.USER_RUN_NUMBER_CHANGED);
+        this.userRunNumberField.setEnabled(true);
+        this.userRunNumberField.setEditable(true);
+
+        this.conditionsTagComboBox = this.addComboBox("Conditions Tag", ResourceUtil.getConditionsTags());
+        this.conditionsTagComboBox.addItem("");
+        this.conditionsTagComboBox.setSelectedItem("");
+        this.conditionsTagComboBox.setActionCommand(Commands.CONDITIONS_TAG_CHANGED);
+        this.conditionsTagComboBox.addActionListener(this);
+        this.conditionsTagComboBox.setEditable(false);
+        this.conditionsTagComboBox.setEnabled(true);
+
+        this.freezeConditionsCheckBox = this.addCheckBox("Freeze detector conditions", false, true);
+        this.freezeConditionsCheckBox.addActionListener(this);
+        this.freezeConditionsCheckBox.setActionCommand(Commands.FREEZE_CONDITIONS_CHANGED);
+
+        this.maxEventsField = this.addField("Max Events", "-1", 10, false);
+        this.maxEventsField.addPropertyChangeListener("value", this);
+        this.maxEventsField.setEnabled(true);
+        this.maxEventsField.setEditable(true);
+
+        this.eventBuilderComboBox = this.addComboBox("LCSim Event Builder", ResourceUtil.findEventBuilderClassNames());
+        this.eventBuilderComboBox.setSize(24, this.eventBuilderComboBox.getPreferredSize().height);
+        this.eventBuilderComboBox.setActionCommand(Commands.EVENT_BUILDER_CHANGED);
+        this.eventBuilderComboBox.addActionListener(this);
+
+        this.disconnectOnErrorCheckBox = this.addCheckBox("Disconnect on error", false, true);
+        this.disconnectOnErrorCheckBox.setActionCommand(Commands.DISCONNECT_ON_ERROR_CHANGED);
+        this.disconnectOnErrorCheckBox.addActionListener(this);
+
+        this.disconnectOnEndRunCheckBox = this.addCheckBox("Disconnect on end run", false, true);
+        this.disconnectOnEndRunCheckBox.setActionCommand(Commands.DISCONNECT_ON_END_RUN_CHANGED);
+        this.disconnectOnEndRunCheckBox.addActionListener(this);
+
+        this.logLevelComboBox = this.addComboBox("Log Level", LOG_LEVELS);
+        this.logLevelComboBox.setActionCommand(Commands.LOG_LEVEL_CHANGED);
+        this.logLevelComboBox.addActionListener(this);
+
+        this.logToFileCheckbox = this.addCheckBox("Log to File", false, false);
+        this.logToFileCheckbox.setEnabled(false);
+
+        this.logFileNameField = this.addField("Log File Name", "", "Full path to log file", 50, false);
+        this.logFileNameField.setEditable(false);
+
+        this.aidaServerNameField = this.addField("AIDA Server Name", "", "Name of AIDA server", 30, true);
+        this.aidaServerNameField.addPropertyChangeListener("value", this);
+    }
+
+    @Override
+    public void actionPerformed(final ActionEvent event) {
+        try {
+            this.getConfigurationModel().removePropertyChangeListener(this);
+            final String command = event.getActionCommand();
+            if (event.getActionCommand().equals(Commands.CHOOSE_STEERING_FILE)) {
+                this.chooseSteeringFile();
+            } else if (event.getActionCommand().equals(Commands.CHOOSE_COMPACT_FILE)) {
+                this.chooseCompactFile();
+            } else if (Commands.DISCONNECT_ON_ERROR_CHANGED.equals(command)) {
+                this.getConfigurationModel().setDisconnectOnError(this.disconnectOnErrorCheckBox.isSelected());
+            } else if (Commands.DISCONNECT_ON_END_RUN_CHANGED.equals(command)) {
+                this.getConfigurationModel().setDisconnectOnEndRun(this.disconnectOnEndRunCheckBox.isSelected());
+            } else if (Commands.STEERING_TYPE_CHANGED.equals(command)) {
+                this.getConfigurationModel().setSteeringType(
+                        SteeringType.valueOf((String) this.steeringTypeComboBox.getSelectedItem()));
+            } else if (Commands.STEERING_RESOURCE_CHANGED.equals(command)) {
+                this.getConfigurationModel().setSteeringResource(
+                        (String) this.steeringResourcesComboBox.getSelectedItem());
+            } else if (Commands.LOG_LEVEL_CHANGED.equals(command)) {
+                this.getConfigurationModel().setLogLevel(Level.parse((String) this.logLevelComboBox.getSelectedItem()));
+            } else if (Commands.EVENT_BUILDER_CHANGED.equals(command)) {
+                this.getConfigurationModel().setEventBuilderClassName(
+                        (String) this.eventBuilderComboBox.getSelectedItem());
+            } else if (Commands.DETECTOR_NAME_CHANGED.equals(command)) {
+                try {
+                    this.getConfigurationModel().setDetectorName((String) this.detectorNameComboBox.getSelectedItem());
+                } catch (final Exception exception) {
+                    exception.printStackTrace();
+                }
+            } else if (Commands.FREEZE_CONDITIONS_CHANGED.equals(command)) {
+                if (this.getConfigurationModel().hasPropertyKey(ConfigurationModel.USER_RUN_NUMBER_PROPERTY)
+                        && this.getConfigurationModel().getUserRunNumber() != null) {
+                    this.getConfigurationModel().setFreezeConditions(this.freezeConditionsCheckBox.isSelected());
+                } else {
+                    throw new IllegalArgumentException(
+                            "Conditions system may only be frozen if there is a valid user run number.");
+                }
+            } else if (Commands.DETECTOR_ALIAS_CHANGED.equals(command)) {
+                this.getConfigurationModel().setDetectorName(this.detectorAliasField.getText());
+            } else if (Commands.CONDITIONS_TAG_CHANGED.equals(command)) {
+                this.getConfigurationModel().setConditionsTag((String) this.conditionsTagComboBox.getSelectedItem());
+            } else if (Commands.PROCESSING_STAGE_CHANGED.equals(command)) {
+                this.getConfigurationModel().setProcessingStage(
+                        (ProcessingStage) this.processingStageComboBox.getSelectedItem());
+            }
+        } finally {
+            this.getConfigurationModel().addPropertyChangeListener(this);
+        }
+    }
+
+    /**
+     * Attaches the ActionListener from the main app to specific GUI components in this class.
+     */
+    @Override
+    public void addActionListener(final ActionListener listener) {
+        this.steeringResourcesComboBox.addActionListener(listener);
+        this.freezeConditionsCheckBox.addActionListener(listener);
+    }
+
+    /**
+     * Parse the lcsim steering file to see if it appears to be valid.
+     *
+     * @param file The input steering file.
+     * @throws IOException if there is a basic IO problem.
+     * @throws JDOMException if the XML is not valid.
+     */
+    private void checkSteeringFile(final File file) throws IOException, JDOMException {
+        final SAXBuilder builder = new SAXBuilder();
+        final Document document = builder.build(file);
+        final Element rootNode = document.getRootElement();
+        if (!rootNode.getName().equals("lcsim")) {
+            throw new IOException("Not an LCSim XML file: " + file.getPath());
+        }
+    }
+
     /**
      * Choose a compact XML file to override the one embedded in the jar as a resource.
      */
     void chooseCompactFile() {
-        JFileChooser fc = new JFileChooser();
+        final JFileChooser fc = new JFileChooser();
         fc.setDialogTitle("Choose a Compact XML File");
         fc.setCurrentDirectory(new File("."));
         fc.setFileFilter(new CompactFileFilter());
-        int r = fc.showDialog(this, "Select ...");
+        final int r = fc.showDialog(this, "Select ...");
         if (r == JFileChooser.APPROVE_OPTION) {
-            File file = fc.getSelectedFile();
-            configurationModel.setDetectorAlias(file.getParent());
-        }
-    }    
-
-    /**
-     * Parse the lcsim steering file to see if it appears to be valid.
-     * @param file The input steering file.
-     * @throws IOException if there is a basic IO problem.
-     * @throws JDOMException if the XML is not valid.
-     */
-    private void checkSteeringFile(File file) throws IOException, JDOMException {
-        SAXBuilder builder = new SAXBuilder();
-        Document document = builder.build(file);
-        Element rootNode = document.getRootElement();
-        if (!rootNode.getName().equals("lcsim")) {
-            throw new IOException("Not an LCSim XML file: " + file.getPath());
-        }
-    }
-
+            final File file = fc.getSelectedFile();
+            this.getConfigurationModel().setDetectorAlias(file.getParent());
+        }
+    }
+
+    /**
+     * Choose an lcsim steering file.
+     */
+    void chooseSteeringFile() {
+        final JFileChooser fc = new JFileChooser();
+        fc.setDialogTitle("Choose an LCSim Steering File");
+        fc.setCurrentDirectory(new File("."));
+        final int r = fc.showDialog(this, "Select ...");
+        if (r == JFileChooser.APPROVE_OPTION) {
+            final File file = fc.getSelectedFile();
+            try {
+                this.checkSteeringFile(file);
+                this.getConfigurationModel().setSteeringFile(file.getCanonicalPath());
+                this.getConfigurationModel().setSteeringType(SteeringType.FILE);
+            } catch (IOException | JDOMException e) {
+                throw new RuntimeException("Error parsing the selected steering file.", e);
+            }
+        }
+    }
+
+    /**
+     * Updates the configuration with changes from the GUI component values. The changes from the GUI are
+     * distinguishable by their component object.
+     */
     @Override
-    public void actionPerformed(ActionEvent event) {
+    public void propertyChange(final PropertyChangeEvent evt) {
+        this.getConfigurationModel().removePropertyChangeListener(this);
         try {
-            configurationModel.removePropertyChangeListener(this);
-            String command = event.getActionCommand();
-            if (event.getActionCommand().equals(Commands.CHOOSE_STEERING_FILE)) {
-                chooseSteeringFile();
-            } else if (event.getActionCommand().equals(Commands.CHOOSE_COMPACT_FILE)) {
-                chooseCompactFile();
-            } else if (Commands.DISCONNECT_ON_ERROR_CHANGED.equals(command)) {
-                configurationModel.setDisconnectOnError(disconnectOnErrorCheckBox.isSelected());
-            } else if (Commands.DISCONNECT_ON_END_RUN_CHANGED.equals(command)) {
-                configurationModel.setDisconnectOnEndRun(disconnectOnEndRunCheckBox.isSelected());
-            } else if (Commands.STEERING_TYPE_CHANGED.equals(command)) {
-                configurationModel.setSteeringType(SteeringType.valueOf((String) steeringTypeComboBox.getSelectedItem()));
-            } else if (Commands.STEERING_RESOURCE_CHANGED.equals(command)) {
-                configurationModel.setSteeringResource((String) steeringResourcesComboBox.getSelectedItem());
-            } else if (Commands.LOG_LEVEL_CHANGED.equals(command)) {
-                configurationModel.setLogLevel(Level.parse((String) logLevelComboBox.getSelectedItem()));
-            } else if (Commands.EVENT_BUILDER_CHANGED.equals(command)) {
-                configurationModel.setEventBuilderClassName((String) eventBuilderComboBox.getSelectedItem());
-            } else if (Commands.DETECTOR_NAME_CHANGED.equals(command)) {
-                try {
-                    configurationModel.setDetectorName((String) detectorNameComboBox.getSelectedItem());
-                } catch (Exception exception) {
-                    exception.printStackTrace();
-                }
-            } else if (Commands.FREEZE_CONDITIONS_CHANGED.equals(command)) {
-                if (configurationModel.hasPropertyKey(ConfigurationModel.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 (Commands.DETECTOR_ALIAS_CHANGED.equals(command)) {
-                configurationModel.setDetectorName(detectorAliasField.getText());
-            } else if (Commands.CONDITIONS_TAG_CHANGED.equals(command)) {
-                configurationModel.setConditionsTag((String) conditionsTagComboBox.getSelectedItem());
-            } else if (Commands.PROCESSING_STAGE_CHANGED.equals(command)) {
-                configurationModel.setProcessingStage((ProcessingStage) processingStageComboBox.getSelectedItem());
-            } 
-        } finally {
-            configurationModel.addPropertyChangeListener(this);
-        }
-    }
-
-    /**
-     * Updates the configuration with changes from the GUI component values. 
-     * The changes from the GUI are distinguishable by their component object.
-     */
-    @Override
-    public void propertyChange(PropertyChangeEvent evt) {                            
-        configurationModel.removePropertyChangeListener(this);
-        try {
-            Object source = evt.getSource();            
-            if (source == steeringFileField) {
-                configurationModel.setSteeringFile(steeringFileField.getText());
-            } else if (source == userRunNumberField) {
+            final Object source = evt.getSource();
+            if (source == this.steeringFileField) {
+                this.getConfigurationModel().setSteeringFile(this.steeringFileField.getText());
+            } else if (source == this.userRunNumberField) {
                 // Is run number being reset to null or empty?
-                if (userRunNumberField.getText() == null || userRunNumberField.getText().isEmpty()) {
+                if (this.userRunNumberField.getText() == null || this.userRunNumberField.getText().isEmpty()) {
                     // Update the model to null user run number and do not freeze the conditions system.
-                    configurationModel.setUserRunNumber(null);
-                    configurationModel.setFreezeConditions(false);
+                    this.getConfigurationModel().setUserRunNumber(null);
+                    this.getConfigurationModel().setFreezeConditions(false);
                 } else {
                     try {
                         // 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);
-                    } catch (NumberFormatException e) {
+                        final int userRunNumber = Integer.parseInt(this.userRunNumberField.getText());
+                        this.getConfigurationModel().setUserRunNumber(userRunNumber);
+                        this.getConfigurationModel().setFreezeConditions(true);
+                    } catch (final 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.");
+                        this.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());
-            } else if (source == aidaServerNameField) {
-                configurationModel.setAIDAServerName(aidaServerNameField.getText());
+            } else if (source == this.maxEventsField) {
+                this.getConfigurationModel().setMaxEvents(Long.parseLong(this.maxEventsField.getText()));
+                // System.out.println("setMaxEvents - " + configurationModel.getMaxEvents());
+            } else if (source == this.aidaServerNameField) {
+                this.getConfigurationModel().setAIDAServerName(this.aidaServerNameField.getText());
             } else if (evt.getPropertyName().equals(ConfigurationModel.LOG_TO_FILE_PROPERTY)) {
-                // This is getting the log to file prop change from the ConfigurationModel to update a read only component.
-                Boolean logToFile = (Boolean) evt.getNewValue();
+                // This is getting the log to file prop change from the ConfigurationModel to update a read only
+                // component.
+                final Boolean logToFile = (Boolean) evt.getNewValue();
                 if (logToFile != null) {
-                    logToFileCheckbox.setSelected(logToFile);
+                    this.logToFileCheckbox.setSelected(logToFile);
                 }
             } else if (evt.getPropertyName().equals(ConfigurationModel.LOG_FILE_NAME_PROPERTY)) {
-                // This is getting the log file name prop change from the ConfigurationModel to update a read only component.
-                String logFileName = (String) evt.getNewValue();
+                // This is getting the log file name prop change from the ConfigurationModel to update a read only
+                // component.
+                final String logFileName = (String) evt.getNewValue();
                 if (logFileName != null && logFileName.length() > 0) {
-                    logFileNameField.setText(logFileName);
+                    this.logFileNameField.setText(logFileName);
                 } else {
-                    logFileNameField.setText("");
+                    this.logFileNameField.setText("");
                 }
             } else if (evt.getPropertyName().equals(ConfigurationModel.CONDITIONS_TAG_PROPERTY)) {
-                conditionsTagComboBox.setSelectedItem(evt.getNewValue()); 
-            } 
+                this.conditionsTagComboBox.setSelectedItem(evt.getNewValue());
+            }
         } 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) {
-            if (evt.getSource() instanceof ConfigurationModel) {
-                Object value = evt.getNewValue();
-                String property = evt.getPropertyName();
-                configurationModel.removePropertyChangeListener(this);
-                try {
-                    if (property.equals(ConfigurationModel.DETECTOR_NAME_PROPERTY)) {
-                        detectorNameComboBox.setSelectedItem((String) value);
-                    } else if (property.equals(ConfigurationModel.DETECTOR_ALIAS_PROPERTY)) {
-                        detectorAliasField.setText((String) value);
-                    } else if (property.equals(ConfigurationModel.DISCONNECT_ON_ERROR_PROPERTY)) {
-                        disconnectOnErrorCheckBox.setSelected((Boolean) value);
-                    } else if (property.equals(ConfigurationModel.DISCONNECT_ON_END_RUN_PROPERTY)) {
-                        disconnectOnEndRunCheckBox.setSelected((Boolean) value);
-                    } else if (property.equals(ConfigurationModel.EVENT_BUILDER_PROPERTY)) {
-                        eventBuilderComboBox.setSelectedItem((String) value);
-                    } else if (property.equals(ConfigurationModel.LOG_FILE_NAME_PROPERTY)) {
-                        logFileNameField.setText((String) value);
-                    } else if (property.equals(ConfigurationModel.LOG_LEVEL_PROPERTY)) {
-                        logLevelComboBox.setSelectedItem(value.toString());
-                    } else if (property.equals(ConfigurationModel.LOG_TO_FILE_PROPERTY)) {
-                        logToFileCheckbox.setSelected((Boolean) value);
-                    } else if (property.equals(ConfigurationModel.STEERING_TYPE_PROPERTY)) {
-                        steeringTypeComboBox.setSelectedIndex(((SteeringType) value).ordinal());
-                    } else if (property.equals(ConfigurationModel.STEERING_FILE_PROPERTY)) {
-                        if (value != null) {
-                            steeringFileField.setText((String) evt.getNewValue());
-                        } else {
-                            // A null value here is actually okay and means this field should be reset to have no value.
-                            steeringFileField.setText(null);
-                        }
-                    } else if (property.equals(ConfigurationModel.STEERING_RESOURCE_PROPERTY)) {
-                        steeringResourcesComboBox.setSelectedItem(value);
-                    } else if (property.equals(ConfigurationModel.USER_RUN_NUMBER_PROPERTY)) {
-                        if (value != null) {
-                            userRunNumberField.setText(Integer.toString((int) value));
-                        } else {
-                            userRunNumberField.setText(null);
-                        }
-                    } else if (property.equals(ConfigurationModel.FREEZE_CONDITIONS_PROPERTY)) {
-                        if (value != null) {
-                            freezeConditionsCheckBox.setSelected((Boolean) value);
-                        }
-                    } else if (property.equals(ConfigurationModel.MAX_EVENTS_PROPERTY)) {
-                        if (value != null) {
-                            maxEventsField.setText(value.toString());
-                        }
-                    } else if (property.equals(ConfigurationModel.PROCESSING_STAGE_PROPERTY)) {
-                        processingStageComboBox.setSelectedItem(evt.getNewValue());
-                    } else if (property.equals(ConfigurationModel.AIDA_SERVER_NAME_PROPERTY)) {
-                        aidaServerNameField.setText((String) evt.getNewValue());
-                    }
-                } finally {
-                    configurationModel.addPropertyChangeListener(this);
-                }
-            }
-        }
-    }
-    
+            this.getConfigurationModel().addPropertyChangeListener(this);
+        }
+    }
+
     @Override
-    public void setConfigurationModel(ConfigurationModel model) {
+    public void setConfigurationModel(final ConfigurationModel model) {
         super.setConfigurationModel(model);
         model.addPropertyChangeListener(new JobSettingsChangeListener());
     }