Print

Print


Commit in java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui on MAIN
AbstractFieldsPanel.java+3-11058 -> 1059
Commands.java+3-11058 -> 1059
DataSourcePanel.java+46-391058 -> 1059
DialogUtil.java+70added 1059
MonitoringApplication.java+104-451058 -> 1059
+226-86
1 added + 4 modified, total 5 files
Improvements to selection and validation of file sources.

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui
AbstractFieldsPanel.java 1058 -> 1059
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/AbstractFieldsPanel.java	2014-09-19 00:18:47 UTC (rev 1058)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/AbstractFieldsPanel.java	2014-09-19 02:48:45 UTC (rev 1059)
@@ -1,6 +1,7 @@
 package org.hps.monitoring.gui;
 
 import java.awt.Color;
+import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.GridBagConstraints;
 import java.awt.Insets;
@@ -11,6 +12,7 @@
 import javax.swing.JCheckBox;
 import javax.swing.JComboBox;
 import javax.swing.JFormattedTextField;
+import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JTextField;
@@ -248,7 +250,7 @@
         ++currY;
         return button;
     }
-    
+        
     /**
      * Add an ActionListener to this component.  By default this does nothing, but 
      * individual sub-components should attach this to individual components.

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui
Commands.java 1058 -> 1059
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/Commands.java	2014-09-19 00:18:47 UTC (rev 1058)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/Commands.java	2014-09-19 02:48:45 UTC (rev 1059)
@@ -10,6 +10,7 @@
     static final String AIDA_AUTO_SAVE_CHANGED = "aidaAutoSaveChanged";
     static final String BLOCKING_CHANGED = "blockingChanged";
     static final String CHOOSE_LOG_FILE = "chooseLogFile";
+    static final String CHOOSE_FILE_SOURCE = "chooseFileSource";
     static final String CHOOSE_STEERING_FILE = "chooseSteeringFile";
     static final String CONNECT = "connect";
     static final String CLEAR_LOG_TABLE = "clearLogTable";
@@ -33,7 +34,7 @@
     static final String SAVE_LOG_TABLE = "saveLogTable";
     static final String SAVE_PLOTS = "savePlots";
     static final String SCREENSHOT = "screenshot";
-    static final String SELECT_CONFIG_FILE = "selectConfigFile";
+    static final String SELECT_CONFIG_FILE = "selectConfigFile";    
     static final String SELECT_LOG_FILE = "logToFile";
     static final String SET_EVENT_BUILDER = "setEventBuilder";
     static final String SET_STEERING_RESOURCE = "setSteeringResource";
@@ -41,5 +42,6 @@
     static final String STEERING_TYPE_CHANGED = "steeringTypeChanged";
     static final String STEERING_RESOURCE_CHANGED = "steeringResourceChanged";                   
     static final String VERBOSE_CHANGED = "verboseChanged";
+    static final String VALIDATE_DATA_FILE = "validateDataFile";
     static final String WAIT_MODE_CHANGED = "waitModeChanged";                         
 }
\ No newline at end of file

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui
DataSourcePanel.java 1058 -> 1059
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/DataSourcePanel.java	2014-09-19 00:18:47 UTC (rev 1058)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/DataSourcePanel.java	2014-09-19 02:48:45 UTC (rev 1059)
@@ -1,20 +1,25 @@
 package org.hps.monitoring.gui;
 
+import static org.hps.monitoring.gui.Commands.CHOOSE_FILE_SOURCE;
 import static org.hps.monitoring.gui.Commands.DATA_SOURCE_TYPE_CHANGED;
 import static org.hps.monitoring.gui.Commands.PROCESSING_STAGE_CHANGED;
+import static org.hps.monitoring.gui.Commands.VALIDATE_DATA_FILE;
 import static org.hps.monitoring.gui.model.ConfigurationModel.DATA_SOURCE_PATH_PROPERTY;
 import static org.hps.monitoring.gui.model.ConfigurationModel.DATA_SOURCE_TYPE_PROPERTY;
 import static org.hps.monitoring.gui.model.ConfigurationModel.PROCESSING_STAGE_PROPERTY;
 
 import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.File;
 
+import javax.swing.JButton;
 import javax.swing.JComboBox;
 import javax.swing.JFileChooser;
 import javax.swing.JTextField;
+import javax.swing.filechooser.FileNameExtensionFilter;
 
 import org.hps.monitoring.gui.model.ConfigurationModel;
 import org.hps.record.enums.DataSourceType;
@@ -39,7 +44,9 @@
     };
     
     JComboBox<?> dataSourceTypeComboBox;
-    JTextField dataSourcePathField;    
+    JTextField dataSourcePathField;
+    JButton fileSourceButton;
+    JButton validateDataFileButton;
     JComboBox<?> processingStageComboBox;
     
     ConfigurationModel configurationModel;
@@ -53,25 +60,48 @@
         dataSourceTypeComboBox.addActionListener(this);
         
         dataSourcePathField = addField("Data Source Path", 40);
-        dataSourcePathField.addPropertyChangeListener(this);       
+        dataSourcePathField.addPropertyChangeListener(this);
         
+        fileSourceButton = addButton("Select data file");
+        fileSourceButton.setActionCommand(CHOOSE_FILE_SOURCE);
+        fileSourceButton.addActionListener(this);
+        
+        validateDataFileButton = addButton("Validate data file");
+        validateDataFileButton.setActionCommand(VALIDATE_DATA_FILE);
+                
         processingStageComboBox = addComboBox("Processing Stage", processingStages);
         processingStageComboBox.setSelectedIndex(2);
         processingStageComboBox.setActionCommand(PROCESSING_STAGE_CHANGED);
         processingStageComboBox.addActionListener(this);        
     }
+    
+    private String getFileExtension(String path) {
+        return path.substring(path.lastIndexOf(".") + 1);
+    }
        
-    private void chooseFile() {
+    private void chooseDataFile() {
         JFileChooser fc = new JFileChooser(System.getProperty("user.dir"));
-        fc.setDialogTitle("Select Data Source");        
+        fc.setAcceptAllFileFilterUsed(false);
+        fc.addChoosableFileFilter(new FileNameExtensionFilter("LCIO files", "slcio"));
+        fc.addChoosableFileFilter(new FileNameExtensionFilter("EVIO files", "evio"));        
+        fc.setDialogTitle("Select Data File");
         int r = fc.showDialog(this, "Select ...");
         File file = null;
         if (r == JFileChooser.APPROVE_OPTION) {
             file = fc.getSelectedFile();
             final String filePath = file.getPath();
+            final String extension = getFileExtension(filePath);
             
             // This will cause the GUI to be updated via a PropertyChangeListener.
-            configurationModel.setDataSourcePath(filePath);                      
+            configurationModel.setDataSourcePath(filePath);
+                                    
+            // This will set the combo box in the GUI to the correct state, which will then
+            // update the model.
+            if (extension.equals("slcio")) { 
+                dataSourceTypeComboBox.setSelectedIndex(DataSourceType.LCIO_FILE.ordinal());
+            } else if (extension.equals("evio")) {
+                dataSourceTypeComboBox.setSelectedIndex(DataSourceType.EVIO_FILE.ordinal());
+            } 
         }
     }
         
@@ -95,14 +125,14 @@
     public void actionPerformed(ActionEvent e) {
         if (DATA_SOURCE_TYPE_CHANGED.equals(e.getActionCommand())) {
             DataSourceType dataSourceType = DataSourceType.values()[dataSourceTypeComboBox.getSelectedIndex()];
-            configurationModel.setDataSourceType(dataSourceType);
-            if (dataSourceType.isFile()) { 
-                chooseFile();
-            }
+            configurationModel.setDataSourceType(dataSourceType);            
+            validateDataFileButton.setEnabled(dataSourceType.isFile());
         } else if (PROCESSING_STAGE_CHANGED.equals(e.getActionCommand())) {
             ProcessingStage processingStage = ProcessingStage.values()[processingStageComboBox.getSelectedIndex()];
             configurationModel.setProcessingStage(processingStage);
-        }
+        } else if (CHOOSE_FILE_SOURCE.equals(e.getActionCommand())) { 
+            chooseDataFile();
+        } 
     }
     
     public void propertyChange(PropertyChangeEvent evt) {
@@ -116,18 +146,11 @@
     public class DataSourceChangeListener implements PropertyChangeListener {
         @Override
         public void propertyChange(PropertyChangeEvent evt) {
-            
-            // FIXME: Anyway to make sure this is not needed?
             if (evt.getPropertyName().equals("ancestor"))
-                return;
-            
-            //System.out.println("DataSourceChangeListener.propertyChange");
-            //System.out.println("  source: " + evt.getSource());
-            //System.out.println("  name: " + evt.getPropertyName());
-            //System.out.println("  value: " + evt.getNewValue());
-            Object value = evt.getNewValue();            
+                return;            
+            Object value = evt.getNewValue();
             if (DATA_SOURCE_TYPE_PROPERTY.equals(evt.getPropertyName())) {
-                dataSourceTypeComboBox.setSelectedItem(value.toString());
+                dataSourceTypeComboBox.setSelectedIndex(((DataSourceType)evt.getNewValue()).ordinal());
             } else if (DATA_SOURCE_PATH_PROPERTY.equals(evt.getPropertyName())) {
                 dataSourcePathField.setText((String) value); 
             } else if (PROCESSING_STAGE_PROPERTY.equals(evt.getPropertyName())) {
@@ -136,24 +159,8 @@
         }
     }
     
-    /*
-    void checkFile() throws IOException {
-        DataSourceType dataSourceType = DataSourceType.values()[this.dataSourceTypeComboBox.getSelectedIndex()];
-        if (!dataSourceType.isFile())
-            return;
-        File file = new File(dataSourcePathField.getText());
-        if (!file.exists()) {
-            throw new IOException("File " + file + " does not exist!");
-        }
-        if (dataSourceType.equals(DataSourceType.EVIO_FILE)) {
-            try {
-                new EvioReader(file, false, false);
-            } catch (EvioException e) {
-                throw new IOException("Error with EVIO file.", e);
-            }
-        } else if (dataSourceType.equals(DataSourceType.LCIO_FILE)) {
-            new LCIOReader(file);
-        }
+    public void addActionListener(ActionListener listener) {
+        // Hook the validate button to the main app where that task actually executes.
+        validateDataFileButton.addActionListener(listener);
     }
-    */    
 }
\ No newline at end of file

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui
DialogUtil.java added at 1059
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/DialogUtil.java	                        (rev 0)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/DialogUtil.java	2014-09-19 02:48:45 UTC (rev 1059)
@@ -0,0 +1,70 @@
+package org.hps.monitoring.gui;
+
+import java.awt.Component;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+
+class DialogUtil {
+      
+    static JDialog showStatusDialog(
+            final Component parentComponent, 
+            String title, 
+            String message) {
+        final JOptionPane optionPane = new JOptionPane(
+                message,
+                JOptionPane.INFORMATION_MESSAGE,
+                JOptionPane.DEFAULT_OPTION, 
+                null, 
+                new Object[]{},
+                null);
+        final JDialog dialog = new JDialog();        
+        dialog.setContentPane(optionPane);
+        dialog.setTitle(title);
+        dialog.setAlwaysOnTop(true);
+        dialog.setLocationRelativeTo(null);
+        dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
+        dialog.pack();        
+        dialog.addWindowListener(new WindowAdapter() {
+            public void windowClosing(WindowEvent e) {
+                dialog.setVisible(false);
+                dialog.dispose();        
+                parentComponent.setEnabled(true);
+            }
+        });
+        parentComponent.setEnabled(false);
+        optionPane.setVisible(true);
+        dialog.setVisible(true);
+        return dialog;
+    }        
+    
+    static void showErrorDialog(final Component component, final Throwable error, final String title) {
+        final Runnable runnable = new Runnable() {
+            public void run() {        
+                JOptionPane.showMessageDialog(
+                        component,
+                        error.getMessage(),                         
+                        title, 
+                        JOptionPane.ERROR_MESSAGE);
+            }
+        };
+        SwingUtilities.invokeLater(runnable);
+    }
+    
+    static void showInfoDialog(final Component component, final String title, final String message) {
+        final Runnable runnable = new Runnable() {
+            public void run() {        
+                JOptionPane.showMessageDialog(
+                        component,
+                        message,                         
+                        title, 
+                        JOptionPane.INFORMATION_MESSAGE);
+            }
+        };
+        SwingUtilities.invokeLater(runnable);
+    }
+}

java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui
MonitoringApplication.java 1058 -> 1059
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/MonitoringApplication.java	2014-09-19 00:18:47 UTC (rev 1058)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/MonitoringApplication.java	2014-09-19 02:48:45 UTC (rev 1059)
@@ -20,9 +20,11 @@
 import static org.hps.monitoring.gui.Commands.SCREENSHOT;
 import static org.hps.monitoring.gui.Commands.SELECT_CONFIG_FILE;
 import static org.hps.monitoring.gui.Commands.SHOW_SETTINGS;
+import static org.hps.monitoring.gui.Commands.VALIDATE_DATA_FILE;
 import static org.hps.monitoring.gui.model.ConfigurationModel.MONITORING_APPLICATION_LAYOUT_PROPERTY;
 import static org.hps.monitoring.gui.model.ConfigurationModel.SAVE_LAYOUT_PROPERTY;
 
+import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
@@ -90,7 +92,10 @@
 import org.hps.record.composite.EventProcessingThread;
 import org.hps.record.enums.DataSourceType;
 import org.hps.record.et.EtConnection;
+import org.jlab.coda.jevio.EvioException;
+import org.jlab.coda.jevio.EvioReader;
 import org.lcsim.job.JobControlManager;
+import org.lcsim.lcio.LCIOReader;
 import org.lcsim.util.Driver;
 import org.lcsim.util.aida.AIDA;
 
@@ -166,6 +171,8 @@
     
     // The RunModel for updating the RunPanel.
     private RunModel runModel = new RunModel();
+    
+    private FileValidationThread fileValidationThread;
                    
     /**
      * Constructor for the monitoring application.
@@ -229,6 +236,9 @@
      * @param e The event to handle.
      */
     public void actionPerformed(ActionEvent e) {
+        
+        //System.out.println("MonitoringApplication. actionPerformed: " + e.getActionCommand());
+        
         String cmd = e.getActionCommand();
         if (CONNECT.equals(cmd)) {
             // Run the start session method on a seperate thread.
@@ -281,9 +291,13 @@
             setSaveLayout();
         } else if (RESTORE_DEFAULT_GUI_LAYOUT.equals(cmd)) {
             restoreDefaultLayout();
+        } else if (VALIDATE_DATA_FILE.equals(cmd)) {
+            if (fileValidationThread == null) {
+                new FileValidationThread().start();
+            }
         }
     }
-        
+           
     /**
      * Set the GUI to visible.
      */
@@ -356,6 +370,18 @@
                 + "mesg: " + status.getMessage());
     }
     
+    public void setEnabled(boolean enabled) {
+        super.setEnabled(enabled);
+        plotWindow.setEnabled(enabled);
+        systemStatusWindow.setEnabled(enabled);
+        //settingsDialog.setEnabled(false);
+        
+        //this.setFocusable(enabled);
+        //plotWindow.setFocusable(enabled);
+        //systemStatusWindow.setFocusable(enabled);
+        //settingsDialog.setFocusable(false);
+    }
+    
     /* -------------------------- private methods ----------------------------- */
                
     /**
@@ -388,11 +414,12 @@
         settingsDialog = new SettingsDialog();
         settingsDialog.getSettingsPanel().addActionListener(this);
         getJobSettingsPanel().addActionListener(this);
+        settingsDialog.getSettingsPanel().getDataSourcePanel().addActionListener(this);
         
         // Push the ConfigurationModel to the job settings dialog.
         getJobSettingsPanel().setConfigurationModel(configurationModel);
         getConnectionSettingsPanel().setConfigurationModel(configurationModel);
-        settingsDialog.getSettingsPanel().getDataSourcePanel().setConfigurationModel(configurationModel);        
+        settingsDialog.getSettingsPanel().getDataSourcePanel().setConfigurationModel(configurationModel);               
     }
 
     /**
@@ -931,7 +958,7 @@
         log(Level.FINE, "Starting a new monitoring session.");
         
         // Show a modal window that will block the GUI until connected or an error occurs.
-        JDialog dialog = showStatusDialog("Info", "Starting new session ...", true);
+        JDialog dialog = DialogUtil.showStatusDialog(this, "Info", "Starting new session ...");
         
         try {
                         
@@ -1392,7 +1419,7 @@
      */
     private void stopSession() {
         // Show a modal message window while this method executes.
-        JDialog dialog = showStatusDialog("Info", "Disconnecting from session ...", true);
+        JDialog dialog = DialogUtil.showStatusDialog(this, "Info", "Disconnecting from session ...");
         
         try {
             // Log message.
@@ -1420,46 +1447,8 @@
             dialog.dispatchEvent(new WindowEvent(dialog, WindowEvent.WINDOW_CLOSING));
         }
     }
-                         
+                                       
     /**
-     * Show a dialog which is modal-like but will not block the current thread
-     * from executing after <code>isVisible(true)</code> is called.  It does not 
-     * have any buttons so must be closed using an action event.
-     * @param title The title of the dialog box.
-     * @param message The message to display.
-     * @param visible Whether it should be immediately visible.
-     * @return The JDialog that was created.
-     */
-    private JDialog showStatusDialog(String title, String message, boolean visible) {
-        final JOptionPane optionPane = new JOptionPane(
-                message, 
-                JOptionPane.INFORMATION_MESSAGE,
-                JOptionPane.DEFAULT_OPTION, 
-                null, 
-                new Object[]{}, 
-                null);
-        final JDialog dialog = new JDialog();
-        dialog.setContentPane(optionPane);        
-        dialog.setTitle(title);
-        dialog.setAlwaysOnTop(true);
-        dialog.setLocationRelativeTo(null);
-        dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
-        dialog.pack();        
-        dialog.addWindowListener(new WindowAdapter() {
-            public void windowClosing(WindowEvent e) {
-                dialog.setVisible(false);
-                dialog.dispose();
-                MonitoringApplication.this.setEnabled(true);
-                plotWindow.setEnabled(true);
-            }
-        });
-        MonitoringApplication.this.setEnabled(false);
-        plotWindow.setEnabled(false);
-        dialog.setVisible(visible);
-        return dialog;
-    }    
-            
-    /**
      * Finish event processing and stop its thread, first killing the session watchdog 
      * thread, if necessary.  The event processing thread may still be alive after 
      * this method, e.g. if there is a call to <code>EtSystem.getEvents()</code> happening.
@@ -1662,8 +1651,78 @@
         setConfiguration(new Configuration(DEFAULT_CONFIG_RESOURCE));
         loadConfiguration();
     }
-        
+    
     /**
+     * Validate the current file source by throwing an IOException if
+     * there appears to be a problem with it. 
+     * @throws IOException if there a problem with the current file source.
+     */
+    private void validateDataFile() throws IOException {
+        DataSourceType dataSourceType = configurationModel.getDataSourceType();        
+        if (dataSourceType.isFile()) {                                         
+            try {
+                if (configurationModel.getDataSourcePath() == null)
+                    throw new IOException("No data file set.");
+                if (configurationModel.getDataSourcePath().equals(""))
+                    throw new IOException("Data file has empty path.");
+                File file = new File(configurationModel.getDataSourcePath());
+                if (!file.exists()) {
+                    throw new IOException("File does not exist.");
+                }
+                if (dataSourceType.equals(DataSourceType.EVIO_FILE)) {
+                    try {
+                        new EvioReader(file, false, false);
+                    } catch (EvioException e) {
+                        throw new IOException("Error reading EVIO file.", e);
+                    }
+                } else if (dataSourceType.equals(DataSourceType.LCIO_FILE)) {
+                    new LCIOReader(file);
+                }
+            } catch (IOException e) {
+                throw e;
+            } 
+        } else {
+            // This shouldn't really ever happen!
+            throw new IOException("No file source was selected.");
+        }
+    }
+    
+    /**
+     * This is a thread to validate the current input file.  This must 
+     * be done on a seperate thread, because EVIO files may take a long time
+     * to be completely read in using the EvioReader.  Also, since
+     * the request for file validation comes on the EDT thread, the task 
+     * must be put onto a seperate thread so that actionPerformed() may exit 
+     * and not block the EDT from updating the GUI.        
+     */
+    class FileValidationThread extends Thread {                
+        boolean isFileValid;
+        public void run() {
+            settingsDialog.setEnabled(false);
+            JDialog dialog = DialogUtil.showStatusDialog(
+                    MonitoringApplication.this,
+                    "Validating data file", 
+                    configurationModel.getDataSourcePath());
+            try {                                
+                validateDataFile();
+                DialogUtil.showInfoDialog(
+                        MonitoringApplication.this, 
+                        "File is valid", 
+                        configurationModel.getDataSourcePath());
+            } catch (IOException error) {
+                DialogUtil.showErrorDialog(
+                        MonitoringApplication.this, 
+                        error, 
+                        "Error validating file");
+            } finally {
+                dialog.dispatchEvent(new WindowEvent(dialog, WindowEvent.WINDOW_CLOSING));
+                settingsDialog.setEnabled(true);
+                fileValidationThread = null;
+            }            
+        }    
+    }
+            
+    /**
      * Create an ET server connection from a <code>ConfigurationModel</code>.
      * @param config The ConfigurationModel with the connection parameters.
      * @return The EtConnection object.
@@ -1681,5 +1740,5 @@
                 config.getWaitMode(), 
                 config.getWaitTime(), 
                 config.getChunkSize());
-    }
+    }                      
 }
\ No newline at end of file
SVNspam 0.1