Print

Print


Author: [log in to unmask]
Date: Tue Mar 10 13:42:48 2015
New Revision: 2390

Log:
Merge trunk into monitoring-app dev branch.

Modified:
    java/branches/monitoring-app-dev/   (props changed)
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/Commands.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventProcessing.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/LogPanel.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/LogTable.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/Main.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MenuBar.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MonitoringApplication.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/PlotPanel.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SettingsPanel.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/TriggerDiagnosticsPanel.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/ErrorHandler.java
    java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/ResourceUtil.java

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/Commands.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/Commands.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/Commands.java	Tue Mar 10 13:42:48 2015
@@ -38,13 +38,17 @@
     static final String SAVE_PLOTS = "savePlots";
     static final String CLEAR_PLOTS = "resetPlots";
     
+    // 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 LOG_LEVEL_FILTER_CHANGED = "logLevelFilterChanged";    
     
-    static final String START_AIDA_SERVER = "startAIDAServer";
-    static final String STOP_AIDA_SERVER = "stopAIDAServer";
-        
+    static final String CONDITIONS_TAG_CHANGED = "conditionsTagChanged";
+    
     ////////////////////////////////////////////    
     static final String BLOCKING_CHANGED = "blockingChanged";
     static final String CHOOSE_COMPACT_FILE = "chooseCompactFile";
@@ -62,10 +66,7 @@
     static final String FREEZE_CONDITIONS_CHANGED = "freezeConditionsChanged";
     
     static final String LOG_LEVEL_CHANGED = "logLevelChanged";
-    static final String LOG_TO_FILE = "logToFile";
-    static final String LOG_TO_FILE_CHANGED = "logToFileChanged";
-    static final String LOG_TO_TERMINAL = "logToTerminal";
-
+    
     static final String PROCESSING_STAGE_CHANGED = "processingStageChanged";    
     static final String SAVE_LOG_TABLE = "saveLogTable";            
     static final String SELECT_LOG_FILE = "logToFile";

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventProcessing.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventProcessing.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventProcessing.java	Tue Mar 10 13:42:48 2015
@@ -114,6 +114,13 @@
             } else if (steeringType.equals(SteeringType.FILE)) {
                 setupSteeringFile(steering);
             }
+            
+            // Set conditions tag.
+            if (configurationModel.hasValidProperty(ConfigurationModel.CONDITIONS_TAG_PROPERTY) && !configurationModel.getConditionsTag().equals("")) {
+                logger.config("conditions tag is set to " + configurationModel.getConditionsTag());                
+            } else {
+                logger.config("conditions NOT using a tag");
+            }
            
             // Is there a user specified run number from the JobPanel?
             if (configurationModel.hasValidProperty(ConfigurationModel.USER_RUN_NUMBER_PROPERTY)) {
@@ -128,7 +135,7 @@
                     conditionsManager.freeze();
                 } else {
                     // Allow run numbers to be picked up from the events.
-                    logger.config("user run number specified but conditions system is NOT frozen");
+                    logger.config("user run number provided but conditions system is NOT frozen");
                     conditionsManager.unfreeze();
                 }
             }
@@ -270,6 +277,8 @@
                 try {
                     logger.info("waiting for event processing thread to finish");
                     // This should always work, because the ET system is disconnected before this.
+                    sessionState.processingThread.interrupt();
+                    sessionState.processingThread.stop();
                     sessionState.processingThread.join();
                     logger.info("event processing thread finished");
                 } catch (InterruptedException e) {

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/JobSettingsPanel.java	Tue Mar 10 13:42:48 2015
@@ -18,8 +18,10 @@
 import javax.swing.JComboBox;
 import javax.swing.JFileChooser;
 import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
 import javax.swing.filechooser.FileFilter;
 
+import org.hps.conditions.database.DatabaseConditionsManager;
 import org.hps.monitoring.application.model.ConfigurationModel;
 import org.hps.monitoring.application.model.SteeringType;
 import org.hps.monitoring.application.util.ResourceUtil;
@@ -39,15 +41,16 @@
     private JComboBox<?> steeringTypeComboBox;
     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 JTextField logFileNameField;
+    private JCheckBox disconnectOnEndRunCheckBox;    
     private JComboBox<?> logLevelComboBox;
     private JCheckBox logToFileCheckbox;
+    private JTextField logFileNameField;
            
     // The package where steering resources must be located.
     static final String STEERING_PACKAGE = "org/hps/steering/monitoring/";
@@ -68,9 +71,13 @@
     /**
      * Class constructor.
      */
-    JobSettingsPanel() {
-
-        super(new Insets(4, 2, 2, 4), true);
+    JobSettingsPanel(ConfigurationModel model) {
+
+        super(new Insets(5, 3, 3, 5), true);
+        
+        setBorder(new EmptyBorder(10, 10, 10, 10));
+        
+        model.addPropertyChangeListener(this);
         
         setLayout(new GridBagLayout());
 
@@ -102,12 +109,21 @@
         compactXmlButton.setActionCommand(Commands.CHOOSE_COMPACT_FILE);
         compactXmlButton.addActionListener(this);
 
-        userRunNumberField = addField("User Run Number", "", 10, false);
+        userRunNumberField = addField("User Run Number", "", 10, true);
         userRunNumberField.addPropertyChangeListener("value", this);
         userRunNumberField.setActionCommand(USER_RUN_NUMBER_CHANGED);
         userRunNumberField.setEnabled(true);
         userRunNumberField.setEditable(true);
         
+        
+        conditionsTagComboBox = addComboBox("Conditions Tag", ResourceUtil.getConditionsTags());
+        conditionsTagComboBox.addItem("");
+        conditionsTagComboBox.setSelectedItem("");
+        conditionsTagComboBox.setActionCommand(CONDITIONS_TAG_CHANGED);
+        conditionsTagComboBox.addActionListener(this);
+        conditionsTagComboBox.setEditable(false);
+        conditionsTagComboBox.setEnabled(true);
+                
         freezeConditionsCheckBox = addCheckBox("Freeze detector conditions", false, true);
         freezeConditionsCheckBox.addActionListener(this);
         freezeConditionsCheckBox.setActionCommand(FREEZE_CONDITIONS_CHANGED);
@@ -136,11 +152,9 @@
                                             
         logToFileCheckbox = addCheckBox("Log to File", false, false);
         logToFileCheckbox.setEnabled(false);
-        logToFileCheckbox.setActionCommand(LOG_TO_FILE_CHANGED);
-        logToFileCheckbox.addActionListener(this);
-
-        logFileNameField = addField("Log File", "", "Full path to log file.", 30, false);
-        logFileNameField.addPropertyChangeListener("value", this);
+
+        logFileNameField = addField("Log File Name", "", "Full path to log file.", 50, false);
+        logFileNameField.setEditable(false);
     }
 
     @Override
@@ -152,8 +166,6 @@
      * Attaches the ActionListener from the main app to specific GUI components in this class.
      */
     public void addActionListener(ActionListener listener) {
-        logFileNameField.addActionListener(listener);
-        logToFileCheckbox.addActionListener(listener);
         steeringResourcesComboBox.addActionListener(listener);
         freezeConditionsCheckBox.addActionListener(listener);
     }
@@ -252,8 +264,6 @@
                 configurationModel.setSteeringType(SteeringType.valueOf((String) steeringTypeComboBox.getSelectedItem()));
             } else if (STEERING_RESOURCE_CHANGED.equals(event.getActionCommand())) {
                 configurationModel.setSteeringResource((String) steeringResourcesComboBox.getSelectedItem());
-            } else if (LOG_TO_FILE_CHANGED.equals(event.getActionCommand())) {
-                configurationModel.setLogToFile(logToFileCheckbox.isSelected());
             } else if (LOG_LEVEL_CHANGED.equals(event.getActionCommand())) {
                 configurationModel.setLogLevel(Level.parse((String) logLevelComboBox.getSelectedItem()));
             } else if (EVENT_BUILDER_CHANGED.equals(event.getActionCommand())) {
@@ -272,6 +282,8 @@
                 }
             } else if (DETECTOR_ALIAS_CHANGED.equals(event.getActionCommand())) {
                 configurationModel.setDetectorName(detectorAliasField.getText());
+            } else if (CONDITIONS_TAG_CHANGED.equals(event.getActionCommand())) {
+                configurationModel.setConditionsTag((String) conditionsTagComboBox.getSelectedItem());
             }
         } finally {
             configurationModel.addPropertyChangeListener(this);
@@ -279,8 +291,8 @@
     }
 
     /**
-     * Updates the configuration with changes from the GUI component values. The changes from the
-     * GUI are distinguishable by their component object.
+     * 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) {                            
@@ -289,8 +301,6 @@
             Object source = evt.getSource();            
             if (source == steeringFileField) {
                 configurationModel.setSteeringFile(steeringFileField.getText());
-            } else if (source == logFileNameField) {
-                configurationModel.setLogFileName(logFileNameField.getText());
             } else if (source == userRunNumberField) {
                 // Is run number being reset to null or empty?
                 if (userRunNumberField.getText() == null || userRunNumberField.getText().isEmpty()) {
@@ -300,12 +310,10 @@
                     configurationModel.setFreezeConditions(false);
                 } else {
                     try {
-                        // System.out.println("setting new user run number " + evt.getNewValue());
                         // Parse the run number. Need to catch errors because it might be an invalid string.
                         int userRunNumber = Integer.parseInt(userRunNumberField.getText());
                         configurationModel.setUserRunNumber(userRunNumber);
                         configurationModel.setFreezeConditions(true);
-                        System.out.println("successfully set run number to userRunNumber");
                     } catch (NumberFormatException e) {
                         System.out.println("bad number format so ignoring user run number " + evt.getNewValue());
                         userRunNumberField.setText((String) evt.getOldValue());
@@ -314,7 +322,23 @@
                 }
             } else if (source == maxEventsField) {
                 configurationModel.setMaxEvents(Long.parseLong(maxEventsField.getText()));
-                System.out.println("setMaxEvents - " + configurationModel.getMaxEvents());
+                //System.out.println("setMaxEvents - " + configurationModel.getMaxEvents());
+            } 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();
+                if (logToFile != null) {
+                    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();
+                if (logFileName != null && logFileName.length() > 0) {
+                    logFileNameField.setText(logFileName);
+                } else {
+                    logFileNameField.setText("");
+                }
+            } else if (evt.getPropertyName().equals(ConfigurationModel.CONDITIONS_TAG_PROPERTY)) {
+                conditionsTagComboBox.setSelectedItem(evt.getNewValue()); 
             }
         } finally {
             configurationModel.addPropertyChangeListener(this);
@@ -358,7 +382,7 @@
                         steeringTypeComboBox.setSelectedIndex(((SteeringType) value).ordinal());
                     } else if (evt.getPropertyName().equals(STEERING_FILE_PROPERTY)) {
                         if (value != null) {
-                            steeringFileField.setText((String) value);
+                            steeringFileField.setText(((File) value).getAbsolutePath());
                         } else {
                             // A null value here is actually okay and means this field should be reset to have no value.
                             steeringFileField.setText(null);

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java	Tue Mar 10 13:42:48 2015
@@ -16,7 +16,7 @@
  * 
  * @author Jeremy McCormick <[log in to unmask]>
  */
-public class LogLevelFilterComboBox extends JComboBox<Level> implements ActionListener, PropertyChangeListener {
+class LogLevelFilterComboBox extends JComboBox<Level> implements ActionListener, PropertyChangeListener {
    
     ConfigurationModel configurationModel;
     

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/LogPanel.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/LogPanel.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/LogPanel.java	Tue Mar 10 13:42:48 2015
@@ -17,11 +17,16 @@
  * This is a simple GUI component for the log table and its controls.
  * @author Jeremy McCormick <[log in to unmask]>
  */
-public class LogPanel extends JPanel {
+class LogPanel extends JPanel{ 
 
     LogTable logTable;
+    LogLevelFilterComboBox logFilterComboBox;
+    
+    ConfigurationModel configurationModel;
         
     LogPanel(ConfigurationModel configurationModel, ActionListener listener) {
+        
+        this.configurationModel = configurationModel;
         
         setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
         
@@ -31,8 +36,8 @@
         controlsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 5));
         
         JLabel label = new JLabel("Log Level Filter");
-        LogLevelFilterComboBox logFilterComboBox = new LogLevelFilterComboBox(configurationModel);
-        logFilterComboBox.setToolTipText("Messages below this level will be filtered out.");              
+        logFilterComboBox = new LogLevelFilterComboBox(configurationModel);
+        logFilterComboBox.setToolTipText("Messages below this level will be filtered out.");
         controlsPanel.add(label);        
         controlsPanel.add(logFilterComboBox);
         
@@ -51,5 +56,5 @@
                 
         add(controlsPanel, BorderLayout.PAGE_START);
         add(tablePane, BorderLayout.PAGE_END);
-    }    
+    }          
 }

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/LogTable.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/LogTable.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/LogTable.java	Tue Mar 10 13:42:48 2015
@@ -132,5 +132,5 @@
             filterLevel = (Level) event.getNewValue();
             model.fireTableDataChanged();
         }
-    }
+    }    
 }

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/Main.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/Main.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/Main.java	Tue Mar 10 13:42:48 2015
@@ -10,7 +10,6 @@
 import org.apache.commons.cli.ParseException;
 import org.apache.commons.cli.PosixParser;
 import org.hps.monitoring.application.model.Configuration;
-
 
 /**
  * This is the front-end for running the monitoring app via a {@link #main(String[])} method.

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MenuBar.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MenuBar.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MenuBar.java	Tue Mar 10 13:42:48 2015
@@ -39,17 +39,17 @@
     JMenuItem closeFileItem;
     JMenuItem openFileItem;    
     JMenu settingsMenu;
-    JMenuItem serverItem;
-    ConfigurationModel configurationModel;
+    JMenuItem logItem;
+    ConfigurationModel configurationModel;    
     
     MenuBar(ConfigurationModel configurationModel, ConnectionStatusModel connectionModel, ActionListener listener) {
-        
-        // Do not need to listen for changes on this model.
-        this.configurationModel = configurationModel;
+         
+        this.configurationModel = configurationModel;        
+        this.configurationModel.addPropertyChangeListener(this);
         
         // Need to listen for connection status changes.
-        connectionModel.addPropertyChangeListener(this);                
-
+        connectionModel.addPropertyChangeListener(this);  
+        
         JMenu fileMenu = new JMenu("File");
         fileMenu.setMnemonic(KeyEvent.VK_F);
         add(fileMenu);
@@ -147,6 +147,14 @@
         screenshotItem.setToolTipText("Save a screenshot to a graphics file");
         toolsMenu.add(screenshotItem);
         
+        logItem = new JMenuItem("Log to File ...");
+        logItem.setMnemonic(KeyEvent.VK_R);
+        logItem.setActionCommand(Commands.LOG_TO_FILE);
+        logItem.addActionListener(listener);
+        logItem.setEnabled(true);
+        logItem.setToolTipText("Redirect System.out to a file instead of terminal");
+        toolsMenu.add(logItem);
+        
         JMenu windowMenu = new JMenu("Window");
         windowMenu.setMnemonic(KeyEvent.VK_W);
         add(windowMenu);
@@ -173,16 +181,34 @@
         defaultsItem.addActionListener(listener);
         defaultsItem.setEnabled(true);
         defaultsItem.setToolTipText("Restore the window defaults");
-        windowMenu.add(defaultsItem);        
+        windowMenu.add(defaultsItem);
     }
 
     @Override
     public void propertyChange(PropertyChangeEvent evt) {
-        if (evt.getPropertyName().equals(ConnectionStatusModel.CONNECTION_STATUS_PROPERTY)) {
-            ConnectionStatus status = (ConnectionStatus) evt.getNewValue();
-            boolean connected = status.equals(ConnectionStatus.CONNECTED);            
-            closeFileItem.setEnabled(!connected);
-            openFileItem.setEnabled(!connected);
+        configurationModel.removePropertyChangeListener(this);        
+        try {            
+            if (evt.getPropertyName().equals(ConnectionStatusModel.CONNECTION_STATUS_PROPERTY)) {
+                ConnectionStatus status = (ConnectionStatus) evt.getNewValue();
+                boolean connected = status.equals(ConnectionStatus.CONNECTED);
+                closeFileItem.setEnabled(!connected);
+                openFileItem.setEnabled(!connected);
+            } else if (evt.getPropertyName().equals(ConfigurationModel.LOG_TO_FILE_PROPERTY)) {
+                Boolean logToFile = (Boolean) evt.getNewValue();
+                if (logToFile == true) {
+                    // Toggle log item state to send to terminal.
+                    logItem.setText("Log to Terminal ...");
+                    logItem.setActionCommand(Commands.LOG_TO_TERMINAL);
+                    logItem.setToolTipText("Log messages to the terminal");
+                } else {
+                    // Toggle log item state to send to file.
+                    logItem.setText("Log to File ...");
+                    logItem.setActionCommand(Commands.LOG_TO_FILE);
+                    logItem.setToolTipText("Log messages to a file");
+                }
+            }
+        } finally {
+            configurationModel.addPropertyChangeListener(this);
         }
     }
 
@@ -195,8 +221,7 @@
                 closeFileItem.setEnabled(false);
             }
         }        
-    }
-    
+    }    
     void setServerConnected(boolean connected) {
         if (connected) {
             serverItem = new JMenuItem("Stop AIDA Server");

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MonitoringApplication.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MonitoringApplication.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MonitoringApplication.java	Tue Mar 10 13:42:48 2015
@@ -14,7 +14,10 @@
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.List;
@@ -73,7 +76,9 @@
     static final Level DEFAULT_LEVEL = Level.ALL;
 
     // Default log stream.
-    PrintStream logStream = System.out;
+    MonitoringApplicationStreamHandler streamHandler;
+    PrintStream sysOut = System.out;
+    PrintStream sysErr = System.err;
     
     // Application error handling.
     final ErrorHandler errorHandler;
@@ -126,6 +131,22 @@
     
     LogTable getLogTable() {
         return frame.logPanel.logTable;
+    }
+    
+    class MonitoringApplicationStreamHandler extends StreamHandler {
+        
+        MonitoringApplicationStreamHandler(PrintStream ps) {
+            super(ps, new DefaultLogFormatter());
+        }
+        
+        public void publish(LogRecord record) {
+            super.publish(record);
+            flush();
+        }
+        
+        public void setOutputStream(OutputStream out) {
+            super.setOutputStream(out);
+        }        
     }
              
     /**
@@ -162,6 +183,21 @@
         loadConfiguration(this.configuration);
                 
         logger.info("application initialized successfully");
+    }
+    
+    /**
+     * Setup the logger.
+     */
+    void setupLogger() {
+        logger.setUseParentHandlers(false);        
+        logger.addHandler(new LogHandler());
+        streamHandler = new MonitoringApplicationStreamHandler(System.out);
+        logger.addHandler(streamHandler);
+        for (Handler handler : logger.getHandlers()) {
+            handler.setLevel(DEFAULT_LEVEL);
+        }
+        logger.setLevel(DEFAULT_LEVEL);
+        logger.info("logging initialized");
     }
     
     /**
@@ -231,10 +267,10 @@
             saveLogTable();
         } else if (Commands.CLEAR_LOG_TABLE.equals(cmd)) {
             getLogRecordModel().clear();
-        } else if (Commands.START_AIDA_SERVER.equals(cmd)) {
-            startAIDAServer();
-        } else if (Commands.STOP_AIDA_SERVER.equals(cmd)) {
-            stopAIDAServer();
+        } else if (Commands.LOG_TO_FILE.equals(cmd)) {
+            chooseLogFile();
+        } else if (Commands.LOG_TO_TERMINAL.equals(cmd)) {
+            logToTerminal();
         }
     }    
     
@@ -261,26 +297,7 @@
         // Perform global configuration of the JFreeChart back end.
         AnalysisFactory.configure();
     }
-    
-    /**
-     * Setup the logger.
-     */
-    void setupLogger() {
-        logger.setUseParentHandlers(false);
-        logger.addHandler(new LogHandler());
-        logger.addHandler(new StreamHandler(logStream, new DefaultLogFormatter()) {
-            public void publish(LogRecord record) {
-                super.publish(record);
-                flush();
-            }
-        });
-        for (Handler handler : logger.getHandlers()) {
-            handler.setLevel(DEFAULT_LEVEL);
-        }
-        logger.setLevel(DEFAULT_LEVEL);
-        logger.info("logging initialized");
-    }
-            
+                
     /**
      * This method sets the configuration on the model, which fires a change for every property.
      * @param configuration The new configuration.
@@ -650,28 +667,88 @@
     void saveLogTable() {
         saveTable(frame.logPanel.logTable);
     }
-    
-    /**
-     * Start the AIDA RMI server.
-     */
-    void startAIDAServer() {
-        boolean started = server.start();
-        frame.menu.setServerConnected(started);
-        if (started) {
-            logger.info("AIDA server started at " + server.getName());
-            DialogUtil.showInfoDialog(frame, "AIDA Server Started", "The AIDA server was started.");
-        } else {
-            DialogUtil.showErrorDialog(frame, "AIDA Server Error", "The AIDA server failed to start.");
-        }
-    }
-    
-    /**
-     * Stop the AIDA server.
-     */
-    void stopAIDAServer() {
-        server.disconnect();
-        frame.menu.setServerConnected(false);
-        logger.info("AIDA server stopped");
-        DialogUtil.showInfoDialog(frame, "AIDA Server Stopped", "The AIDA server was stopped.");
+        
+    /**
+     * Redirect <code>System.out</code> and <code>System.err</code> to file chosen
+     * by a file chooser.
+     */
+    void chooseLogFile() {
+        JFileChooser fc = new JFileChooser();
+        fc.setAcceptAllFileFilterUsed(false);
+        fc.setDialogTitle("Save Log Messages to File");       
+        fc.setCurrentDirectory(new File("."));
+        int r = fc.showSaveDialog(frame);
+        if (r == JFileChooser.APPROVE_OPTION) {            
+            String fileName = fc.getSelectedFile().getPath();
+            if (new File(fileName).exists()) {
+                DialogUtil.showErrorDialog(frame, "File Exists", "File already exists.");
+            } else {
+                logToFile(new File(fileName));
+            }
+        }        
+    }
+    
+    /**
+     * Redirect <code>System.out</code> and <code>System.err</code> to a file.
+     * @param file The output log file.
+     * @throws FileNotFoundException if the file does not exist.
+     */
+    void logToFile(File file) {
+        try {
+            
+            // Create the output file stream.
+            PrintStream fileStream = new PrintStream(new FileOutputStream(file.getPath()));
+            System.setOut(fileStream);
+            System.setErr(fileStream);
+            
+            // Flush the current handler, but do NOT close here or System.out gets clobbered!
+            streamHandler.flush();
+            
+            // Replace the current handler with one using the file stream.
+            logger.removeHandler(streamHandler);
+            streamHandler = new MonitoringApplicationStreamHandler(fileStream);
+            streamHandler.setLevel(logger.getLevel());
+            logger.addHandler(streamHandler);
+            
+            // Set the properties on the model.
+            configurationModel.setLogFileName(file.getPath());
+            configurationModel.setLogToFile(true);
+            
+            logger.info("Saving log messages to " + configurationModel.getLogFileName());
+            DialogUtil.showInfoDialog(frame, "Logging to File", 
+                    "Log messages redirected to file" + '\n' + configurationModel.getLogFileName());
+            
+        } catch (FileNotFoundException e) {
+            errorHandler.setError(e).log().showErrorDialog();
+        }
+    }      
+    
+    /**
+     * Send <code>System.out</code> and <code>System.err</code> back to the terminal, 
+     * e.g. if they were previously sent to a file.
+     */
+    void logToTerminal() {
+        
+        // Reset System.out and err back to original streams.
+        System.setOut(sysOut);
+        System.setErr(sysErr);
+        
+        // Flush and close the current handler, which is using a file stream.
+        streamHandler.flush();
+        streamHandler.close();
+        
+        // Replace the handler with the one printing to the terminal.
+        logger.removeHandler(streamHandler);               
+        streamHandler = new MonitoringApplicationStreamHandler(System.out);
+        streamHandler.setLevel(logger.getLevel());
+        logger.addHandler(streamHandler);
+        
+        logger.log(Level.INFO, "log messages redirected to terminal");
+        
+        // Update the model to indicate logging to file has been disabled.
+        configurationModel.setLogToFile(false);
+        
+        DialogUtil.showInfoDialog(frame, "Log to Terminal", "Log messages will be sent to the terminal.");
     }    
+       
 }

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java	Tue Mar 10 13:42:48 2015
@@ -38,9 +38,9 @@
 /**
  * <p>
  * This is a GUI component for showing the statistics and other information about an AIDA plot
- * when it is clicked on in the monitoring app.
+ * when it is clicked on in the monitoring application.
  * <p>
- * The information is updated dynamically via the <code>AIDAObserver</code> API on the AIDA object.
+ * The information in the table is updated dynamically via the <code>AIDAObserver</code> API on the AIDA object.
  */
 class PlotInfoPanel extends JPanel implements AIDAListener, ActionListener, FunctionListener {
 

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/PlotPanel.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/PlotPanel.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/PlotPanel.java	Tue Mar 10 13:42:48 2015
@@ -6,7 +6,7 @@
 import javax.swing.JTabbedPane;
 
 /**
- * This is the panel containing the monitoring plots.
+ * This is the panel containing the tabs with the monitoring plots.
  * @author Jeremy McCormick <[log in to unmask]>
  */
 class PlotPanel extends JPanel {

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SettingsPanel.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SettingsPanel.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SettingsPanel.java	Tue Mar 10 13:42:48 2015
@@ -31,7 +31,7 @@
         this.parent = parent;
         
         connectionPanel = new ConnectionSettingsPanel();        
-        jobPanel = new JobSettingsPanel();
+        jobPanel = new JobSettingsPanel(configurationModel);
         
         // Push configuration to sub-components.
         connectionPanel.setConfigurationModel(configurationModel);
@@ -55,7 +55,6 @@
         add(Box.createRigidArea(new Dimension(1, 5)));
         JPanel buttonsPanel = new JPanel();
         buttonsPanel.add(okayButton);
-        //buttonsPanel.add(defaultsButton);
         buttonsPanel.setLayout(new FlowLayout());
         add(buttonsPanel);
         add(Box.createRigidArea(new Dimension(1, 5)));

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/TriggerDiagnosticsPanel.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/TriggerDiagnosticsPanel.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/TriggerDiagnosticsPanel.java	Tue Mar 10 13:42:48 2015
@@ -21,7 +21,7 @@
  * 
  * @author Jeremy McCormick <[log in to unmask]>
  */
-public class TriggerDiagnosticsPanel extends JPanel {
+class TriggerDiagnosticsPanel extends JPanel {
 
     JTabbedPane tabs = new JTabbedPane();
     ClusterTablePanel clusterPanel = new ClusterTablePanel();
@@ -70,9 +70,7 @@
                 for (DiagnosticUpdatable update : updateList) {
                     update.updatePanel(snapshot);
                 }
-            } else {
-                System.out.println("no diag snapshot in event");
-            }
+            } 
         }
         
         void setDiagnosticCollectionName(String name) {

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/ConfigurationModel.java	Tue Mar 10 13:42:48 2015
@@ -16,6 +16,7 @@
     Configuration configuration;    
     
     // Job setting properties.
+    public static final String CONDITIONS_TAG_PROPERTY = "ConditionsTag";
     public static final String DETECTOR_NAME_PROPERTY = "DetectorName";
     public static final String DETECTOR_ALIAS_PROPERTY = "DetectorAlias";
     public static final String DISCONNECT_ON_ERROR_PROPERTY = "DisconnectOnError";
@@ -392,6 +393,16 @@
     public String getEtPath() {
         return getEtName() + "@" + getHost() + ":" + getPort();
     }
+    
+    public void setConditionsTag(String conditionsTag) {
+        String oldValue = getConditionsTag();
+        configuration.set(CONDITIONS_TAG_PROPERTY, conditionsTag);
+        firePropertyChange(CONDITIONS_TAG_PROPERTY, oldValue, getConditionsTag());
+    }     
+    
+    public String getConditionsTag() {
+        return configuration.get(CONDITIONS_TAG_PROPERTY);
+    }
 
     public void remove(String property) {
         if (hasPropertyKey(property)) {

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/ErrorHandler.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/ErrorHandler.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/ErrorHandler.java	Tue Mar 10 13:42:48 2015
@@ -85,7 +85,7 @@
      * @return This object.
      */
     public ErrorHandler log() {
-        logger.log(Level.SEVERE, message);
+        logger.log(Level.SEVERE, message, error);
         return this;
     }
 

Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/ResourceUtil.java
 =============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/ResourceUtil.java	(original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/ResourceUtil.java	Tue Mar 10 13:42:48 2015
@@ -14,6 +14,7 @@
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 
+import org.hps.conditions.database.DatabaseConditionsManager;
 import org.hps.record.LCSimEventBuilder;
 import org.reflections.Reflections;
 
@@ -116,4 +117,8 @@
         Collections.sort(detectorNames);
         return detectorNames.toArray(new String[detectorNames.size()]);
     }        
+    
+    public static String[] getConditionsTags() {
+        return DatabaseConditionsManager.getInstance().getTags().toArray(new String[] {});
+    }
 }