Author: [log in to unmask] Date: Mon Nov 10 16:42:56 2014 New Revision: 1483 Log: Change detector field from text to combo box listing all available detectors. HPSJAVA-310 Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/Commands.java java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/JobSettingsPanel.java Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/Commands.java ============================================================================= --- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/Commands.java (original) +++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/Commands.java Mon Nov 10 16:42:56 2014 @@ -15,6 +15,7 @@ static final String CONNECT = "connect"; static final String CLEAR_LOG_TABLE = "clearLogTable"; static final String DATA_SOURCE_TYPE_CHANGED = "dataSourceTypeChanged"; + static final String DETECTOR_NAME_CHANGED = "detectorNameChanged"; static final String DISCONNECT = "disconnect"; static final String DISCONNECT_ON_ERROR_CHANGED = "disconnectOnErrorChanged"; static final String DISCONNECT_ON_END_RUN_CHANGED = "disconnectOnEndRunChanged"; Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/JobSettingsPanel.java ============================================================================= --- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/JobSettingsPanel.java (original) +++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/gui/JobSettingsPanel.java Mon Nov 10 16:42:56 2014 @@ -3,6 +3,7 @@ import static org.hps.monitoring.gui.Commands.AIDA_AUTO_SAVE_CHANGED; import static org.hps.monitoring.gui.Commands.DISCONNECT_ON_END_RUN_CHANGED; import static org.hps.monitoring.gui.Commands.DISCONNECT_ON_ERROR_CHANGED; +import static org.hps.monitoring.gui.Commands.DETECTOR_NAME_CHANGED; import static org.hps.monitoring.gui.Commands.EVENT_BUILDER_CHANGED; import static org.hps.monitoring.gui.Commands.LOG_LEVEL_CHANGED; import static org.hps.monitoring.gui.Commands.LOG_TO_FILE_CHANGED; @@ -29,12 +30,15 @@ import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.net.JarURLConnection; import java.net.URL; import java.util.ArrayList; +import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.List; +import java.util.Properties; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -59,17 +63,13 @@ * 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. */ -// TODO: Add validity checks for event builder, lcsim steering files, etc. -// and revert to old values if new values are invalid. -// http://docs.oracle.com/javase/7/docs/api/javax/swing/JFormattedTextField.html class JobSettingsPanel extends AbstractFieldsPanel { private JTextField aidaSaveFileNameField; private JCheckBox aidaAutoSaveCheckbox; - private JTextField detectorNameField; private JCheckBox disconnectOnErrorCheckBox; private JCheckBox disconnectOnEndRunCheckBox; - //private JTextField eventBuilderField; + private JComboBox<String> detectorNameComboBox; private JComboBox<String> eventBuilderComboBox; private JTextField logFileNameField; private JComboBox<?> logLevelComboBox; @@ -81,14 +81,21 @@ // The package where steering resources must be located. static final String STEERING_PACKAGE = "org/hps/steering/monitoring/"; - // FIXME: This should be in the default global config file rather than hard-coded here. - static final String DEFAULT_EVENT_BUILDER_CLASS_NAME = "org.hps.evio.LCSimEngRunEventBuilder"; - - // This will connect the GUI component to the underlying global configuration model. + // This connects the GUI to the global configuration model. ConfigurationModel configurationModel; // The available LogLevel settings as an array of strings. - static final String[] LOG_LEVELS = new String[] { Level.ALL.toString(), Level.FINEST.toString(), Level.FINER.toString(), Level.FINE.toString(), Level.CONFIG.toString(), Level.INFO.toString(), Level.WARNING.toString(), Level.SEVERE.toString(), Level.OFF.toString() }; + 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. @@ -121,15 +128,16 @@ steeringFileButton.setActionCommand(Commands.CHOOSE_STEERING_FILE); steeringFileButton.addActionListener(this); - steeringResourcesComboBox = addComboBoxMultiline("Steering File Resource", getAvailableSteeringFileResources(STEERING_PACKAGE)); + steeringResourcesComboBox = addComboBoxMultiline("Steering File Resource", findSteeringResources(STEERING_PACKAGE)); steeringResourcesComboBox.setActionCommand(STEERING_RESOURCE_CHANGED); steeringResourcesComboBox.addActionListener(this); - detectorNameField = addField("Detector Name", 20); - detectorNameField.addPropertyChangeListener("value", this); + detectorNameComboBox = addComboBox("Detector Name", this.findDetectorNames()); + detectorNameComboBox.setActionCommand(DETECTOR_NAME_CHANGED); + detectorNameComboBox.addActionListener(this); eventBuilderComboBox = addComboBox("LCSim Event Builder", this.findEventBuilderClassNames()); - eventBuilderComboBox.setActionCommand(Commands.EVENT_BUILDER_CHANGED); + eventBuilderComboBox.setActionCommand(EVENT_BUILDER_CHANGED); eventBuilderComboBox.addActionListener(this); logToFileCheckbox = addCheckBox("Log to File", false, false); @@ -180,7 +188,6 @@ * Attaches the ActionListener from the main app to specific GUI components in this class. */ void addActionListener(ActionListener listener) { - eventBuilderComboBox.addActionListener(listener); logFileNameField.addActionListener(listener); logToFileCheckbox.addActionListener(listener); steeringResourcesComboBox.addActionListener(listener); @@ -236,41 +243,8 @@ Document document = builder.build(file); Element rootNode = document.getRootElement(); if (!rootNode.getName().equals("lcsim")) { - throw new IOException("Not an LCSim XML file."); - } - } - - /** - * Get the files with extension "lcsim" from all loaded jar files. - * @return A list of embedded steering file resources. - */ - static String[] getAvailableSteeringFileResources(String packageName) { - List<String> resources = new ArrayList<String>(); - URL url = JobSettingsPanel.class.getResource("MonitoringApplication.class"); - String scheme = url.getProtocol(); - if (!"jar".equals(scheme)) { - throw new IllegalArgumentException("Unsupported scheme. Only jar is allowed."); - } - try { - JarURLConnection con = (JarURLConnection) url.openConnection(); - JarFile archive = con.getJarFile(); - Enumeration<JarEntry> entries = archive.entries(); - while (entries.hasMoreElements()) { - JarEntry entry = entries.nextElement(); - if (entry.getName().endsWith(".lcsim") && entry.getName().contains(packageName)) { - resources.add(entry.getName()); - } - } - archive.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - java.util.Collections.sort(resources); - String[] arr = new String[resources.size()]; - for (int i = 0; i < arr.length; i++) { - arr[i] = resources.get(i); - } - return arr; + throw new IOException("Not an LCSim XML file: " + file.getPath()); + } } @Override @@ -293,6 +267,8 @@ configurationModel.setAidaAutoSave(aidaAutoSaveCheckbox.isSelected()); } else if (EVENT_BUILDER_CHANGED.equals(e.getActionCommand())) { configurationModel.setEventBuilderClassName((String) eventBuilderComboBox.getSelectedItem()); + } else if (DETECTOR_NAME_CHANGED.equals(e.getActionCommand())) { + configurationModel.setDetectorName((String) detectorNameComboBox.getSelectedItem()); } } @@ -309,9 +285,7 @@ Object source = evt.getSource(); - if (source == detectorNameField) { - configurationModel.setDetectorName(detectorNameField.getText()); - } else if (source == steeringFileField) { + if (source == steeringFileField) { configurationModel.setSteeringFile(steeringFileField.getText()); } else if (source == logFileNameField) { configurationModel.setLogFileName(logFileNameField.getText()); @@ -326,7 +300,7 @@ * Update the GUI from changes in the underlying configuration. The changes from the * configuration are distinguishable by their property name. */ - public class JobSettingsChangeListener implements PropertyChangeListener { + private class JobSettingsChangeListener implements PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent evt) { @@ -337,7 +311,7 @@ Object value = evt.getNewValue(); if (evt.getPropertyName().equals(DETECTOR_NAME_PROPERTY)) { - detectorNameField.setText((String) value); + detectorNameComboBox.setSelectedItem((String) value); } else if (evt.getPropertyName().equals(AIDA_AUTO_SAVE_PROPERTY)) { aidaAutoSaveCheckbox.setSelected((Boolean) value); } else if (evt.getPropertyName().equals(AIDA_FILE_NAME_PROPERTY)) { @@ -364,7 +338,46 @@ } } - String[] findEventBuilderClassNames() { + /** + * Get the files with extension 'lcsim' from all loaded jar files. + * @param packageName The package name for filtering the resources. + * @return A list of embedded steering file resources. + */ + private static String[] findSteeringResources(String packageName) { + List<String> resources = new ArrayList<String>(); + URL url = JobSettingsPanel.class.getResource("MonitoringApplication.class"); + String scheme = url.getProtocol(); + if (!"jar".equals(scheme)) { + throw new IllegalArgumentException("Unsupported scheme. Only jar is allowed."); + } + try { + JarURLConnection con = (JarURLConnection) url.openConnection(); + JarFile archive = con.getJarFile(); + Enumeration<JarEntry> entries = archive.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + if (entry.getName().endsWith(".lcsim") && entry.getName().contains(packageName)) { + resources.add(entry.getName()); + } + } + archive.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + java.util.Collections.sort(resources); + String[] arr = new String[resources.size()]; + for (int i = 0; i < arr.length; i++) { + arr[i] = resources.get(i); + } + return arr; + } + + /** + * Find all classes that implement {@link org.hps.evio.LCSimEventBuilder} and return + * a list of their canonical names. + * @return The list of classes implementing LCSimEventBuilder. + */ + private static String[] findEventBuilderClassNames() { Reflections reflections = new Reflections("org.hps"); Set<Class<? extends LCSimEventBuilder>> subTypes = reflections.getSubTypesOf(LCSimEventBuilder.class); Set<String> classNames = new HashSet<String>(); @@ -373,4 +386,45 @@ } return classNames.toArray(new String[classNames.size()]); } + + /** + * Find a list of available detector names. + * Only those detectors that have names starting with "HPS" in their + * detector.properties files will be returned. + * @return The list of available detector names. + */ + private static String[] findDetectorNames() { + ClassLoader classLoader = JobSettingsPanel.class.getClassLoader(); + List<String> detectorNames = new ArrayList<String>(); + URL url = JobSettingsPanel.class.getResource("MonitoringApplication.class"); + String protocol = url.getProtocol(); + if (!"jar".equals(protocol)) { + throw new RuntimeException("Unsupported URL protocol: " + url.getProtocol()); + } + try { + JarURLConnection con = (JarURLConnection) url.openConnection(); + JarFile archive = con.getJarFile(); + Enumeration<JarEntry> entries = archive.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + if (entry.getName().endsWith("detector.properties")) { + InputStream inputStream = classLoader.getResourceAsStream(entry.getName()); + if (inputStream == null) { + throw new RuntimeException("Failed to load jar entry: " + entry.getName()); + } + Properties properties = new Properties(); + properties.load(inputStream); + String detectorName = properties.getProperty("name"); + if (detectorName.startsWith("HPS")) { + detectorNames.add(detectorName); + } + } + } + archive.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + Collections.sort(detectorNames); + return detectorNames.toArray(new String[detectorNames.size()]); + } }