Author: [log in to unmask]
Date: Tue Apr 21 14:48:39 2015
New Revision: 2772
Log:
Merge trunk changes into monitoring-app-dev branch..
Modified:
java/branches/monitoring-app-dev/ (props changed)
java/branches/monitoring-app-dev/pom.xml
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/AddActionListener.java
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/ConditionsCollectionTableModel.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConditionsPanel.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/DataSourceComboBox.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/DatePanel.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventDashboard.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/FieldPanel.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/MonitoringApplicationFrame.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/SettingsDialog.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/SystemStatusEventsTable.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusPanel.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusTable.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ToolbarPanel.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/AbstractModel.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/Configuration.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/model/ConnectionStatus.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/HasConfigurationModel.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/RunModel.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/SteeringType.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/SystemStatusTableModel.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/package-info.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/AIDAServer.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/DialogUtil.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/EtSystemUtil.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/EvioFileFilter.java
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/SyncEventProcessor.java
java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/TableExporter.java
Modified: java/branches/monitoring-app-dev/pom.xml
=============================================================================
--- java/branches/monitoring-app-dev/pom.xml (original)
+++ java/branches/monitoring-app-dev/pom.xml Tue Apr 21 14:48:39 2015
@@ -7,7 +7,7 @@
<groupId>org.hps</groupId>
<artifactId>hps-parent</artifactId>
<relativePath>../parent/pom.xml</relativePath>
- <version>3.2-SNAPSHOT</version>
+ <version>3.3.1-SNAPSHOT</version>
</parent>
<scm>
<url>http://java.freehep.org/svn/repos/hps/list/java/trunk/monitoring-app/</url>
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/AbstractFieldsPanel.java Tue Apr 21 14:48:39 2015
@@ -16,305 +16,362 @@
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
+import javax.swing.SwingConstants;
import org.hps.monitoring.application.model.ConfigurationModel;
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.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-// 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) {
+ return !"ancestor".equals(evt.getPropertyName());
+ }
+
+ /**
+ * 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 <code>true</code> if component is selected
+ * @param enabled <code>true</code> if component enabled
+ * @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 Object[] 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(SwingConstants.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 <code>JComboBox</code> 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(SwingConstants.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);
+ *
+ * @param name the name of the field
+ * @param size the size of the field
+ * @return the <code>JTextField</code> component
+ */
+ 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);
+ *
+ * @param name the name of the field
+ * @param value the default value of the field
+ * @param size the size of the field
+ * @return the <code>JTextField</code> component
+ */
+ 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 tooltip The tooltip text.
- * @param size The size of the field.
- * @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);
+ *
+ * @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 <code>JTextField</code> 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(SwingConstants.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
+ * @param size the size of the field
+ * @param editable the editable setting
+ * @return the <code>JTextField</code> component
+ */
+ 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 {@link org.hps.monitoring.application.model.ConfigurationModel} for this component.
+ *
+ * @return the {@link org.hps.monitoring.application.model.ConfigurationModel} for this 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/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/AddActionListener.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/AddActionListener.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/AddActionListener.java Tue Apr 21 14:48:39 2015
@@ -2,7 +2,18 @@
import java.awt.event.ActionListener;
+/**
+ * Mix-in interface for components which can be assigned an <code>ActionListener</code>.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ */
interface AddActionListener {
+ /**
+ * Set an <code>ActionListener</code> for this component, which should assign it to appropriate child components
+ * that emit <code>ActionEvent</code> objects.
+ *
+ * @param listener the <code>ActionListener</code> to assign to this component
+ */
void addActionListener(ActionListener listener);
}
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 Apr 21 14:48:39 2015
@@ -1,85 +1,256 @@
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 <code>ActionEvent</code> commands in the MonitoringApplication.
+ *
+ * @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";
+
+ /**
+ * Action when plot is selected from a tab.
+ */
+ static final String PLOT_SELECTED = "PlotSelected";
+
+ /**
+ * 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";
+
+ /**
+ * Okay button in settings panel.
+ */
+ static final String SETTINGS_OKAY_COMMAND = "settingsOkay";
+
+ /**
+ * 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/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java Tue Apr 21 14:48:39 2015
@@ -9,85 +9,144 @@
/**
* This is a table model for a collection of conditions objects.
- * @author Jeremy McCormick <[log in to unmask]>
*
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class ConditionsCollectionTableModel extends DefaultTableModel {
+@SuppressWarnings("serial")
+final 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];
- if (columnClass.equals(int.class)) {
+ public Class<?> getColumnClass(final int columnIndex) {
+ final Class<?> columnClass = this.columnTypes[columnIndex];
+ if (int.class.equals(columnClass)) {
return Integer.class;
- } else if (columnClass.equals(float.class)) {
+ } else if (float.class.equals(columnClass)) {
return Float.class;
- } else if (columnClass.equals(double.class)) {
+ } else if (double.class.equals(columnClass)) {
return Double.class;
} else {
return columnClass;
}
}
+ /**
+ * 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.
+ *
+ * @param columnIndex the column index
+ * @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 table cell value.
+ *
+ * @param rowIndex the row index
+ * @param columnIndex the column index
+ * @return the value of the cell
+ */
+ @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 the 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/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConditionsPanel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConditionsPanel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConditionsPanel.java Tue Apr 21 14:48:39 2015
@@ -1,6 +1,3 @@
-/**
- *
- */
package org.hps.monitoring.application;
import java.awt.BorderLayout;
@@ -29,65 +26,96 @@
import org.lcsim.conditions.ConditionsListener;
/**
- * @author Jeremy McCormick <[log in to unmask]>
+ * The component for showing conditions table records in the monitoring application tabs.
*
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-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);
- }
-
+@SuppressWarnings("serial")
+final class ConditionsPanel extends JPanel {
+
+ /**
+ * The listener for updating the panel when conditions are changed.
+ */
class ConditionsPanelListener implements ConditionsListener {
+ /**
+ * Handle conditions change event.
+ *
+ * @param event the conditions change event
+ */
@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));
}
}
}
-}
+
+ /**
+ * The GUI component listing the conditions sets for the run.
+ */
+ private final JList<String> conditionsList = new JList<String>();
+
+ /**
+ * The table which shows the currently selected conditions set from the list.
+ */
+ private final JTable conditionsTable = new JTable();
+
+ /**
+ * Map of conditions set names to table models.
+ */
+ private Map<String, ConditionsCollectionTableModel> tableModels;
+
+ /**
+ * Class constructor which will initialize sub-components.
+ */
+ ConditionsPanel() {
+ super(new BorderLayout());
+
+ this.conditionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ this.conditionsList.addListSelectionListener(new ListSelectionListener() {
+
+ /**
+ * The selection listener method implementation which will activate a new table in the conditions panel.
+ *
+ * @param e the list selection event
+ */
+ @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<TableModel>(model));
+ ConditionsPanel.this.conditionsTable.revalidate();
+ }
+ });
+
+ // Initialize with default table model.
+ this.conditionsTable.setModel(new DefaultTableModel());
+
+ final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, this.conditionsList, new JScrollPane(
+ this.conditionsTable));
+
+ this.add(splitPane);
+ }
+}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConnectionSettingsPanel.java Tue Apr 21 14:48:39 2015
@@ -15,189 +15,252 @@
/**
* Connection settings panel.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-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.
+@SuppressWarnings("serial")
+final class ConnectionSettingsPanel extends AbstractFieldsPanel {
+
+ /**
+ * Update the GUI from changes in the {@link org.hps.monitoring.application.model.ConfigurationModel}.
*/
public class ConnectionSettingsChangeListener implements PropertyChangeListener {
+
+ /**
+ * Handle a property change from the model.
+ *
+ * @param the <code>PropertyChangeEvent</code> to handle
+ */
@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);
}
}
}
/**
+ * The available wait mode settings (sleep, timed and asynchronous).
+ */
+ private static final String[] WAIT_MODES = {Mode.SLEEP.name(), Mode.TIMED.name(), Mode.ASYNC.name()};
+
+ /**
+ * Check box for blocking setting.
+ */
+ private final JCheckBox blockingCheckBox;
+
+ /**
+ * Field for chunk size.
+ */
+ private final JTextField chunkSizeField;
+
+ /**
+ * Field for ET name (file).
+ */
+ private final JTextField etNameField;
+
+ /**
+ * Field for host name.
+ */
+ private final JTextField hostField;
+
+ /**
+ * Field for TCP/IP port.
+ */
+ private final JTextField portField;
+
+ /**
+ * Field for prescale setting.
+ */
+ private final JTextField prescaleField;
+
+ /**
+ * Field for queue size.
+ */
+ private final JTextField queueSizeField;
+
+ /**
+ * Field for station name.
+ */
+ private final JTextField stationNameField;
+
+ /**
+ * Field for station position.
+ */
+ private final JTextField stationPositionField;
+
+ /**
+ * Check box for verbose flag.
+ */
+ private final JCheckBox verboseCheckBox;
+
+ /**
+ * Check box for wait mode selection.
+ */
+ private final JComboBox<?> waitModeComboBox;
+
+ /**
+ * Field for wait time.
+ */
+ 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", WAIT_MODES);
+ 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.
+ *
+ * @param e the <code>ActionEvent</code> to handle
+ */
+ @Override
+ public void actionPerformed(final ActionEvent e) {
+ if (Commands.WAIT_MODE_CHANGED.equals(e.getActionCommand())) {
+ this.getConfigurationModel().setWaitMode(this.waitModeComboBox.getSelectedItem().toString());
+ } 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 <code>true</code> to enable the components in the panel
+ */
+ 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);
+ }
+ }
+
+ /**
+ * Set configuration model (using <code>super</code> method) and add a property change listener for connection
+ * settings.
*/
@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/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java Tue Apr 21 14:48:39 2015
@@ -11,59 +11,82 @@
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
+import javax.swing.SwingConstants;
import org.hps.monitoring.application.model.ConnectionStatus;
import org.hps.monitoring.application.model.ConnectionStatusModel;
/**
- * This is the panel for showing the current connection status (connected, disconnected, etc.).
+ * This is the panel for showing the current connection status (connected, disconnected, etc.) in the tool bar.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class ConnectionStatusPanel extends JPanel implements PropertyChangeListener {
+@SuppressWarnings("serial")
+final class ConnectionStatusPanel extends JPanel implements PropertyChangeListener {
- JTextField statusField;
- JTextField dateField;
+ /**
+ * Date formatting.
+ */
+ private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MMMM-dd-yyyy HH:mm:ss");
- // Format for date field.
- private final SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM-dd-yyyy HH:mm:ss");
-
- ConnectionStatusModel model;
+ /**
+ * Field for date when status changed (read only).
+ */
+ private final JTextField dateField;
+
+ /**
+ * The model for getting connection status changes.
+ */
+ private final ConnectionStatusModel model;
+
+ /**
+ * The field showing the current connection status (read only).
+ */
+ private final JTextField statusField;
/**
* Class constructor.
+ *
+ * @param model the model which notifies this component of connection status changes
*/
- ConnectionStatusPanel(ConnectionStatusModel model) {
-
+ ConnectionStatusPanel(final ConnectionStatusModel model) {
+
this.model = model;
this.model.addPropertyChangeListener(this);
-
+
setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0));
-
- statusField = new JTextField("", 10);
- statusField.setHorizontalAlignment(JTextField.LEFT);
- statusField.setEditable(false);
- statusField.setBackground(Color.WHITE);
- statusField.setFont(new Font("Arial", Font.BOLD, 16));
- statusField.setForeground(model.getConnectionStatus().getColor());
- statusField.setText(model.getConnectionStatus().name());
- add(statusField);
-
+
+ this.statusField = new JTextField("", 10);
+ this.statusField.setHorizontalAlignment(SwingConstants.LEFT);
+ this.statusField.setEditable(false);
+ this.statusField.setBackground(Color.WHITE);
+ this.statusField.setFont(new Font("Arial", Font.BOLD, 16));
+ this.statusField.setForeground(model.getConnectionStatus().getColor());
+ this.statusField.setText(model.getConnectionStatus().name());
+ add(this.statusField);
+
add(new JLabel("@"));
-
- dateField = new JTextField("", 21);
- dateField.setEditable(false);
- dateField.setBackground(Color.WHITE);
- dateField.setHorizontalAlignment(JTextField.LEFT);
- dateField.setFont(new Font("Arial", Font.PLAIN, 14));
- add(dateField);
+
+ this.dateField = new JTextField("", 21);
+ this.dateField.setEditable(false);
+ this.dateField.setBackground(Color.WHITE);
+ this.dateField.setHorizontalAlignment(SwingConstants.LEFT);
+ this.dateField.setFont(new Font("Arial", Font.PLAIN, 14));
+ add(this.dateField);
}
+ /**
+ * Handle a property change event coming from the model.
+ *
+ * @param evt the property change event
+ */
@Override
- public void propertyChange(PropertyChangeEvent evt) {
+ public void propertyChange(final PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(ConnectionStatusModel.CONNECTION_STATUS_PROPERTY)) {
final ConnectionStatus status = (ConnectionStatus) evt.getNewValue();
- statusField.setForeground(status.getColor());
- statusField.setText(status.name());
- dateField.setText(dateFormat.format(new Date()));
- }
+ this.statusField.setForeground(status.getColor());
+ this.statusField.setText(status.name());
+ this.dateField.setText(ConnectionStatusPanel.DATE_FORMAT.format(new Date()));
+ }
}
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/DataSourceComboBox.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/DataSourceComboBox.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/DataSourceComboBox.java Tue Apr 21 14:48:39 2015
@@ -21,28 +21,48 @@
import org.hps.record.enums.DataSourceType;
/**
- * This is a combo box that shows the current data source such as an LCIO file, EVIO file or ET ring.
- * It can also be used to select a new data source for the new session.
+ * This is a combo box that shows the current data source such as an LCIO file, EVIO file or ET ring. It can also be
+ * used to select a data source for the next monitoring session.
* <p>
- * The way this works is kind of odd because it is not directly connected to an event loop, so it must
- * catch changes to the configuration and update its items accordingly.
+ * This component is not directly connected to an event loop, so it must catch changes to the configuration via property
+ * change events and then update its state accordingly.
* <p>
- * A single ET item is kept in the list and updated as changes are made to the global configuration.
- *
- * @author Jeremy McCormick <[log in to unmask]>
+ * Only a single "global" ET item is kept in the list, and it is updated as changes are made to the configuration model.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class DataSourceComboBox extends JComboBox<DataSourceItem> implements PropertyChangeListener, ActionListener{
-
- ConnectionStatusModel connectionModel;
- ConfigurationModel configurationModel;
-
+@SuppressWarnings("serial")
+final class DataSourceComboBox extends JComboBox<DataSourceItem> implements PropertyChangeListener, ActionListener {
+
+ /**
+ * This class represents a data source item in the combo box, which has a name for display, a full path to the file,
+ * and an implicit type (EVIO, LCIO or ET).
+ */
static class DataSourceItem {
+ /**
+ * The name of the data source which will show in the drop down box.
+ */
private String name;
- private String path;
- private DataSourceType type;
-
- DataSourceItem(String path, String name, DataSourceType type) {
+
+ /**
+ * The full path used for the data source (for ET this is not used directly).
+ */
+ private final String path;
+
+ /**
+ * The implicit data type (EVIO, LCIO and ET).
+ */
+ private final DataSourceType type;
+
+ /**
+ * Create a data source item.
+ *
+ * @param path the data source path
+ * @param name the data source name
+ * @param type the data source type
+ */
+ DataSourceItem(final String path, final String name, final DataSourceType type) {
if (path == null) {
throw new IllegalArgumentException("path is null");
}
@@ -57,48 +77,81 @@
this.path = path;
}
- public String toString() {
- return name;
- }
-
- public String getPath() {
- return path;
- }
-
- public String getName() {
- return name;
- }
-
- public boolean equals(Object object) {
+ /**
+ * Implementation of equals operation.
+ *
+ * @param object the other object
+ */
+ @Override
+ public boolean equals(final Object object) {
if (!(object instanceof DataSourceItem)) {
return false;
}
- DataSourceItem otherItem = (DataSourceItem) object;
- if (this.name == otherItem.name && this.path == otherItem.path && this.type == otherItem.type) {
- return true;
- } else {
- return false;
- }
- }
- }
-
- @SuppressWarnings({ "rawtypes", "serial", "unchecked" })
- DataSourceComboBox(ConfigurationModel configurationModel, ConnectionStatusModel connectionModel) {
+ final DataSourceItem otherItem = (DataSourceItem) object;
+ return this.name == otherItem.name && this.path == otherItem.path && this.type == otherItem.type;
+ }
+
+ /**
+ * Get the name of the source that is used as text in the drop down menu.
+ *
+ * @return the name of the data source
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Get the full path to the data source which is used as tool tip text (not used directly for ET sources).
+ *
+ * @return the full path to the data source
+ */
+ public String getPath() {
+ return this.path;
+ }
+
+ /**
+ * Convert this object to a string.
+ *
+ * @return this object converted to a string
+ */
+ @Override
+ public String toString() {
+ return this.name;
+ }
+ }
+
+ /**
+ * The preferred width of this component in pixels.
+ */
+ private static final int PREFERRED_WIDTH = 510;
+
+ /**
+ * The backing configuration model.
+ */
+ private ConfigurationModel configurationModel;
+
+ /**
+ * Create a new data source combo box.
+ *
+ * @param configurationModel the underlying configuration data model
+ * @param connectionModel the underlying connection status data model
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ DataSourceComboBox(final ConfigurationModel configurationModel, final ConnectionStatusModel connectionModel) {
addActionListener(this);
setActionCommand(Commands.DATA_SOURCE_CHANGED);
- setPreferredSize(new Dimension(510, this.getPreferredSize().height));
+ setPreferredSize(new Dimension(PREFERRED_WIDTH, this.getPreferredSize().height));
setEditable(false);
this.configurationModel = configurationModel;
- connectionModel.addPropertyChangeListener(this);
+ connectionModel.addPropertyChangeListener(this);
configurationModel.addPropertyChangeListener(this);
-
- ListCellRenderer renderer = new DefaultListCellRenderer() {
+
+ final ListCellRenderer renderer = new DefaultListCellRenderer() {
@Override
- public Component getListCellRendererComponent(JList<?> list,
- Object value, int index, boolean isSelected,
- boolean cellHasFocus) {
+ public Component getListCellRendererComponent(final JList<?> list, final Object value, final int index,
+ final boolean isSelected, final boolean cellHasFocus) {
if (value instanceof DataSourceItem) {
- setToolTipText(((DataSourceItem)value).getPath());
+ setToolTipText(((DataSourceItem) value).getPath());
} else {
setToolTipText(null);
}
@@ -108,48 +161,142 @@
};
this.setRenderer(renderer);
}
-
- boolean containsItem(DataSourceItem item) {
+
+ /**
+ * Handle action events.
+ *
+ * @param evt the <code>ActionEvent</code> to handle
+ */
+ @Override
+ public void actionPerformed(final ActionEvent evt) {
+ if (evt.getActionCommand().equals(Commands.DATA_SOURCE_CHANGED)) {
+ try {
+ // Update the model with data source settings.
+ this.configurationModel.removePropertyChangeListener(this);
+ final DataSourceItem item = (DataSourceItem) getSelectedItem();
+ if (item != null) {
+ this.configurationModel.setDataSourceType(item.type);
+ if (item.type != DataSourceType.ET_SERVER) {
+ this.configurationModel.setDataSourcePath(item.getPath());
+ }
+ }
+ } finally {
+ this.configurationModel.addPropertyChangeListener(this);
+ }
+ }
+ }
+
+ /**
+ * Add a data source item with a specific type and path.
+ *
+ * @param path the data source path
+ * @param type the data source type
+ * @return the new data source item
+ */
+ DataSourceItem addDataSourceItem(final String path, final DataSourceType type) {
+ final DataSourceItem newItem = new DataSourceItem(path, new File(path).getName(), type);
+ addItem(newItem);
+ return newItem;
+ }
+
+ /**
+ * Add a data source item. Attempting to add an item that already exists will be ignored.
+ */
+ @Override
+ public void addItem(final DataSourceItem item) {
+ if (containsItem(item)) {
+ return;
+ }
+ if (findItem(item.getPath()) == null) {
+ super.addItem(item);
+ }
+ }
+
+ /**
+ * Return true if the (exact) given item exists in the combo box model.
+ *
+ * @param item the data source item
+ * @return <code>true</code> if data source item exists in the model
+ */
+ boolean containsItem(final DataSourceItem item) {
return ((DefaultComboBoxModel<DataSourceItem>) getModel()).getIndexOf(item) != -1;
}
+ /**
+ * Find the single data source item for the ET configuration in the items.
+ *
+ * @return the data source item for the ET configuration or <code>null</code> if does not exist
+ */
+ DataSourceItem findEtItem() {
+ for (int i = 0; i < this.getItemCount(); i++) {
+ final DataSourceItem item = this.getItemAt(i);
+ if (item.type == DataSourceType.ET_SERVER) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Find an item by its path.
+ *
+ * @param path the path of the item
+ * @return the item or <code>null</code> if does not exist
+ */
+ DataSourceItem findItem(final String path) {
+ for (int i = 0; i < this.getItemCount(); i++) {
+ final DataSourceItem item = this.getItemAt(i);
+ if (item.getPath().equals(path)) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Handle property change events which is used to update the GUI from changes to the global configuration model.
+ *
+ * @param evt the property change event
+ */
@Override
- public void propertyChange(PropertyChangeEvent evt) {
- configurationModel.removePropertyChangeListener(this);
+ public void propertyChange(final PropertyChangeEvent evt) {
+ this.configurationModel.removePropertyChangeListener(this);
try {
if (evt.getPropertyName().equals(ConnectionStatusModel.CONNECTION_STATUS_PROPERTY)) {
- ConnectionStatus status = (ConnectionStatus) evt.getNewValue();
+ final ConnectionStatus status = (ConnectionStatus) evt.getNewValue();
if (status.equals(ConnectionStatus.DISCONNECTED)) {
setEnabled(true);
} else {
setEnabled(false);
}
} else if (evt.getPropertyName().equals(ConfigurationModel.DATA_SOURCE_PATH_PROPERTY)) {
- if (configurationModel.hasValidProperty(ConfigurationModel.DATA_SOURCE_TYPE_PROPERTY)) {
- String path = configurationModel.getDataSourcePath();
- DataSourceType type = DataSourceType.getDataSourceType(path);
+ if (this.configurationModel.hasValidProperty(ConfigurationModel.DATA_SOURCE_TYPE_PROPERTY)) {
+ final String path = this.configurationModel.getDataSourcePath();
+ final DataSourceType type = DataSourceType.getDataSourceType(path);
if (type.isFile()) {
DataSourceItem item = findItem(path);
if (item == null) {
item = addDataSourceItem(path, type);
}
- if (configurationModel.getDataSourceType().isFile()) {
+ if (this.configurationModel.getDataSourceType().isFile()) {
setSelectedItem(item);
}
}
}
} else if (evt.getPropertyName().equals(ConfigurationModel.DATA_SOURCE_TYPE_PROPERTY)) {
- if (configurationModel.getDataSourceType() == DataSourceType.ET_SERVER) {
+ if (this.configurationModel.getDataSourceType() == DataSourceType.ET_SERVER) {
DataSourceItem item = findEtItem();
if (item == null) {
- item = new DataSourceItem(configurationModel.getEtPath(), configurationModel.getEtPath(), DataSourceType.ET_SERVER);
+ item = new DataSourceItem(this.configurationModel.getEtPath(),
+ this.configurationModel.getEtPath(), DataSourceType.ET_SERVER);
}
setSelectedItem(item);
} else {
- if (configurationModel.hasValidProperty(ConfigurationModel.DATA_SOURCE_PATH_PROPERTY)) {
- DataSourceItem item = findItem(configurationModel.getDataSourcePath());
+ if (this.configurationModel.hasValidProperty(ConfigurationModel.DATA_SOURCE_PATH_PROPERTY)) {
+ DataSourceItem item = findItem(this.configurationModel.getDataSourcePath());
if (item == null) {
- item = addDataSourceItem(configurationModel.getDataSourcePath(), configurationModel.getDataSourceType());
+ item = addDataSourceItem(this.configurationModel.getDataSourcePath(),
+ this.configurationModel.getDataSourceType());
}
setSelectedItem(item);
}
@@ -162,76 +309,33 @@
updateEtItem();
}
} finally {
- configurationModel.addPropertyChangeListener(this);
- }
- }
-
+ this.configurationModel.addPropertyChangeListener(this);
+ }
+ }
+
+ /**
+ * Set the currently selected item.
+ *
+ * @param object the currently selected item (should be an instance of this class)
+ */
@Override
- public void setSelectedItem(Object object) {
+ public void setSelectedItem(final Object object) {
super.setSelectedItem(object);
- this.setToolTipText(((DataSourceItem)object).getPath());
- }
-
- public void actionPerformed(ActionEvent evt) {
- if (evt.getActionCommand().equals(Commands.DATA_SOURCE_CHANGED)) {
- try {
- // Update the model with data source settings.
- configurationModel.removePropertyChangeListener(this);
- DataSourceItem item = (DataSourceItem) getSelectedItem();
- if (item != null) {
- configurationModel.setDataSourceType(item.type);
- if (item.type != DataSourceType.ET_SERVER) {
- configurationModel.setDataSourcePath(item.getPath());
- }
- }
- } finally {
- configurationModel.addPropertyChangeListener(this);
- }
- }
- }
-
- public void addItem(DataSourceItem item) {
- if (containsItem(item)) {
- return;
- }
- if (findItem(item.getPath()) == null) {
- super.addItem(item);
- }
- }
-
- DataSourceItem findItem(String path) {
- for (int i = 0; i < this.getItemCount(); i++) {
- DataSourceItem item = this.getItemAt(i);
- if (item.getPath().equals(path)) {
- return item;
- }
- }
- return null;
- }
-
- DataSourceItem findEtItem() {
- for (int i = 0; i < this.getItemCount(); i++) {
- DataSourceItem item = this.getItemAt(i);
- if (item.type == DataSourceType.ET_SERVER) {
- return item;
- }
- }
- return null;
- }
-
- DataSourceItem addDataSourceItem(String path, DataSourceType type) {
- DataSourceItem newItem = new DataSourceItem(path, new File(path).getName(), type);
- addItem(newItem);
- return newItem;
- }
-
+ this.setToolTipText(((DataSourceItem) object).getPath());
+ }
+
+ /**
+ * Update the path value of the current ET item from the current global configuration. There is only one ET item
+ * present in the list at one time so property changes to ET configuration will trigger this method.
+ */
void updateEtItem() {
DataSourceItem item = findEtItem();
if (item == null) {
- item = new DataSourceItem(configurationModel.getEtPath(), configurationModel.getEtPath(), DataSourceType.ET_SERVER);
+ item = new DataSourceItem(this.configurationModel.getEtPath(), this.configurationModel.getEtPath(),
+ DataSourceType.ET_SERVER);
addItem(item);
} else {
- item.name = configurationModel.getEtPath();
- }
- }
-}
+ item.name = this.configurationModel.getEtPath();
+ }
+ }
+}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/DatePanel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/DatePanel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/DatePanel.java Tue Apr 21 14:48:39 2015
@@ -5,33 +5,72 @@
import java.util.Date;
/**
- * A small JPanel with a date field and a label on its border.
+ * A small <code>JPanel</code> with a date field and a label on its border.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class DatePanel extends FieldPanel {
+@SuppressWarnings("serial")
+final class DatePanel extends FieldPanel {
+ /**
+ * Default date formatting.
+ */
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- DatePanel(String fieldName, String defaultValue, int size, boolean editable) {
+ /**
+ * Create a date panel.
+ *
+ * @param fieldName the field name for the label
+ * @param defaultValue the default value
+ * @param format the date formatter
+ * @param size the size of the field
+ * @param editable <code>true</code> to enable editing
+ */
+ DatePanel(final String fieldName, final Date defaultValue, final SimpleDateFormat format, final int size,
+ final boolean editable) {
+ super(fieldName, format.format(defaultValue), size, editable);
+ }
+
+ /**
+ * Create a date panel with default date formatting.
+ *
+ * @param fieldName the field name for the label
+ * @param defaultValue the default value
+ * @param size the size of the field
+ * @param editable <code>true</code> to enable editing
+ */
+ DatePanel(final String fieldName, final String defaultValue, final int size, final boolean editable) {
super(fieldName, defaultValue, size, editable);
}
- DatePanel(String fieldName, Date defaultValue, SimpleDateFormat format, int size, boolean editable) {
- super(fieldName, format.format(defaultValue), size, editable);
+ /**
+ * Get the value of the field.
+ *
+ * @return the <code>Date</code> object
+ */
+ Date getDateValue() {
+ try {
+ return this.dateFormat.parse(getValue());
+ } catch (final ParseException e) {
+ throw new RuntimeException(e);
+ }
}
- void setDateFormat(SimpleDateFormat dateFormat) {
+ /**
+ * Set the date formatter.
+ *
+ * @param dateFormat the date formatter
+ */
+ void setDateFormat(final SimpleDateFormat dateFormat) {
this.dateFormat = dateFormat;
}
- void setValue(Date date) {
- setValue(dateFormat.format(date));
- }
-
- Date getDateValue() {
- try {
- return dateFormat.parse(getValue());
- } catch (ParseException e) {
- throw new RuntimeException(e);
- }
+ /**
+ * Set the value of the field.
+ *
+ * @param date the <code>Date</code> object
+ */
+ void setValue(final Date date) {
+ setValue(this.dateFormat.format(date));
}
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java Tue Apr 21 14:48:39 2015
@@ -16,32 +16,94 @@
import org.hps.monitoring.application.model.ConnectionStatusModel;
/**
- * This is the panel with buttons for connecting or disconnecting from the session
- * and controlling the application from pause mode.
+ * This is the panel with buttons for connecting or disconnecting from the session and controlling the application when
+ * event processing is paused.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class EventButtonsPanel extends JPanel implements PropertyChangeListener {
+@SuppressWarnings("serial")
+final class EventButtonsPanel extends JPanel implements PropertyChangeListener {
- JButton nextButton;
- JButton pauseButton;
- JButton connectButton;
- JButton resumeButton;
-
- static final ImageIcon connectedIcon = getImageIcon("/monitoringButtonGraphics/connected-128.png");
- static final ImageIcon disconnectedIcon = getImageIcon("/monitoringButtonGraphics/disconnected-128.png");
-
- EventButtonsPanel(ConnectionStatusModel connectionModel, ActionListener listener) {
-
+ /**
+ * Icon when application is connected to event processing session.
+ */
+ static final ImageIcon CONNECTED_ICON = getImageIcon("/monitoringButtonGraphics/connected-128.png");
+
+ /**
+ * Icon when application is disconnected from event processing.
+ */
+ static final ImageIcon DISCONNECTED_ICON = getImageIcon("/monitoringButtonGraphics/disconnected-128.png");
+
+ /**
+ * The icon size (width and height) in pixels.
+ */
+ private static final int ICON_SIZE = 24;
+
+ /**
+ * Get an image icon from a jar resource.
+ *
+ * @param resource the resource path
+ * @return the image icon
+ */
+ static ImageIcon getImageIcon(final String resource) {
+ Image image = null;
+ try {
+ image = ImageIO.read(EventButtonsPanel.class.getResource(resource));
+ image = image.getScaledInstance(ICON_SIZE, ICON_SIZE, 0);
+ } catch (final IOException e) {
+ }
+ return new ImageIcon(image);
+ }
+
+ /**
+ * Button for connect and disconnect which is toggled depending on state.
+ */
+ private final JButton connectButton;
+
+ /**
+ * Button for getting next event when paused.
+ */
+ private final JButton nextButton;
+
+ /**
+ * Button for pausing the event processing.
+ */
+ private final JButton pauseButton;
+
+ /**
+ * Button for resuming the event processing.
+ */
+ private final JButton resumeButton;
+
+ /**
+ * Class constructor.
+ *
+ * @param connectionModel the global connection model
+ * @param listener the action listener
+ */
+ EventButtonsPanel(final ConnectionStatusModel connectionModel, final ActionListener listener) {
+
connectionModel.addPropertyChangeListener(this);
-
+
setLayout(new FlowLayout());
- connectButton = addButton(disconnectedIcon, Commands.CONNECT, listener, true);
- resumeButton = addButton("/toolbarButtonGraphics/media/Play24.gif", Commands.RESUME, listener, false);
- pauseButton = addButton("/toolbarButtonGraphics/media/Pause24.gif", Commands.PAUSE, listener, false);
- nextButton = addButton("/toolbarButtonGraphics/media/StepForward24.gif", Commands.NEXT, listener, false);
+ this.connectButton = addButton(DISCONNECTED_ICON, Commands.CONNECT, listener, true);
+ this.resumeButton = addButton("/toolbarButtonGraphics/media/Play24.gif", Commands.RESUME, listener, false);
+ this.pauseButton = addButton("/toolbarButtonGraphics/media/Pause24.gif", Commands.PAUSE, listener, false);
+ this.nextButton = addButton("/toolbarButtonGraphics/media/StepForward24.gif", Commands.NEXT, listener, false);
}
-
- final JButton addButton(ImageIcon icon, String command, ActionListener listener, boolean enabled) {
- JButton button = new JButton();
+
+ /**
+ * Add a button to the panel.
+ *
+ * @param icon the button's image icon
+ * @param command the command for the action event
+ * @param listener the action listener which handles action events
+ * @param enabled <code>true</code> if button should be enabled initially
+ * @return the new button object
+ */
+ private JButton addButton(final ImageIcon icon, final String command, final ActionListener listener,
+ final boolean enabled) {
+ final JButton button = new JButton();
button.setIcon(icon);
button.setEnabled(enabled);
button.addActionListener(listener);
@@ -49,21 +111,26 @@
this.add(button);
return button;
}
-
- final JButton addButton(String resource, String actionCommand, ActionListener listener, boolean enabled) {
+
+ /**
+ * Add a button to the panel.
+ *
+ * @param resource the resource for the image icon
+ * @param actionCommand the command for the action event
+ * @param listener the action listener which handles action events
+ * @param enabled <code>true</code> if button should be enabled initially
+ * @return the new button object
+ */
+ private JButton addButton(final String resource, final String actionCommand, final ActionListener listener,
+ final boolean enabled) {
return addButton(getImageIcon(resource), actionCommand, listener, enabled);
}
-
- static ImageIcon getImageIcon(String resource) {
- Image image = null;
- try {
- image = ImageIO.read(EventButtonsPanel.class.getResource(resource));
- image = image.getScaledInstance(24, 24, 0);
- } catch (IOException e) {
- }
- return new ImageIcon(image);
- }
+ /**
+ * Handle property change events to set status from changes to the connection status model.
+ *
+ * @param evt the <code>PropertyChangeEvent</code> to handle
+ */
@Override
public void propertyChange(final PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(ConnectionStatusModel.CONNECTION_STATUS_PROPERTY)) {
@@ -72,35 +139,45 @@
setPaused((boolean) evt.getNewValue());
}
}
-
- void setConnectionStatus(final ConnectionStatus status) {
+
+ /**
+ * Set the connection status to update the button state.
+ *
+ * @param status the new connection status
+ */
+ private void setConnectionStatus(final ConnectionStatus status) {
if (status.equals(ConnectionStatus.DISCONNECTED)) {
- nextButton.setEnabled(false);
- pauseButton.setEnabled(false);
- resumeButton.setEnabled(false);
- connectButton.setActionCommand(Commands.CONNECT);
- connectButton.setIcon(disconnectedIcon);
- connectButton.setToolTipText("Start new session");
- connectButton.setEnabled(true);
+ this.nextButton.setEnabled(false);
+ this.pauseButton.setEnabled(false);
+ this.resumeButton.setEnabled(false);
+ this.connectButton.setActionCommand(Commands.CONNECT);
+ this.connectButton.setIcon(DISCONNECTED_ICON);
+ this.connectButton.setToolTipText("Start new session");
+ this.connectButton.setEnabled(true);
} else if (status.equals(ConnectionStatus.DISCONNECTING)) {
- nextButton.setEnabled(false);
- pauseButton.setEnabled(false);
- resumeButton.setEnabled(false);
- connectButton.setEnabled(false);
+ this.nextButton.setEnabled(false);
+ this.pauseButton.setEnabled(false);
+ this.resumeButton.setEnabled(false);
+ this.connectButton.setEnabled(false);
} else if (status.equals(ConnectionStatus.CONNECTED)) {
- nextButton.setEnabled(false);
- pauseButton.setEnabled(true);
- resumeButton.setEnabled(false);
- connectButton.setActionCommand(Commands.DISCONNECT);
- connectButton.setIcon(connectedIcon);
- connectButton.setToolTipText("Disconnect from session");
- connectButton.setEnabled(true);
+ this.nextButton.setEnabled(false);
+ this.pauseButton.setEnabled(true);
+ this.resumeButton.setEnabled(false);
+ this.connectButton.setActionCommand(Commands.DISCONNECT);
+ this.connectButton.setIcon(CONNECTED_ICON);
+ this.connectButton.setToolTipText("Disconnect from session");
+ this.connectButton.setEnabled(true);
}
- }
-
- void setPaused(final boolean paused) {
- resumeButton.setEnabled(paused);
- pauseButton.setEnabled(!paused);
- nextButton.setEnabled(paused);
}
-}
+
+ /**
+ * Set pause mode.
+ *
+ * @param paused <code>true</code> to set paused state
+ */
+ private void setPaused(final boolean paused) {
+ this.resumeButton.setEnabled(paused);
+ this.pauseButton.setEnabled(!paused);
+ this.nextButton.setEnabled(paused);
+ }
+}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventDashboard.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventDashboard.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventDashboard.java Tue Apr 21 14:48:39 2015
@@ -20,248 +20,387 @@
import org.lcsim.event.EventHeader;
/**
- * Dashboard for displaying information about the current run.
- * @author Jeremy McCormick <[log in to unmask]>
+ * This class implements a dashboard for displaying information about the current run.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class EventDashboard extends JPanel implements PropertyChangeListener {
-
- FieldPanel runNumberField = new FieldPanel("Run Number", "", 10, false);
- DatePanel startDateField = new DatePanel("Run Start", "", 14, false);
- DatePanel endDateField = new DatePanel("Run End", "", 14, false);
- FieldPanel lengthField = new FieldPanel("Run Length [sec]", "", 12, false);
- FieldPanel totalEventsField = new FieldPanel("Total Events in Run", "", 14, false);
- FieldPanel elapsedTimeField = new FieldPanel("Elapsed Time [sec]", "", 14, false);
- FieldPanel eventsReceivedField = new FieldPanel("Events Received", "", 14, false);
- FieldPanel dataReceivedField = new FieldPanel("Data Received [MB]", "", 14, false);
- FieldPanel eventNumberField = new FieldPanel("Event Number", "", 14, false);
- FieldPanel dataRateField = new FieldPanel("Data Rate [MB/s]", "", 12, false);
- FieldPanel eventRateField = new FieldPanel("Event Rate [Hz]", "", 14, false);
-
- RunModel runModel;
-
- static final NumberFormat formatter = new DecimalFormat("#0.0000");
-
- public EventDashboard() {
- build();
- }
-
- public EventDashboard(RunModel runModel) {
- this.runModel = runModel;
- this.runModel.addPropertyChangeListener(this);
- build();
- }
-
- private void build() {
-
- setLayout(new FlowLayout(FlowLayout.LEADING));
-
- add(runNumberField);
- add(startDateField);
- add(endDateField);
- add(lengthField);
- add(totalEventsField);
-
- add(elapsedTimeField);
- add(eventsReceivedField);
- add(dataReceivedField);
- add(eventNumberField);
- add(dataRateField);
- add(eventRateField);
- }
-
- public void setModel(RunModel runModel) {
- this.runModel = runModel;
- }
-
+@SuppressWarnings("serial")
+final class EventDashboard extends JPanel implements PropertyChangeListener {
+
+ /**
+ * Updates the fields as events are processed.
+ */
class EventDashboardUpdater extends CompositeRecordProcessor {
- Timer timer;
-
- int eventsReceived;
- double bytesReceived;
- int totalEvents;
- int eventNumber;
- int runNumber = -1;
- long jobStartMillis;
- long lastTickMillis = 0;
- static final long millis = 1000;
-
+ /**
+ * Task to periodically update the fields as events are processed.
+ */
class RunTimerTask extends TimerTask {
-
- public void run() {
-
- double tickLengthSeconds = (System.currentTimeMillis() - lastTickMillis) / (double)millis;
- int elapsedTime = (int) ((System.currentTimeMillis() - jobStartMillis) / (double)millis);
- double megaBytesReceived = bytesReceived / 1000000;
- totalEvents += eventsReceived;
-
- /*
- System.out.println("tickLengthSeconds = " + tickLengthSeconds);
- System.out.println("elapsedTime = " + elapsedTime);
- System.out.println("eventsReceived = " + eventsReceived);
- System.out.println("dataRate = " + (megaBytesReceived / tickLengthSeconds));
- System.out.println("eventNumber = " + eventNumber);
- System.out.println("eventRate = " + (eventsReceived / tickLengthSeconds));
- System.out.println("totalEvents = " + totalEvents);
- System.out.println("megaBytesReceived = " + megaBytesReceived);
- */
-
- runModel.setElapsedTime(elapsedTime);
- runModel.setEventsReceived(totalEvents);
- runModel.setDataRate(megaBytesReceived / tickLengthSeconds);
- runModel.addDataReceived(megaBytesReceived);
- runModel.setEventNumber(eventNumber);
- runModel.setEventRate(eventsReceived / tickLengthSeconds);
-
- eventsReceived = 0;
- bytesReceived = 0;
- eventNumber = 0;
-
- lastTickMillis = System.currentTimeMillis();
-
+
+ /**
+ * Run the timer task to update the GUI from the current values in the model.
+ */
+ @Override
+ public void run() {
+
+ final double tickLengthSeconds = (System.currentTimeMillis() - EventDashboardUpdater.this.lastTickMillis)
+ / (double) MILLIS;
+ final int elapsedTime = (int) ((System.currentTimeMillis() - EventDashboardUpdater.this.jobStartMillis) / (double) MILLIS);
+ final double megaBytesReceived = EventDashboardUpdater.this.bytesReceived / 1000000;
+ EventDashboardUpdater.this.totalEvents += EventDashboardUpdater.this.eventsReceived;
+
+ // Print to System.out if debugging the processor (by default this is off).
+ if (DEBUG) {
+ System.out.println("tickLengthSeconds = " + tickLengthSeconds);
+ System.out.println("elapsedTime = " + elapsedTime);
+ System.out.println("eventsReceived = " + EventDashboardUpdater.this.eventsReceived);
+ System.out.println("dataRate = " + megaBytesReceived / tickLengthSeconds);
+ System.out.println("eventNumber = " + EventDashboardUpdater.this.eventNumber);
+ System.out.println("eventRate = " + EventDashboardUpdater.this.eventsReceived / tickLengthSeconds);
+ System.out.println("totalEvents = " + EventDashboardUpdater.this.totalEvents);
+ System.out.println("megaBytesReceived = " + megaBytesReceived);
+
+ }
+
+ EventDashboard.this.runModel.setElapsedTime(elapsedTime);
+ EventDashboard.this.runModel.setEventsReceived(EventDashboardUpdater.this.totalEvents);
+ EventDashboard.this.runModel.setDataRate(megaBytesReceived / tickLengthSeconds);
+ EventDashboard.this.runModel.addDataReceived(megaBytesReceived);
+ EventDashboard.this.runModel.setEventNumber(EventDashboardUpdater.this.eventNumber);
+ EventDashboard.this.runModel
+ .setEventRate(EventDashboardUpdater.this.eventsReceived / tickLengthSeconds);
+
+ EventDashboardUpdater.this.eventsReceived = 0;
+ EventDashboardUpdater.this.bytesReceived = 0;
+ EventDashboardUpdater.this.eventNumber = 0;
+
+ EventDashboardUpdater.this.lastTickMillis = System.currentTimeMillis();
+
// System.out.println();
- }
- }
-
+ }
+ }
+
+ /**
+ * Set to <code>true</code> to enable debugging.
+ */
+ private static final boolean DEBUG = false;
+
+ /**
+ * Helper for second to milliseconds conversion.
+ */
+ private static final long MILLIS = 1000;
+
+ /**
+ * Helper for second to nanoseconds conversion.
+ */
+ private static final int NANOS = 1000000000;
+
+ /**
+ * The number of bytes received.
+ */
+ private double bytesReceived;
+
+ /**
+ * The current event number.
+ */
+ private int eventNumber;
+
+ /**
+ * The number of events received.
+ */
+ private int eventsReceived;
+
+ /**
+ * The system time in milliseconds when the job started.
+ */
+ private long jobStartMillis;
+
+ /**
+ * The system time in milliseconds when the last timer tick occurred.
+ */
+ private long lastTickMillis = 0;
+
+ /**
+ * The current run number.
+ */
+ private int runNumber = -1;
+
+ /**
+ * The timer for running the update task.
+ */
+ private Timer timer;
+
+ /**
+ * The total number of events received.
+ */
+ private int totalEvents;
+
+ /**
+ * Check for head bank and update the run info if necessary.
+ *
+ * @param evioEvent the EVIO event
+ */
+ private void checkHeadBank(final EvioEvent evioEvent) {
+ final BaseStructure headBank = EvioEventUtilities.getHeadBank(evioEvent);
+ if (headBank != null) {
+ final int headBankRun = headBank.getIntData()[1];
+ if (headBankRun != this.runNumber) {
+ this.runNumber = headBankRun;
+ EventDashboard.this.runModel.setRunNumber(headBankRun);
+ EventDashboard.this.runModel.setStartDate(new Date(headBank.getIntData()[3] * MILLIS));
+ }
+ }
+ }
+
+ /**
+ * Perform end of job hook, which will cancel the update timer.
+ */
@Override
- public void startJob() {
- runModel.reset();
- jobStartMillis = System.currentTimeMillis();
-
- // Start the timer to update GUI components about once per second.
- timer = new Timer("RunModelUpdaterTimer");
- lastTickMillis = System.currentTimeMillis();
- timer.scheduleAtFixedRate(new RunTimerTask(), 0, 1000);
- }
-
+ public void endJob() {
+ this.timer.cancel();
+
+ // Push final values into GUI.
+ this.timer = new Timer("RunModelUpdaterEndJobTimer");
+ this.timer.schedule(new RunTimerTask(), 0);
+ }
+
+ /**
+ * Handle an EVIO END event.
+ *
+ * @param evioEvent the EVIO END event
+ */
+ private void endRun(final EvioEvent evioEvent) {
+ // Get end run data.
+ final int[] data = EvioEventUtilities.getControlEventData(evioEvent);
+ if (data != null) {
+ final int seconds = data[0];
+ final int eventCount = data[2];
+ final long endMillis = (long) seconds * 1000;
+
+ // Update the GUI.
+ EventDashboard.this.runModel.setEndDate(new Date(endMillis));
+ EventDashboard.this.runModel.computeRunLength();
+ EventDashboard.this.runModel.setTotalEvents(eventCount);
+ }
+ }
+
+ /**
+ * Process a {@link org.hps.record.composite.CompositeRecord} to extract information from available event
+ * sources and update the running values.
+ */
@Override
- public void process(CompositeRecord event) {
+ public void process(final CompositeRecord event) {
// FIXME: CompositeRecord number is always -1 here.
if (event.getEvioEvent() != null) {
- EvioEvent evioEvent = event.getEvioEvent();
- bytesReceived += evioEvent.getTotalBytes();
+ final EvioEvent evioEvent = event.getEvioEvent();
+ this.bytesReceived += evioEvent.getTotalBytes();
if (EvioEventUtilities.isPreStartEvent(evioEvent)) {
// Get run start info from pre start event.
startRun(evioEvent);
} else if (EvioEventUtilities.isEndEvent(evioEvent)) {
// Get end run info from end event.
endRun(evioEvent);
- } else if (EvioEventUtilities.isPhysicsEvent(evioEvent)) {
+ } else if (EvioEventUtilities.isPhysicsEvent(evioEvent)) {
// Check for run info in head bank.
checkHeadBank(evioEvent);
- eventNumber = evioEvent.getEventNumber();
- eventsReceived += 1;
+ this.eventNumber = evioEvent.getEventNumber();
+ this.eventsReceived += 1;
}
} else if (event.getEtEvent() != null) {
- bytesReceived += event.getEtEvent().getData().length;
- eventNumber = event.getEtEvent().getId();
- eventsReceived += 1;
+ this.bytesReceived += event.getEtEvent().getData().length;
+ this.eventNumber = event.getEtEvent().getId();
+ this.eventsReceived += 1;
} else if (event.getLcioEvent() != null) {
- EventHeader lcioEvent = event.getLcioEvent();
- eventNumber = lcioEvent.getEventNumber();
- if (lcioEvent.getRunNumber() != runNumber) {
- runNumber = lcioEvent.getRunNumber();
+ final EventHeader lcioEvent = event.getLcioEvent();
+ this.eventNumber = lcioEvent.getEventNumber();
+ if (lcioEvent.getRunNumber() != this.runNumber) {
+ this.runNumber = lcioEvent.getRunNumber();
startRun(lcioEvent);
}
- eventsReceived += 1;
- }
- }
-
- /**
- * Check for head bank and update the run info if necessary.
- * @param evioEvent The EVIO event.
- */
- private void checkHeadBank(EvioEvent evioEvent) {
- BaseStructure headBank = EvioEventUtilities.getHeadBank(evioEvent);
- if (headBank != null) {
- int headBankRun = headBank.getIntData()[1];
- if (headBankRun != runNumber) {
- runNumber = headBankRun;
- runModel.setRunNumber(headBankRun);
- runModel.setStartDate(new Date(headBank.getIntData()[3] * 1000));
- }
- }
- }
-
- private void endRun(EvioEvent evioEvent) {
- // Get end run data.
- int[] data = EvioEventUtilities.getControlEventData(evioEvent);
+ this.eventsReceived += 1;
+ }
+ }
+
+ /**
+ * Perform start of job hook which initializes this processor.
+ */
+ @Override
+ public void startJob() {
+ EventDashboard.this.runModel.reset();
+ this.jobStartMillis = System.currentTimeMillis();
+
+ // Start the timer to update GUI components about once per second.
+ this.timer = new Timer("RunModelUpdaterTimer");
+ this.lastTickMillis = System.currentTimeMillis();
+ this.timer.scheduleAtFixedRate(new RunTimerTask(), 0, MILLIS);
+ }
+
+ /**
+ * Handle start of run using an LCIO event.
+ *
+ * @param lcioEvent the LCIO event
+ */
+ private void startRun(final EventHeader lcioEvent) {
+ EventDashboard.this.runModel.setRunNumber(lcioEvent.getRunNumber());
+ final long seconds = lcioEvent.getTimeStamp() / NANOS;
+ EventDashboard.this.runModel.setStartDate(new Date((int) seconds));
+ }
+
+ /**
+ * Handle start of run using an EVIO START event.
+ *
+ * @param evioEvent the EVIO START event
+ */
+ private void startRun(final EvioEvent evioEvent) {
+ // Get start of run data.
+ final int[] data = EvioEventUtilities.getControlEventData(evioEvent);
if (data != null) {
- int seconds = data[0];
- int eventCount = data[2];
- long endMillis = ((long) seconds) * 1000;
+ final int seconds = data[0];
+ this.runNumber = data[1];
// Update the GUI.
- runModel.setEndDate(new Date(endMillis));
- runModel.computeRunLength();
- runModel.setTotalEvents(eventCount);
- }
- }
-
- private void startRun(EvioEvent evioEvent) {
- // Get start of run data.
- int[] data = EvioEventUtilities.getControlEventData(evioEvent);
- if (data != null) {
- int seconds = data[0];
- runNumber = data[1];
-
- // Update the GUI.
- runModel.setRunNumber(runNumber);
- runModel.setStartDate(new Date(seconds * 1000));
- }
- }
-
- private void startRun(EventHeader lcioEvent) {
- runModel.setRunNumber(lcioEvent.getRunNumber());
- long seconds = lcioEvent.getTimeStamp() / 1000000000;
- runModel.setStartDate(new Date((int)seconds));
- }
-
- @Override
- public void endJob() {
- timer.cancel();
-
- // Push final values into GUI.
- timer = new Timer("RunModelUpdaterEndJobTimer");
- timer.schedule(new RunTimerTask(), 0);
+ EventDashboard.this.runModel.setRunNumber(this.runNumber);
+ EventDashboard.this.runModel.setStartDate(new Date(seconds * MILLIS));
+ }
}
}
-
- /**
- * Update the GUI from changes to the backing RunModel object.
+
+ /**
+ * The decimal format (shows decimal numbers to 4 places).
+ */
+ static final NumberFormat DECIMAL_FORMAT = new DecimalFormat("#0.0000");
+
+ /**
+ * Field for showing the data rate in MB per second.
+ */
+ private final FieldPanel dataRateField = new FieldPanel("Data Rate [MB/s]", "", 12, false);
+
+ /**
+ * Field for showing the total data received in MB.
+ */
+ private final FieldPanel dataReceivedField = new FieldPanel("Data Received [MB]", "", 14, false);
+
+ /**
+ * Field for showing the elapsed job time in seconds.
+ */
+ private final FieldPanel elapsedTimeField = new FieldPanel("Elapsed Time [sec]", "", 14, false);
+
+ /**
+ * Field for showing the end date.
+ */
+ private final DatePanel endDateField = new DatePanel("Run End", "", 14, false);
+
+ /**
+ * Field for showing the current event number.
+ */
+ private final FieldPanel eventNumberField = new FieldPanel("Event Number", "", 14, false);
+
+ /**
+ * Field showing the event rate in Hertz.
+ */
+ private final FieldPanel eventRateField = new FieldPanel("Event Rate [Hz]", "", 14, false);
+
+ /**
+ * Field for showing the total number of events received.
+ */
+ private final FieldPanel eventsReceivedField = new FieldPanel("Events Received", "", 14, false);
+
+ /**
+ * Field for showing the length of the run in seconds.
+ */
+ private final FieldPanel lengthField = new FieldPanel("Run Length [sec]", "", 12, false);
+
+ /**
+ * The backing model with run and event information.
+ */
+ private final RunModel runModel;
+
+ /**
+ * Field for showing the run number.
+ */
+ private final FieldPanel runNumberField = new FieldPanel("Run Number", "", 10, false);
+
+ /**
+ * Field for showing the start date.
+ */
+ private final DatePanel startDateField = new DatePanel("Run Start", "", 14, false);
+
+ /**
+ * Field for showing the total events in the run.
+ */
+ private final FieldPanel totalEventsField = new FieldPanel("Total Events in Run", "", 14, false);
+
+ /**
+ * Class constructor which takes reference to backing model.
+ *
+ * @param runModel the backing {@link org.hps.monitoring.application.model.RunModel} with event and run information
+ */
+ public EventDashboard(final RunModel runModel) {
+ this.runModel = runModel;
+ this.runModel.addPropertyChangeListener(this);
+ build();
+ }
+
+ /**
+ * Build the GUI components.
+ */
+ private void build() {
+
+ setLayout(new FlowLayout(FlowLayout.LEADING));
+
+ add(this.runNumberField);
+ add(this.startDateField);
+ add(this.endDateField);
+ add(this.lengthField);
+ add(this.totalEventsField);
+
+ add(this.elapsedTimeField);
+ add(this.eventsReceivedField);
+ add(this.dataReceivedField);
+ add(this.eventNumberField);
+ add(this.dataRateField);
+ add(this.eventRateField);
+ }
+
+ /**
+ * Update the GUI from changes to the backing {@link org.hps.monitoring.application.model.RunModel} object.
+ *
+ * @param evt the {@link java.beans.PropertyChangeEvent} to handle
*/
@Override
- public void propertyChange(PropertyChangeEvent evt) {
- //System.out.println("RunPanel.propertyChange - " + evt.getPropertyName());
- Object value = evt.getNewValue();
+ public void propertyChange(final PropertyChangeEvent evt) {
+ // System.out.println("RunPanel.propertyChange - " + evt.getPropertyName());
+ final Object value = evt.getNewValue();
if (RunModel.RUN_NUMBER_PROPERTY.equals(evt.getPropertyName())) {
- runNumberField.setValue((Integer) value);
+ this.runNumberField.setValue((Integer) value);
} else if (RunModel.START_DATE_PROPERTY.equals(evt.getPropertyName())) {
- if (value != null)
- startDateField.setValue((Date) value);
- else
- startDateField.setValue("");
+ if (value != null) {
+ this.startDateField.setValue((Date) value);
+ } else {
+ this.startDateField.setValue("");
+ }
} else if (RunModel.END_DATE_PROPERTY.equals(evt.getPropertyName())) {
- if (value != null)
- endDateField.setValue((Date) value);
- else
- endDateField.setValue("");
+ if (value != null) {
+ this.endDateField.setValue((Date) value);
+ } else {
+ this.endDateField.setValue("");
+ }
} else if (RunModel.RUN_LENGTH_PROPERTY.equals(evt.getPropertyName())) {
- lengthField.setValue((Integer) value);
+ this.lengthField.setValue((Integer) value);
} else if (RunModel.TOTAL_EVENTS_PROPERTY.equals(evt.getPropertyName())) {
- totalEventsField.setValue((Integer) value);
+ this.totalEventsField.setValue((Integer) value);
} else if (RunModel.EVENTS_RECEIVED_PROPERTY.equals(evt.getPropertyName())) {
- eventsReceivedField.setValue((Integer) value);
+ this.eventsReceivedField.setValue((Integer) value);
} else if (RunModel.ELAPSED_TIME_PROPERTY.equals(evt.getPropertyName())) {
- elapsedTimeField.setValue((Integer) value);
+ this.elapsedTimeField.setValue((Integer) value);
} else if (RunModel.DATA_RECEIVED_PROPERTY.equals(evt.getPropertyName())) {
- dataReceivedField.setValue(formatter.format((Double) value));
+ this.dataReceivedField.setValue(DECIMAL_FORMAT.format(value));
} else if (RunModel.EVENT_NUMBER_PROPERTY.equals(evt.getPropertyName())) {
- eventNumberField.setValue((Integer) value);
+ this.eventNumberField.setValue((Integer) value);
} else if (RunModel.DATA_RATE_PROPERTY.equals(evt.getPropertyName())) {
- dataRateField.setValue(formatter.format((Double) value));
+ this.dataRateField.setValue(DECIMAL_FORMAT.format(value));
} else if (RunModel.EVENT_RATE_PROPERTY.equals(evt.getPropertyName())) {
- eventRateField.setValue(formatter.format((Double) value));
+ this.eventRateField.setValue(DECIMAL_FORMAT.format(value));
}
}
-}
+}
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 Apr 21 14:48:39 2015
@@ -18,7 +18,6 @@
import org.hps.monitoring.application.model.SteeringType;
import org.hps.monitoring.application.util.ErrorHandler;
import org.hps.monitoring.application.util.EtSystemUtil;
-import org.hps.monitoring.application.util.SyncEventProcessor;
import org.hps.monitoring.subsys.et.EtSystemMonitor;
import org.hps.monitoring.subsys.et.EtSystemStripCharts;
import org.hps.record.LCSimEventBuilder;
@@ -27,13 +26,9 @@
import org.hps.record.composite.CompositeRecordProcessor;
import org.hps.record.composite.EventProcessingThread;
import org.hps.record.enums.DataSourceType;
-import org.hps.record.epics.EpicsEtProcessor;
import org.hps.record.et.EtConnection;
-import org.hps.record.et.EtEventProcessor;
import org.hps.record.et.EtStationThread;
-import org.hps.record.et.PreStartProcessor;
import org.hps.record.evio.EvioDetectorConditionsProcessor;
-import org.hps.record.evio.EvioEventConstants;
import org.jlab.coda.et.EtConstants;
import org.jlab.coda.et.exception.EtClosedException;
import org.jlab.coda.et.exception.EtException;
@@ -43,665 +38,722 @@
import org.lcsim.util.Driver;
/**
- * This class encapsulates all of the logic involved with processing events and managing the related
- * state and objects within the monitoring application.
- *
- * @author Jeremy McCormick <[log in to unmask]>
+ * This class encapsulates all of the logic involved with processing events and managing the related state and objects
+ * within the monitoring application.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class EventProcessing {
-
- SessionState sessionState;
- MonitoringApplication application;
- ConfigurationModel configurationModel;
- ConnectionStatusModel connectionModel;
- ErrorHandler errorHandler;
- Logger logger;
-
- /**
- * This class is used to organize the objects for an event processing session.
- */
- class SessionState {
-
- List<CompositeRecordProcessor> processors;
- List<Driver> drivers;
- List<ConditionsListener> conditionsListeners;
-
- JobManager jobManager;
- LCSimEventBuilder eventBuilder;
- CompositeLoop loop;
-
- boolean usingEtServer;
-
- EventProcessingThread processingThread;
- Thread sessionWatchdogThread;
- ThreadGroup stationThreadGroup = new ThreadGroup("Station Threads");
- List<EtStationThread> stations = new ArrayList<EtStationThread>();
- EtConnection connection;
- }
-
- /**
- * Initialize with reference to the current monitoring application and a list of extra
- * processors to add to the loop after configuration.
- * @param application The current monitoring application.
- * @param processors A list of processors to add after configuration is performed.
- */
- EventProcessing(
- MonitoringApplication application,
- List<CompositeRecordProcessor> processors,
- List<Driver> drivers,
- List<ConditionsListener> conditionsListeners) {
-
+final class EventProcessing {
+
+ /**
+ * This class organizes and encapsulates most of the objects used by an event processing session.
+ */
+ private final class SessionState {
+
+ /**
+ * A list of extra {@link org.lcsim.conditions.ConditionsListener} objects to add to the loop.
+ */
+ private List<ConditionsListener> conditionsListeners;
+
+ /**
+ * An {@link org.hps.record.et.EtConnection} with ET configuration (can be null if using a file source).
+ */
+ private EtConnection connection;
+
+ /**
+ * A list of extra {@link org.lcsim.util.Driver} objects to add to the loop.
+ */
+ private List<Driver> drivers;
+
+ /**
+ * The class for building the LCSim events from EVIO data.
+ */
+ private LCSimEventBuilder eventBuilder;
+
+ /**
+ * The LCSim {@link org.hps.job.JobManager} which handles the <code>Driver</code> setup from XML steering files.
+ */
+ private JobManager jobManager;
+
+ /**
+ * The loop which manages the ET to EVIO to LCIO event building and processing.
+ */
+ private CompositeLoop loop;
+
+ /**
+ * The {@link org.hps.record.composite.EventProcessingThread} on which event processing executes.
+ */
+ private EventProcessingThread processingThread;
+
+ /**
+ * The list of extra {@link org.hps.record.composite.CompositeRecordProcessor} objects to add to the loop.
+ */
+ private List<CompositeRecordProcessor> processors;
+
+ /**
+ * A {@link java.lang.Thread} which is used to monitor the event processing.
+ */
+ private Thread sessionWatchdogThread;
+
+ /**
+ * A list of ET stations on separate threads (currently unused).
+ */
+ private List<EtStationThread> stations = new ArrayList<EtStationThread>();
+
+ /**
+ * The ET station thread group (currently unused).
+ */
+ private ThreadGroup stationThreadGroup = new ThreadGroup("Station Threads");
+
+ /**
+ * This is <code>true</code> if the session will connect to a network ET event server.
+ */
+ private boolean usingEtServer;
+ }
+
+ /**
+ * This class will cause the application to disconnect from the current event processing session if the event
+ * processing thread completes.
+ */
+ private final class SessionWatchdogThread extends Thread {
+
+ /**
+ * A reference to the current {{@link #EventProcessing(Thread)}.
+ */
+ private final Thread processingThread;
+
+ /**
+ * Class constructor.
+ *
+ * @param processingThread the current {{@link #EventProcessing(Thread)}
+ */
+ private SessionWatchdogThread(final Thread processingThread) {
+ this.processingThread = processingThread;
+ }
+
+ /**
+ * Run this thread, which will disconnect from the current session if the event processing ends for any reason.
+ */
+ @Override
+ public void run() {
+ try {
+ // This thread waits on the event processing thread to die.
+ this.processingThread.join();
+
+ // Activate a disconnect using the ActionEvent which is used by the disconnect button.
+ EventProcessing.this.logger.finest("processing thread ended so automatic disconnect is happening");
+ EventProcessing.this.application.actionPerformed(new ActionEvent(Thread.currentThread(), 0,
+ Commands.DISCONNECT));
+
+ } catch (final InterruptedException e) {
+ EventProcessing.this.logger.finest("SessionWatchdogThread got interrupted");
+ // This happens when the thread is interrupted by the user pressing the disconnect button.
+ }
+ }
+ }
+
+ /**
+ * Create the select array from event selection in ET stations (not currently used).
+ *
+ * @return The select array.
+ */
+ static int[] createSelectArray() {
+ final int[] select = new int[EtConstants.stationSelectInts];
+ Arrays.fill(select, -1);
+ return select;
+ }
+
+ /**
+ * Reference to the current application.
+ */
+ private MonitoringApplication application;
+
+ /**
+ * Reference to the global configuration model.
+ */
+ private ConfigurationModel configurationModel;
+
+ /**
+ * Reference to the global connection model.
+ */
+ private ConnectionStatusModel connectionModel;
+
+ /**
+ * The error handler, which is just a reference to the application's error handler.
+ */
+ private ErrorHandler errorHandler;
+
+ /**
+ * The logger to use for message which is the application's logger.
+ */
+ private Logger logger;
+
+ /**
+ * The current {@link EventProcessing.SessionState} object which has all of the session state for event processing.
+ */
+ private SessionState sessionState;
+
+ /**
+ * Class constructor, which will initialize with reference to the current monitoring application and lists of extra
+ * processors to add to the loop, as well as supplemental conditions listeners that activate when the conditions
+ * change.
+ *
+ * @param application the current monitoring application object
+ * @param processors a list of processors to add after configuration is performed
+ * @param drivers a list of extra {@link org.lcsim.util.Driver} objects to add to the loop
+ * @param conditionsListeners a list of extra {@link org.lcsim.conditions.ConditionsListener} to add to the loop
+ */
+ EventProcessing(final MonitoringApplication application, final List<CompositeRecordProcessor> processors,
+ final List<Driver> drivers, final List<ConditionsListener> conditionsListeners) {
+
this.application = application;
- logger = MonitoringApplication.logger;
- configurationModel = application.configurationModel;
- connectionModel = application.connectionModel;
- errorHandler = application.errorHandler;
-
- sessionState = new SessionState();
- sessionState.processors = processors;
- sessionState.drivers = drivers;
- sessionState.conditionsListeners = conditionsListeners;
- sessionState.usingEtServer = application.configurationModel.getDataSourceType().equals(DataSourceType.ET_SERVER);
- }
-
- /**
- * Setup this class from the global configuration.
- * @param configurationModel The global configuration.
- */
- void setup(ConfigurationModel configurationModel) {
-
+ this.logger = application.getLogger();
+ this.configurationModel = application.getConfigurationModel();
+ this.connectionModel = application.getConnectionModel();
+ this.errorHandler = application.getErrorHandler();
+
+ this.sessionState = new SessionState();
+ this.sessionState.processors = processors;
+ this.sessionState.drivers = drivers;
+ this.sessionState.conditionsListeners = conditionsListeners;
+ this.sessionState.usingEtServer = application.getConfigurationModel().getDataSourceType()
+ .equals(DataSourceType.ET_SERVER);
+ }
+
+ /**
+ * Close the current ET connection.
+ * <p>
+ * This method does not need to be <code>synchronized</code>, because it is only called from the
+ * {@link #disconnect()} method which is itself <code>synchronized</code>.
+ */
+ private void closeEtConnection() {
+ if (this.sessionState.connection != null) {
+ this.logger.fine("closing ET connection");
+ if (this.sessionState.connection.getEtSystem().alive()) {
+ this.logger.finest("cleaning up the connection ...");
+ this.sessionState.connection.cleanup();
+ this.logger.finest("connection cleanup successful");
+ }
+ this.sessionState.connection = null;
+ this.logger.fine("ET connection closed");
+ }
+ }
+
+ /**
+ * Connect to the ET system using the current connection settings.
+ *
+ * @throws IOException if any error occurs while creating the ET connection
+ */
+ synchronized void connect() throws IOException {
+ // Setup the network connection if using an ET server.
+ if (this.usingEtServer()) {
+ // Create a connection to the ET server.
+ try {
+ this.logger.fine("connecting to ET system ...");
+
+ // Create the main ET system connection.
+ this.createEtConnection();
+
+ // FIXME: Separate event processing ET stations not currently used due to synchronization and ET issues.
+
+ // Add an attachment that listens for DAQ configuration changes via physics SYNC events.
+ // createSyncStation();
+
+ // Add an attachment which listens for EPICs events with scalar data.
+ // createEpicsStation();
+
+ // Add an attachment that listens for PRESTART events.
+ // createPreStartStation();
+
+ } catch (final Exception e) {
+ throw new IOException(e);
+ }
+
+ this.logger.fine("ET system is connected");
+ } else {
+ // This is when a direct file source is used and ET is not needed.
+ this.connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED);
+ }
+
+ }
+
+ /**
+ * Create a connection to an ET system using current parameters from the GUI.
+ * <p>
+ * This method does not need to be <code>synchronized</code>, because it is only called from the {@link #connect()}
+ * method which is itself <code>synchronized</code>.
+ */
+ private void createEtConnection() {
+ // Setup connection to ET system.
+ this.sessionState.connection = EtSystemUtil.createEtConnection(this.configurationModel);
+
+ if (this.sessionState.connection != null) {
+ // Set status to connected as there is now a live ET connection.
+ this.connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED);
+ } else {
+ this.errorHandler.setError(new RuntimeException("Failed to create ET connection.")).log().printStackTrace()
+ .raiseException();
+ }
+ }
+
+ /**
+ * Create the event builder for converting EVIO events to LCSim.
+ *
+ * @param configurationModel the current global {@link org.hps.monitoring.application.ConfigurationModel} object
+ */
+ private void createEventBuilder(final ConfigurationModel configurationModel) {
+
+ // Get the class for the event builder.
+ final String eventBuilderClassName = configurationModel.getEventBuilderClassName();
+
+ try {
+ // Create a new instance of the builder class.
+ this.sessionState.eventBuilder = (LCSimEventBuilder) Class.forName(eventBuilderClassName, true,
+ Thread.currentThread().getContextClassLoader()).newInstance();
+ } catch (final Exception e) {
+ throw new RuntimeException("Failed to create LCSimEventBuilder.", e);
+ }
+
+ // Add the builder as a listener so it is notified when conditions change.
+ ConditionsManager.defaultInstance().addConditionsListener(this.sessionState.eventBuilder);
+ }
+
+ /**
+ * Disconnect from the current session, closing the ET connection if necessary.
+ */
+ synchronized void disconnect() {
+
+ // Cleanup the ET connection.
+ if (this.usingEtServer()) {
+ this.closeEtConnection();
+ }
+
+ // Change application state to disconnected.
+ this.connectionModel.setConnectionStatus(ConnectionStatus.DISCONNECTED);
+ }
+
+ /**
+ * Invalidate all of the local variables and session state so that this object is not usable after a disconnect.
+ */
+ void invalidate() {
+
+ this.application = null;
+ this.logger = null;
+ this.configurationModel = null;
+ this.connectionModel = null;
+ this.errorHandler = null;
+
+ this.sessionState.conditionsListeners = null;
+ this.sessionState.drivers = null;
+ this.sessionState.processors = null;
+ this.sessionState.jobManager = null;
+ this.sessionState.eventBuilder = null;
+ this.sessionState.loop = null;
+ this.sessionState.processingThread = null;
+ this.sessionState.sessionWatchdogThread = null;
+ this.sessionState.stationThreadGroup = null;
+ this.sessionState.stations = null;
+ this.sessionState.connection = null;
+
+ this.sessionState = null;
+ }
+
+ /**
+ * Return <code>true</code> if the event processing thread is valid (non-null) and active.
+ *
+ * @return <code>true</code> if event processing thread is active
+ */
+ boolean isActive() {
+ return this.sessionState.processingThread != null && this.sessionState.processingThread.isAlive();
+ }
+
+ /**
+ * Interrupt and join the processing watchdog thread.
+ * <p>
+ * This will happen if there is a user requested disconnect from pushing the button in the GUI.
+ */
+ synchronized void killWatchdogThread() {
+ // Is the session watchdog thread not null?
+ if (this.sessionState.sessionWatchdogThread != null) {
+ this.logger.finest("killing watchdog thread ...");
+ // Is the thread still alive?
+ if (this.sessionState.sessionWatchdogThread.isAlive()) {
+ // Interrupt the thread which should cause it to stop.
+ this.sessionState.sessionWatchdogThread.interrupt();
+ try {
+ // This should always work once the thread is interrupted.
+ this.sessionState.sessionWatchdogThread.join();
+ } catch (final InterruptedException e) {
+ }
+ }
+ // Set the thread object to null.
+ this.sessionState.sessionWatchdogThread = null;
+ this.logger.finest("watchdog thread killed");
+ }
+ }
+
+ /**
+ * Get the next event from the loop if in pause mode.
+ */
+ synchronized void next() {
+ this.logger.finest("getting next event");
+ if (this.connectionModel.getPaused()) {
+ this.connectionModel.setPaused(false);
+ this.sessionState.loop.execute(Command.GO_N, 1L, true);
+ this.connectionModel.setPaused(true);
+ }
+ this.logger.finest("got next event");
+ }
+
+ /**
+ * Notify the loop to pause the event processing.
+ */
+ synchronized void pause() {
+ this.logger.finest("pausing");
+ if (!this.connectionModel.getPaused()) {
+ this.sessionState.loop.pause();
+ this.connectionModel.setPaused(true);
+ }
+ this.logger.finest("paused");
+ }
+
+ /**
+ * Resume processing events from pause mode by resuming loop event processing.
+ */
+ synchronized void resume() {
+ this.logger.finest("resuming");
+ if (this.connectionModel.getPaused()) {
+ // Notify event processor to continue.
+ this.sessionState.loop.resume();
+ this.connectionModel.setPaused(false);
+ }
+ this.logger.finest("resumed");
+ }
+
+ /**
+ * Setup this class from the global {@link org.hps.monitoring.model.ConfigurationModel} object.
+ *
+ * @param configurationModel the global @link org.hps.monitoring.model.ConfigurationModel} object
+ */
+ void setup(final ConfigurationModel configurationModel) {
+
// Setup LCSim from the configuration.
- setupLcsim(configurationModel);
+ this.setupLcsim(configurationModel);
// Now setup the CompositeLoop.
- setupLoop(configurationModel);
- }
-
- /**
- * @param configurationModel
- */
- void setupLcsim(ConfigurationModel configurationModel) {
- MonitoringApplication.logger.info("setting up lcsim");
+ this.setupLoop(configurationModel);
+ }
+
+ /**
+ * Setup LCSim event processing from the global {@link org.hps.monitoring.model.ConfigurationModel} object.
+ *
+ * @param configurationModel the global @link org.hps.monitoring.model.ConfigurationModel} object
+ */
+ private void setupLcsim(final ConfigurationModel configurationModel) {
+ this.logger.info("setting up lcsim");
// Get steering resource or file as a String parameter.
String steering = null;
- SteeringType steeringType = configurationModel.getSteeringType();
+ final SteeringType steeringType = configurationModel.getSteeringType();
if (steeringType.equals(SteeringType.FILE)) {
steering = configurationModel.getSteeringFile();
} else {
steering = configurationModel.getSteeringResource();
}
- MonitoringApplication.logger.config("set steering " + steering + " with type " + (steeringType == SteeringType.RESOURCE ? "RESOURCE" : "FILE"));
+ this.logger.config("set steering " + steering + " with type "
+ + (steeringType == SteeringType.RESOURCE ? "RESOURCE" : "FILE"));
try {
// Create the job manager. A new conditions manager is instantiated from this call but not configured.
- sessionState.jobManager = new JobManager();
+ this.sessionState.jobManager = new JobManager();
// Add conditions listeners after new database conditions manager is initialized from the job manager.
- DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
- for (ConditionsListener conditionsListener : sessionState.conditionsListeners) {
- logger.config("adding conditions listener " + conditionsListener.getClass().getName());
+ final DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
+ for (final ConditionsListener conditionsListener : this.sessionState.conditionsListeners) {
+ this.logger.config("adding conditions listener " + conditionsListener.getClass().getName());
conditionsManager.addConditionsListener(conditionsListener);
}
if (configurationModel.hasValidProperty(ConfigurationModel.DETECTOR_ALIAS_PROPERTY)) {
// Set a detector alias.
- ConditionsReader.addAlias(configurationModel.getDetectorName(), "file://" + configurationModel.getDetectorAlias());
- logger.config("using detector alias " + configurationModel.getDetectorAlias());
+ ConditionsReader.addAlias(configurationModel.getDetectorName(),
+ "file://" + configurationModel.getDetectorAlias());
+ this.logger.config("using detector alias " + configurationModel.getDetectorAlias());
}
// Setup the event builder to translate from EVIO to LCIO.
// This must happen before Driver setup so the builder's listeners are activated first!
- createEventBuilder(configurationModel);
+ this.createEventBuilder(configurationModel);
// Configure the job manager for the XML steering.
- sessionState.jobManager.setPerformDryRun(true);
+ this.sessionState.jobManager.setPerformDryRun(true);
if (steeringType == SteeringType.RESOURCE) {
- setupSteeringResource(steering);
+ this.setupSteeringResource(steering);
} 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());
+ this.setupSteeringFile(steering);
+ }
+
+ // Set conditions tag if applicable.
+ if (configurationModel.hasValidProperty(ConfigurationModel.CONDITIONS_TAG_PROPERTY)
+ && !configurationModel.getConditionsTag().equals("")) {
+ this.logger.config("conditions tag is set to " + configurationModel.getConditionsTag());
} else {
- logger.config("conditions NOT using a tag");
+ this.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)) {
- int userRunNumber = configurationModel.getUserRunNumber();
- String detectorName = configurationModel.getDetectorName();
- logger.config("setting user run number " + userRunNumber + " with detector " + detectorName);
+ final int userRunNumber = configurationModel.getUserRunNumber();
+ final String detectorName = configurationModel.getDetectorName();
+ this.logger.config("setting user run number " + userRunNumber + " with detector " + detectorName);
conditionsManager.setDetector(configurationModel.getDetectorName(), userRunNumber);
if (configurationModel.hasPropertyKey(ConfigurationModel.FREEZE_CONDITIONS_PROPERTY)) {
// Freeze the conditions system to ignore run numbers from the events.
- logger.config("user configured to freeze conditions system");
+ this.logger.config("user configured to freeze conditions system");
conditionsManager.freeze();
} else {
// Allow run numbers to be picked up from the events.
- logger.config("user run number provided but conditions system is NOT frozen");
+ this.logger.config("user run number provided but conditions system is NOT frozen");
conditionsManager.unfreeze();
}
}
- logger.info("lcsim setup was successful");
-
- } catch (Throwable t) {
+ this.logger.info("lcsim setup was successful");
+
+ } catch (final Throwable t) {
throw new RuntimeException("Error setting up LCSim.", t);
}
}
/**
- * Create the event builder for converting EVIO events to LCSim.
- */
- void createEventBuilder(ConfigurationModel configurationModel) {
-
- // Get the class for the event builder.
- String eventBuilderClassName = configurationModel.getEventBuilderClassName();
-
- try {
- // Create a new instance of the builder class.
- sessionState.eventBuilder = (LCSimEventBuilder) Class.forName(eventBuilderClassName, true, Thread.currentThread().getContextClassLoader()).newInstance();
- } catch (Exception e) {
- throw new RuntimeException("Failed to create LCSimEventBuilder.", e);
- }
-
- // Add the builder as a listener so it is notified when conditions change.
- ConditionsManager.defaultInstance().addConditionsListener(sessionState.eventBuilder);
- }
-
- /**
- * Setup the loop from the global configuration.
- * @param configurationModel The global configuration.
- */
- void setupLoop(ConfigurationModel configurationModel) {
-
- logger.config("setting up record loop ...");
-
- CompositeLoopConfiguration loopConfig = new CompositeLoopConfiguration()
- .setStopOnEndRun(configurationModel.getDisconnectOnEndRun())
- .setStopOnErrors(configurationModel.getDisconnectOnError())
- .setDataSourceType(configurationModel.getDataSourceType())
- .setProcessingStage(configurationModel.getProcessingStage())
- .setEtConnection(sessionState.connection)
- .setFilePath(configurationModel.getDataSourcePath())
- .setLCSimEventBuilder(sessionState.eventBuilder);
-
- logger.config("data source path is " + configurationModel.getDataSourcePath());
- logger.config("data source type is " + configurationModel.getDataSourceType());
-
+ * Setup the {@link org.hps.record.composite.CompositeLoop} from the global
+ * {@link org.hps.monitoring.model.ConfigurationModel} object.
+ *
+ * @param configurationModel the global {@link org.hps.monitoring.model.ConfigurationModel} object
+ */
+ private void setupLoop(final ConfigurationModel configurationModel) {
+
+ this.logger.config("setting up record loop ...");
+
+ // Initialize the loop from the ConfigurationModel.
+ final CompositeLoopConfiguration loopConfig = new CompositeLoopConfiguration()
+ .setStopOnEndRun(configurationModel.getDisconnectOnEndRun())
+ .setStopOnErrors(configurationModel.getDisconnectOnError())
+ .setDataSourceType(configurationModel.getDataSourceType())
+ .setProcessingStage(configurationModel.getProcessingStage())
+ .setEtConnection(this.sessionState.connection).setFilePath(configurationModel.getDataSourcePath())
+ .setLCSimEventBuilder(this.sessionState.eventBuilder);
+
+ this.logger.config("data source path is " + configurationModel.getDataSourcePath());
+ this.logger.config("data source type is " + configurationModel.getDataSourceType());
+
+ // Set the max events.
if (configurationModel.hasValidProperty(ConfigurationModel.MAX_EVENTS_PROPERTY)) {
- long maxEvents = configurationModel.getMaxEvents();
+ final long maxEvents = configurationModel.getMaxEvents();
if (maxEvents > 0L) {
loopConfig.setMaxRecords(maxEvents);
}
}
// Add all Drivers from the JobManager.
- for (Driver driver : sessionState.jobManager.getDriverExecList()) {
+ for (final Driver driver : this.sessionState.jobManager.getDriverExecList()) {
loopConfig.add(driver);
- logger.config("added Driver " + driver.getName());
+ this.logger.config("added Driver " + driver.getName());
}
// Using ET server?
if (configurationModel.getDataSourceType().equals(DataSourceType.ET_SERVER)) {
// ET system monitor.
- logger.config("added EtSystemMonitor");
+ this.logger.config("added EtSystemMonitor");
loopConfig.add(new EtSystemMonitor());
// ET system strip charts.
- logger.config("added EtSystemStripCharts");
+ this.logger.config("added EtSystemStripCharts");
loopConfig.add(new EtSystemStripCharts());
}
// Add extra CompositeRecordProcessors to the loop config.
- for (CompositeRecordProcessor processor : sessionState.processors) {
+ for (final CompositeRecordProcessor processor : this.sessionState.processors) {
loopConfig.add(processor);
- logger.config("added extra processor " + processor.getClass().getSimpleName());
+ this.logger.config("added extra processor " + processor.getClass().getSimpleName());
}
// Add extra Drivers to the loop config.
- for (Driver driver : sessionState.drivers) {
+ for (final Driver driver : this.sessionState.drivers) {
loopConfig.add(driver);
- logger.config("added extra Driver " + driver.getName());
+ this.logger.config("added extra Driver " + driver.getName());
}
// Enable conditions system activation from EVIO event data in case the PRESTART is missed.
loopConfig.add(new EvioDetectorConditionsProcessor(configurationModel.getDetectorName()));
- logger.config("added EvioDetectorConditionsProcessor to job with detector " + configurationModel.getDetectorName());
+ this.logger.config("added EvioDetectorConditionsProcessor to job with detector "
+ + configurationModel.getDetectorName());
// Create the CompositeLoop with the configuration.
- sessionState.loop = new CompositeLoop(loopConfig);
-
- logger.config("record loop is setup");
- }
-
- /**
- * Setup a steering file on disk.
- * @param steering The steering file.
- */
- void setupSteeringFile(String steering) {
- sessionState.jobManager.setup(new File(steering));
- }
-
- /**
- * Setup a steering resource.
- * @param steering The steering resource.
- * @throws IOException if there is a problem setting up or accessing the resource.
- */
- void setupSteeringResource(String steering) throws IOException {
- InputStream is = this.getClass().getClassLoader().getResourceAsStream(steering);
- if (is == null)
+ this.sessionState.loop = new CompositeLoop(loopConfig);
+
+ this.logger.config("record loop is setup");
+ }
+
+ /**
+ * Setup XML steering from a file from disk.
+ *
+ * @param steering the steering file path
+ */
+ private void setupSteeringFile(final String steering) {
+ this.sessionState.jobManager.setup(new File(steering));
+ }
+
+ /**
+ * Setup XML steering from a jar resource.
+ *
+ * @param steering the steering resource
+ * @throws IOException if there is a problem accessing or setting up the resource
+ */
+ private void setupSteeringResource(final String steering) throws IOException {
+ final InputStream is = this.getClass().getClassLoader().getResourceAsStream(steering);
+ if (is == null) {
throw new IOException("Steering resource is not accessible or does not exist.");
- sessionState.jobManager.setup(is);
+ }
+ this.sessionState.jobManager.setup(is);
is.close();
}
+ /**
+ * Start event processing on a separate thread and also start the watchdog thread.
+ * <p>
+ * This method is called externally by the app to activate event processing after it is initialized and configured.
+ */
+ synchronized void start() {
+
+ this.logger.fine("event processing threads are starting");
+
+ // Start the event processing thread.
+ this.sessionState.processingThread = new EventProcessingThread(this.sessionState.loop);
+ this.sessionState.processingThread.start();
+
+ // Start the watch dog thread which will auto-disconnect when event processing is done.
+ this.sessionState.sessionWatchdogThread = new SessionWatchdogThread(this.sessionState.processingThread);
+ this.sessionState.sessionWatchdogThread.start();
+
+ this.logger.fine("started event processing threads");
+ }
+
+ /**
+ * Stop the current session, which will bring down the current ET client connection and activate end-of-job and
+ * end-of-run hooks on all registered event processors.
+ * <p>
+ * This method is called externally by the app to stop an event processing session e.g. from action event handling.
+ */
synchronized void stop() {
// Kill session watchdog thread.
- killWatchdogThread();
-
- // Wake up all ET stations to unblock the system and make sure secondary stations are detached.
- if (usingEtServer()) {
- wakeUpEtStations();
- }
-
- // Stop the event processing now that ET system is unblocked.
- logger.fine("sending STOP command to loop ...");
- sessionState.loop.execute(Command.STOP);
- logger.fine("loop got command STOP");
-
- // Cleanup the event processing thread since it was told to stop now.
+ this.killWatchdogThread();
+
+ // Wake up all ET stations to unblock the system and make sure stations are detached properly.
+ if (this.usingEtServer()) {
+ this.wakeUpEtStations();
+ }
+
+ // Stop the event processing now that ET system should be unblocked.
+ this.logger.finer("sending STOP command to loop ...");
+ this.sessionState.loop.execute(Command.STOP);
+ this.logger.finer("loop got STOP command");
+
+ this.logger.finer("processing thread is alive: " + this.sessionState.processingThread.isAlive());
+
try {
- logger.fine("waiting for event processing thread to end ...");
- sessionState.processingThread.join();
- logger.fine("event processing thread ended");
- } catch (InterruptedException e) {
+ // Give the event processing thread a chance to end cleanly.
+ this.logger.finer("waiting for event processing thread to end ...");
+ this.sessionState.processingThread.join(5000);
+ this.logger.finer("processing thread is alive: " + this.sessionState.processingThread.isAlive());
+ // this.logger.finer("event processing thread ended cleanly");
+ } catch (final InterruptedException e) {
e.printStackTrace();
}
+ try {
+ this.logger.finer("processing thread is alive: " + this.sessionState.processingThread.isAlive());
+ // In this case the thread needs to be interrupted and then joined.
+ this.logger.finer("interrupting event processing thread");
+ this.sessionState.processingThread.interrupt();
+ this.sessionState.processingThread.join();
+ this.logger.finer("event processing thread ended after interrupt");
+ } catch (final InterruptedException e) {
+ e.printStackTrace();
+ }
+
// Notify of last error that occurred in event processing.
- if (sessionState.loop.getLastError() != null) {
+ if (this.sessionState.loop.getLastError() != null) {
// Log the error.
- errorHandler.setError(sessionState.loop.getLastError()).log();
+ this.errorHandler.setError(this.sessionState.loop.getLastError()).log();
}
// Invalidate the loop.
- sessionState.loop = null;
+ this.sessionState.loop = null;
// Disconnect from the ET system.
- disconnect();
-
+ this.disconnect();
+
// Invalidate the event processing object so it is unusable now.
- invalidate();
- }
-
- /**
- * Wake up all ET stations associated with event processing.
- */
- void wakeUpEtStations() {
- if (sessionState.connection != null) {
- logger.fine("waking up ET stations ...");
+ this.invalidate();
+ }
+
+ /**
+ * Return <code>true</code> if using an ET server.
+ *
+ * @return <code>true</code> if using an ET server in the current session
+ */
+ private boolean usingEtServer() {
+ return this.sessionState.usingEtServer;
+ }
+
+ /**
+ * Wake up all ET stations associated with the event processing.
+ */
+ private void wakeUpEtStations() {
+ if (this.sessionState.connection != null) {
+ this.logger.fine("waking up ET stations ...");
// Wake up secondary ET stations.
- for (EtStationThread station : sessionState.stations) {
-
+ for (final EtStationThread station : this.sessionState.stations) {
+
// First unblock if in ET call.
station.wakeUp();
-
+
// Next interrupt so that it will definitely stop.
station.interrupt();
}
// Wait for station threads to die after being woken up.
- while (sessionState.stationThreadGroup.activeCount() != 0) {
- logger.finest("waiting for station threads to die ...");
- Object lock = new Object();
+ while (this.sessionState.stationThreadGroup.activeCount() != 0) {
+ this.logger.finest("waiting for station threads to die ...");
+ final Object lock = new Object();
synchronized (lock) {
try {
lock.wait(500);
- } catch (InterruptedException e) {
+ } catch (final InterruptedException e) {
e.printStackTrace();
}
}
}
-
- sessionState.stationThreadGroup.destroy();
-
- logger.finest("station threads destroyed");
+
+ this.sessionState.stationThreadGroup.destroy();
+
+ this.logger.finest("station threads destroyed");
// Wake up the primary ET station doing the event processing.
- logger.finest("waking up event processing station ...");
+ this.logger.finest("waking up event processing station ...");
try {
- sessionState.connection.getEtSystem().wakeUpAll(sessionState.connection.getEtStation());
- logger.finest("event processing station was woken up");
+ this.sessionState.connection.getEtSystem().wakeUpAll(this.sessionState.connection.getEtStation());
+ this.logger.finest("event processing station was woken up");
} catch (IOException | EtException | EtClosedException e) {
e.printStackTrace();
}
- logger.finest("ET stations all woken up");
- }
- }
-
- /**
- * Start event processing on the event processing thread and start the watchdog thread.
- */
- synchronized void start() {
-
- logger.fine("event processing threads are starting");
-
- // Start the event processing thread.
- sessionState.processingThread = new EventProcessingThread(sessionState.loop);
- sessionState.processingThread.start();
-
- // Start the watch dog thread which will auto-disconnect when event processing is done.
- sessionState.sessionWatchdogThread = new SessionWatchdogThread(sessionState.processingThread);
- sessionState.sessionWatchdogThread.start();
-
- logger.fine("started event processing threads");
- }
-
- /**
- * Notify the event processor to pause processing.
- */
- synchronized void pause() {
- logger.finest("pausing");
- if (!connectionModel.getPaused()) {
- sessionState.loop.pause();
- connectionModel.setPaused(true);
- }
- logger.finest("paused");
- }
-
- /**
- * Get next event if in pause mode.
- */
- synchronized void next() {
- logger.finest("getting next event");
- if (connectionModel.getPaused()) {
- connectionModel.setPaused(false);
- sessionState.loop.execute(Command.GO_N, 1L, true);
- connectionModel.setPaused(true);
- }
- logger.finest("got next event");
- }
-
- /**
- * Resume processing events from pause mode.
- */
- synchronized void resume() {
- logger.finest("resuming");
- if (connectionModel.getPaused()) {
- // Notify event processor to continue.
- sessionState.loop.resume();
- connectionModel.setPaused(false);
- }
- logger.finest("resumed");
- }
-
- /**
- * Interrupt and join to the processing watchdog thread.
- */
- synchronized void killWatchdogThread() {
- // Is the session watchdog thread not null?
- if (sessionState.sessionWatchdogThread != null) {
- logger.finest("killing watchdog thread ...");
- // Is the thread still alive?
- if (sessionState.sessionWatchdogThread.isAlive()) {
- // Interrupt the thread which should cause it to stop.
- sessionState.sessionWatchdogThread.interrupt();
- try {
- // This should always work once the thread is interrupted.
- sessionState.sessionWatchdogThread.join();
- } catch (InterruptedException e) {
- // This should never happen.
- e.printStackTrace();
- }
- }
- // Set the thread object to null.
- sessionState.sessionWatchdogThread = null;
- logger.finest("watchdog thread killed");
- }
- }
-
- /**
- * Cleanup the ET connection.
- */
- synchronized void closeEtConnection() {
- if (sessionState.connection != null) {
- logger.fine("closing ET connection");
- if (sessionState.connection.getEtSystem().alive()) {
- logger.finest("cleaning up the connection ...");
- sessionState.connection.cleanup();
- logger.finest("connection cleanup successful");
- }
- sessionState.connection = null;
- logger.fine("ET connection closed");
- }
- }
-
- /**
- * True if the processing thread is valid and active.
- * @return True if processing thread is active.
- */
- boolean isActive() {
- return sessionState.processingThread != null && sessionState.processingThread.isAlive();
- }
-
- /**
- * Connect to the ET system using the current connection settings.
- */
- synchronized void connect() throws IOException {
- // Setup the network connection if using an ET server.
- if (usingEtServer()) {
- // Create a connection to the ET server.
- try {
- logger.fine("connecting to ET system ...");
-
- // Create the main ET system connection.
- createEtConnection();
-
- // Add an attachment that listens for DAQ configuration changes via physics SYNC events.
- //createSyncStation();
-
- // Add an attachment which listens for EPICs events with scalar data.
- //createEpicsStation();
-
- // Add an attachment that listens for PRESTART events.
- //createPreStartStation();
-
- } catch (Exception e) {
- throw new IOException(e);
- }
-
- logger.fine("ET system is connected");
- } else {
- // This is when a direct file source is used and ET is not needed.
- connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED);
- }
-
- }
-
- /**
- * True if using an ET server.
- * @return True if using an ET server.
- */
- boolean usingEtServer() {
- return sessionState.usingEtServer;
- }
-
- /**
- * Create a connection to an ET system using current parameters from the GUI.
- */
- synchronized void createEtConnection() {
- // Setup connection to ET system.
- sessionState.connection = EtSystemUtil.createEtConnection(configurationModel);
-
- if (sessionState.connection != null) {
- // Set status to connected as there is now a live ET connection.
- connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED);
- } else {
- errorHandler.setError(new RuntimeException("Failed to create ET connection.")).log().printStackTrace().raiseException();
- }
- }
-
- /**
- * Create the select array from event selection in ET stations.
- * @return The select array.
- */
- static int[] createSelectArray() {
- int select[] = new int[EtConstants.stationSelectInts];
- Arrays.fill(select, -1);
- return select;
- }
-
- /**
- * Create a station that listens for physics sync events
- * containing DAQ configuration.
- */
- void createSyncStation() {
-
- // Sync events have bits 6 and 7 set.
- int syncEventType = 0;
- syncEventType = syncEventType ^ (1 << 6);
- syncEventType = syncEventType ^ (1 << 7);
- int select[] = createSelectArray();
- select[1] = syncEventType;
-
- createStationThread(
- new SyncEventProcessor(),
- "SYNC",
- 1,
- select);
- }
-
- /**
- * Create a station that listens for PRESTART events
- * to initialize the conditions system.
- */
- void createPreStartStation() {
-
- // Select only PRESTART events.
- int[] select = createSelectArray();
- select[0] = EvioEventConstants.PRESTART_EVENT_TAG;
-
- createStationThread(
- new PreStartProcessor(configurationModel.getDetectorName()),
- "PRESTART",
- 1,
- select);
- }
-
- /**
- * Create a station that listens for EPICS control events (currently not activated).
- */
- void createEpicsStation() {
-
- // Select only EPICS events.
- int[] select = createSelectArray();
- select[0] = EvioEventConstants.EPICS_EVENT_TAG;
-
- createStationThread(
- new EpicsEtProcessor(),
- "EPICS",
- 1,
- select);
- }
-
- /**
- * Create an ET station thread.
- * @param processor The event processor to run on the thread.
- * @param nameAppend The string to append for naming this station.
- * @param stationPosition The position of the station.
- * @param select The event selection data array.
- */
- void createStationThread(EtEventProcessor processor, String nameAppend, int stationPosition, int[] select) {
- EtStationThread stationThread = new EtStationThread(
- processor,
- sessionState.connection.getEtSystem(),
- sessionState.connection.getEtStation().getName() + "_" + nameAppend,
- stationPosition,
- select);
- new Thread(sessionState.stationThreadGroup, stationThread).start();
- sessionState.stations.add(stationThread);
- logger.config("started ET station " + nameAppend);
- StringBuffer sb = new StringBuffer();
- for (int word : select) {
- sb.append(word + " ");
- }
- logger.config("station has select array: " + sb.toString());
- }
-
- /**
- * Disconnect from the current ET session.
- * @param status The connection status.
- */
- synchronized void disconnect() {
-
- // Cleanup the ET connection.
- if (usingEtServer()) {
- closeEtConnection();
- }
-
- // Change application state to disconnected.
- connectionModel.setConnectionStatus(ConnectionStatus.DISCONNECTED);
- }
-
- /**
- * This class notifies the application to disconnect if the event processing thread completes.
- */
- class SessionWatchdogThread extends Thread {
-
- Thread processingThread;
-
- SessionWatchdogThread(Thread processingThread) {
- this.processingThread = processingThread;
- }
-
- public void run() {
- try {
- // This thread waits on the event processing thread to die.
- processingThread.join();
-
- // Activate a disconnect using the ActionEvent which is used by the disconnect button.
- logger.finest("processing thread ended so automatic disconnect is happening");
- application.actionPerformed(new ActionEvent(Thread.currentThread(), 0, Commands.DISCONNECT));
-
- } catch (InterruptedException e) {
- logger.finest("SessionWatchdogThread got interrupted");
- // This happens when the thread is interrupted by the user pressing the disconnect button.
- }
- }
- }
-
- /**
- * Invalidate all
- */
- void invalidate() {
-
- application = null;
- logger = null;
- configurationModel = null;
- connectionModel = null;
- errorHandler = null;
-
- sessionState.conditionsListeners = null;
- sessionState.drivers = null;
- sessionState.processors = null;
- sessionState.jobManager = null;
- sessionState.eventBuilder = null;
- sessionState.loop = null;
- sessionState.processingThread = null;
- sessionState.sessionWatchdogThread = null;
- sessionState.stationThreadGroup = null;
- sessionState.stations = null;
- sessionState.connection = null;
-
- sessionState = null;
+ this.logger.finest("ET stations all woken up");
+ }
}
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/FieldPanel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/FieldPanel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/FieldPanel.java Tue Apr 21 14:48:39 2015
@@ -3,81 +3,138 @@
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JTextField;
+import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
/**
* A panel with a label and a text field.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
+@SuppressWarnings("serial")
class FieldPanel extends JPanel {
- String fieldName;
- String defaultValue;
- JTextField field;
+ /**
+ * The default component border.
+ */
+ private static final Border DEFAULT_BORDER = BorderFactory.createLoweredBevelBorder();
- static Border border = BorderFactory.createLoweredBevelBorder();
+ /**
+ * The component with the field value.
+ */
+ private final JTextField field;
- FieldPanel(String fieldName, String defaultValue, int size, boolean editable) {
+ /**
+ * Class constructor.
+ *
+ * @param fieldName the name of the field for the label
+ * @param defaultValue the default value
+ * @param size the size of the field
+ * @param editable <code>true</code> if field is editable
+ */
+ protected FieldPanel(final String fieldName, final String defaultValue, final int size, final boolean editable) {
- this.fieldName = fieldName;
- this.defaultValue = defaultValue;
-
- TitledBorder title = BorderFactory.createTitledBorder(border, fieldName);
+ final TitledBorder title = BorderFactory.createTitledBorder(DEFAULT_BORDER, fieldName);
title.setTitleJustification(TitledBorder.LEFT);
- field = new JTextField(defaultValue, size);
- field.setHorizontalAlignment(JTextField.RIGHT);
- field.setEditable(editable);
- field.setBorder(title);
- add(field);
+ this.field = new JTextField(defaultValue, size);
+ this.field.setHorizontalAlignment(SwingConstants.RIGHT);
+ this.field.setEditable(editable);
+ this.field.setBorder(title);
+ add(this.field);
}
- void setValue(final String value) {
+ /**
+ * Get a <code>Double</code> value from the field.
+ *
+ * @return the <code>Double</code> value
+ */
+ final Double getDoubleValue() {
+ return Double.parseDouble(getValue());
+ }
+
+ /**
+ * Get an <code>Integer</code> value from the field.
+ *
+ * @return the <code>Integer</code> value
+ */
+ final Integer getIntegerValue() {
+ return Integer.parseInt(getValue());
+ }
+
+ /**
+ * Get a <code>Long</code> value from the field.
+ *
+ * @return the <code>Long</code> value
+ */
+ final Long getLongValue() {
+ return Long.parseLong(getValue());
+ }
+
+ /**
+ * Get the <code>String</code> value from the field.
+ *
+ * @return the <code>String</code> value from the field
+ */
+ final String getValue() {
+ return this.field.getText();
+ }
+
+ /**
+ * Set the field value from a <code>double</code>.
+ *
+ * @param value the <code>double</code> value
+ */
+ final void setValue(final double value) {
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
- field.setText(value);
+ FieldPanel.this.field.setText(new Double(value).toString());
}
});
}
- void setValue(final int value) {
+ /**
+ * Set the field value from an <code>int</code>.
+ *
+ * @param value the <code>int</code> value
+ */
+ final void setValue(final int value) {
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
- field.setText(new Integer(value).toString());
+ FieldPanel.this.field.setText(new Integer(value).toString());
}
});
}
- void setValue(final double value) {
+ /**
+ * Set the field value from a <code>long</code>.
+ *
+ * @param value the <code>long</code> value
+ */
+ final void setValue(final long value) {
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
- field.setText(new Double(value).toString());
+ FieldPanel.this.field.setText(new Long(value).toString());
}
});
}
- void setValue(final long value) {
+ /**
+ * Set the field value from a <code>String</code>.
+ *
+ * @param value the <code>String</code> value
+ */
+ void setValue(final String value) {
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
- field.setText(new Long(value).toString());
+ FieldPanel.this.field.setText(value);
}
});
}
-
- String getValue() {
- return field.getText();
- }
-
- Integer getIntegerValue() {
- return Integer.parseInt(getValue());
- }
-
- Double getDoubleValue() {
- return Double.parseDouble(getValue());
- }
-
- Long getLongValue() {
- return Long.parseLong(getValue());
- }
-}
+}
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 Apr 21 14:48:39 2015
@@ -28,400 +28,502 @@
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 settings via a
+ * {@link org.hps.monitoring.model.ConfigurationModel} object.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-// 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()
- };
+@SuppressWarnings("serial")
+final class JobSettingsPanel extends AbstractFieldsPanel {
+
+ /**
+ * This filter will accept only files called compact.xml which should be an LCSim detector description file.
+ */
+ static class CompactFileFilter extends FileFilter {
+
+ /**
+ * Class constructor.
+ */
+ public CompactFileFilter() {
+ }
+
+ /**
+ * Returns <code>true</code> if the path passes the filter.
+ *
+ * @return <code>true</code> if the path passes the filter
+ */
+ @Override
+ public boolean accept(final File pathname) {
+ return "compact.xml".equals(pathname.getName());
+ }
+
+ /**
+ * Get the description of the filter.
+ *
+ * @return the description of the filter
+ */
+ @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 {
+
+ /**
+ * Handle {@link java.beans.PropertyChangeEvent} by updating the GUI from changes to the model.
+ *
+ * @param evt the {@link java.beans.PropertyChangeEvent} to handle
+ */
+ @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.setSelectedItem(value);
+ } 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.
+ */
+ private static final String STEERING_PACKAGE = "org/hps/steering/monitoring/";
+
+ /**
+ * Field for name of remote AIDA server.
+ */
+ private final JTextField aidaServerNameField;
+
+ /**
+ * Combo box for selecting a conditions system tag.
+ */
+ private final JComboBox<String> conditionsTagComboBox;
+
+ /**
+ * Field setting a detector alias to a local file.
+ */
+ private final JTextField detectorAliasField;
+
+ /**
+ * Combo box for selecting a detector model.
+ */
+ private final JComboBox<String> detectorNameComboBox;
+
+ /**
+ * Check box for enabling disconnect on end run.
+ */
+ private final JCheckBox disconnectOnEndRunCheckBox;
+
+ /**
+ * Check box for enabling disconnect on event processing errors.
+ */
+ private final JCheckBox disconnectOnErrorCheckBox;
+
+ /**
+ * Combo box for selecting the event builder class.
+ */
+ private final JComboBox<String> eventBuilderComboBox;
+
+ /**
+ * Check box for freezing conditions system provided there is a user selected run number and detector.
+ */
+ private final JCheckBox freezeConditionsCheckBox;
+
+ /**
+ * Field for specifying an output log file.
+ */
+ private final JTextField logFileNameField;
+
+ /**
+ * Field for setting the log level.
+ */
+ private final JComboBox<?> logLevelComboBox;
+
+ /**
+ * Check box for enabling logging to a file.
+ */
+ private final JCheckBox logToFileCheckbox;
+
+ /**
+ * Field for setting the maximum number of events to process in the session.
+ */
+ private final JTextField maxEventsField;
+
+ /**
+ * Combo box for selecting the processing stage(s) to execute (ET, EVIO or LCIO).
+ */
+ private final JComboBox<ProcessingStage> processingStageComboBox;
+
+ /**
+ * Field for setting an XML steering file.
+ */
+ private final JTextField steeringFileField;
+
+ /**
+ * Combo box for selecting a steering file resource.
+ */
+ private final JComboBox<?> steeringResourcesComboBox;
+
+ /**
+ * Combo box for selecting between current file or resource for XML steering.
+ */
+ private final JComboBox<SteeringType> steeringTypeComboBox;
+
+ /**
+ * Field for setting a user run number for conditions system activation.
+ */
+ private final JTextField userRunNumberField;
/**
* Class constructor.
- */
- JobSettingsPanel(ConfigurationModel model) {
+ *
+ * @param model the current {@link org.hps.monitoring.application.model.ConfigurationModel} with global
+ * configuration
+ */
+ @SuppressWarnings("unchecked")
+ JobSettingsPanel(final ConfigurationModel model) {
super(new Insets(5, 3, 3, 5), true);
-
- setBorder(new EmptyBorder(10, 10, 10, 10));
-
- setLayout(new GridBagLayout());
-
+
+ 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);
- 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");
+ 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);
-
- 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");
+
+ this.steeringTypeComboBox = this.addComboBox("Steering Type", SteeringType.values());
+ 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);
- 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);
- }
-
+ 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);
+ }
+
+ /**
+ * Handle {@link java.awt.event.ActionEvent} objects by pushing changes from the GUI into the model.
+ *
+ * @param event the {@link java.awt.event.ActionEvent} to handle
+ */
@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();
+ 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(this.steeringTypeComboBox.getSelectedItem().toString());
+ } else if (Commands.STEERING_RESOURCE_CHANGED.equals(command)) {
+ this.getConfigurationModel().setSteeringResource(
+ this.steeringResourcesComboBox.getSelectedItem().toString());
+ } 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(
+ this.processingStageComboBox.getSelectedItem().toString());
+ }
+ } finally {
+ this.getConfigurationModel().addPropertyChangeListener(this);
+ }
+ }
+
+ /**
+ * Attaches the ActionListener from the main application to specific GUI components in this class.
+ *
+ * @param the {@link java.awt.event.ActionListener} to register with the relevant components
+ */
+ @Override
+ public void addActionListener(final ActionListener listener) {
+ this.steeringResourcesComboBox.addActionListener(listener);
+ this.freezeConditionsCheckBox.addActionListener(listener);
+ }
+
+ /**
+ * Parse the LCSim XML steering file to see if it looks valid.
+ *
+ * @param file the input steering file
+ * @throws IOException if there is a basic IO problem like reading the file
+ * @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 (!"lcsim".equals(rootNode.getName())) {
+ 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.
+ */
+ private void chooseCompactFile() {
+ final JFileChooser fc = new JFileChooser();
+ fc.setDialogTitle("Choose a Compact XML File");
+ fc.setCurrentDirectory(new File("."));
+ fc.setFileFilter(new CompactFileFilter());
+ final int r = fc.showDialog(this, "Select ...");
+ if (r == JFileChooser.APPROVE_OPTION) {
+ final File file = fc.getSelectedFile();
+ this.getConfigurationModel().setDetectorAlias(file.getParent());
+ }
+ }
+
+ /**
+ * Choose an LCSim steering file.
+ */
+ private void chooseSteeringFile() {
+ final JFileChooser fc = new JFileChooser();
fc.setDialogTitle("Choose an LCSim Steering File");
fc.setCurrentDirectory(new File("."));
- int r = fc.showDialog(this, "Select ...");
+ final int r = fc.showDialog(this, "Select ...");
if (r == JFileChooser.APPROVE_OPTION) {
- File file = fc.getSelectedFile();
+ final File file = fc.getSelectedFile();
try {
- checkSteeringFile(file);
- configurationModel.setSteeringFile(file.getCanonicalPath());
- configurationModel.setSteeringType(SteeringType.FILE);
+ this.checkSteeringFile(file);
+ this.getConfigurationModel().setSteeringFile(file.getCanonicalPath());
+ this.getConfigurationModel().setSteeringType(SteeringType.FILE.toString());
} 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.
- */
- static class CompactFileFilter extends FileFilter {
-
- public CompactFileFilter() {
- }
-
- @Override
- public boolean accept(File pathname) {
- if (pathname.getName().equals("compact.xml")) {
- return true;
- } else {
- return false;
- }
- }
-
- @Override
- public String getDescription() {
- return "Compact XML files";
- }
- }
-
-
- /**
- * Choose a compact XML file to override the one embedded in the jar as a resource.
- */
- void chooseCompactFile() {
- 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 ...");
- 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());
- }
- }
-
+
+ /**
+ * 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);
+ }
+ }
+
+ /**
+ * Sets the {@link org.hps.monitoring.application.model.ConfigurationModel} for the component containing global
+ * configuration.
+ * <p>
+ * The job settings will be updated automatically if the model changes.
+ *
+ * @param the {@link org.hps.monitoring.application.model.ConfigurationModel} for the component
+ */
@Override
- public void setConfigurationModel(ConfigurationModel model) {
+ public void setConfigurationModel(final ConfigurationModel model) {
super.setConfigurationModel(model);
model.addPropertyChangeListener(new JobSettingsChangeListener());
}
-}
+}
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 Apr 21 14:48:39 2015
@@ -14,62 +14,74 @@
/**
* This is a combo box used to filter the log table messages by level.
- * @author Jeremy McCormick <[log in to unmask]>
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class LogLevelFilterComboBox extends JComboBox<Level> implements ActionListener, PropertyChangeListener {
-
- ConfigurationModel configurationModel;
-
- static final Level[] LOG_LEVELS = new Level[] {
- Level.ALL,
- Level.FINEST,
- Level.FINER,
- Level.FINE,
- Level.CONFIG,
- Level.INFO,
- Level.WARNING,
- Level.SEVERE
- };
-
- LogLevelFilterComboBox(ConfigurationModel configurationModel) {
-
+@SuppressWarnings("serial")
+final class LogLevelFilterComboBox extends JComboBox<Level> implements ActionListener, PropertyChangeListener {
+
+ /**
+ * Available log levels.
+ */
+ private static final Level[] LOG_LEVELS = new Level[] { Level.ALL, Level.FINEST, Level.FINER, Level.FINE,
+ Level.CONFIG, Level.INFO, Level.WARNING, Level.SEVERE };
+
+ /**
+ * The {@link org.hps.monitoring.application.model.ConfigurationModel} providing the backing model.
+ */
+ private final ConfigurationModel configurationModel;
+
+ /**
+ * Class constructor.
+ *
+ * @param configurationModel the {@link org.hps.monitoring.application.model.ConfigurationModel} providing the
+ * backing model
+ */
+ LogLevelFilterComboBox(final ConfigurationModel configurationModel) {
+
configurationModel.addPropertyChangeListener(this);
- this.configurationModel = configurationModel;
-
+ this.configurationModel = configurationModel;
+
setModel(new DefaultComboBoxModel<Level>(LOG_LEVELS));
setPrototypeDisplayValue(Level.WARNING);
- setSelectedItem(Level.ALL);
+ setSelectedItem(Level.ALL);
setActionCommand(Commands.LOG_LEVEL_FILTER_CHANGED);
addActionListener(this);
setPreferredSize(new Dimension(100, getPreferredSize().height));
setSize(new Dimension(100, getPreferredSize().height));
- }
-
+ }
+
/**
- * Push change in log level filtering to the configuration model.
+ * The {@link java.awt.event.ActionEvent} handling, which is used to push changes to the global data model.
+ *
+ * @param event the {@link java.awt.event.ActionEvent} object
*/
- public void actionPerformed(ActionEvent event) {
+ @Override
+ public void actionPerformed(final ActionEvent event) {
if (event.getActionCommand().equals(Commands.LOG_LEVEL_FILTER_CHANGED)) {
- configurationModel.removePropertyChangeListener(this);
- try {
- configurationModel.setLogLevelFilter((Level) getSelectedItem());
+ this.configurationModel.removePropertyChangeListener(this);
+ try {
+ this.configurationModel.setLogLevelFilter((Level) getSelectedItem());
} finally {
- configurationModel.addPropertyChangeListener(this);
+ this.configurationModel.addPropertyChangeListener(this);
}
}
}
-
+
/**
- * Get change in log level filtering from the configuration model.
+ * The {@link java.beans.PropertyChangeEvent} handling, which is used to get changes from the model into the GUI.
+ *
+ * @param event the {@link java.beans.PropertyChangeEvent} object to handle
*/
- public void propertyChange(PropertyChangeEvent event) {
+ @Override
+ public void propertyChange(final PropertyChangeEvent event) {
if (event.getPropertyName().equals(ConfigurationModel.LOG_LEVEL_FILTER_PROPERTY)) {
- Level newLevel = (Level) event.getNewValue();
- configurationModel.removePropertyChangeListener(this);
+ final Level newLevel = (Level) event.getNewValue();
+ this.configurationModel.removePropertyChangeListener(this);
try {
setSelectedItem(newLevel);
} finally {
- configurationModel.addPropertyChangeListener(this);
+ this.configurationModel.addPropertyChangeListener(this);
}
}
}
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 Apr 21 14:48:39 2015
@@ -15,46 +15,67 @@
/**
* This is a simple GUI component for the log table and its controls.
- * @author Jeremy McCormick <[log in to unmask]>
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class LogPanel extends JPanel{
+@SuppressWarnings("serial")
+final class LogPanel extends JPanel {
- LogTable logTable;
- LogLevelFilterComboBox logFilterComboBox;
-
- ConfigurationModel configurationModel;
-
- LogPanel(ConfigurationModel configurationModel, ActionListener listener) {
-
- this.configurationModel = configurationModel;
-
+ /**
+ * The combo box for filtering which messages are currently showing in the table.
+ */
+ private final LogLevelFilterComboBox logFilterComboBox;
+
+ /**
+ * The table containing the log messages.
+ */
+ private final LogTable logTable;
+
+ /**
+ * Class constructor.
+ *
+ * @param configurationModel the {@link org.hps.monitoring.application.model.ConfigurationModel} providing the data
+ * model
+ * @param listener an {@link java.awt.event.ActionListener} to register on certain components
+ */
+ LogPanel(final ConfigurationModel configurationModel, final ActionListener listener) {
+
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
-
- logTable = new LogTable(configurationModel);
-
- JPanel controlsPanel = new JPanel();
+
+ this.logTable = new LogTable(configurationModel);
+
+ final JPanel controlsPanel = new JPanel();
controlsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 5));
-
- JLabel label = new JLabel("Log Level Filter");
- logFilterComboBox = new LogLevelFilterComboBox(configurationModel);
- logFilterComboBox.setToolTipText("Messages below this level will be filtered out.");
- controlsPanel.add(label);
- controlsPanel.add(logFilterComboBox);
-
- JButton exportButton = new JButton("Export ...");
+
+ final JLabel label = new JLabel("Log Level Filter");
+ this.logFilterComboBox = new LogLevelFilterComboBox(configurationModel);
+ this.logFilterComboBox.setToolTipText("Messages below this level will be filtered out.");
+ controlsPanel.add(label);
+ controlsPanel.add(this.logFilterComboBox);
+
+ final JButton exportButton = new JButton("Export ...");
exportButton.setActionCommand(Commands.SAVE_LOG_TABLE);
exportButton.addActionListener(listener);
controlsPanel.add(exportButton);
-
- JButton clearButton = new JButton("Clear");
+
+ final JButton clearButton = new JButton("Clear");
clearButton.setActionCommand(Commands.CLEAR_LOG_TABLE);
clearButton.addActionListener(listener);
controlsPanel.add(clearButton);
-
- JScrollPane tablePane = new JScrollPane(logTable);
+
+ final JScrollPane tablePane = new JScrollPane(this.logTable);
controlsPanel.setMaximumSize(new Dimension(tablePane.getPreferredSize().width, 200));
-
+
add(controlsPanel, BorderLayout.PAGE_START);
add(tablePane, BorderLayout.PAGE_END);
- }
+ }
+
+ /**
+ * Get the log table.
+ *
+ * @return the log table
+ */
+ LogTable getLogTable() {
+ return this.logTable;
+ }
}
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 Apr 21 14:48:39 2015
@@ -18,79 +18,144 @@
import org.hps.monitoring.application.model.ConfigurationModel;
/**
- * This is a simple Swing component for the table of log messages.
- * @author Jeremy McCormick <[log in to unmask]>
+ * This is a simple {@link avax.swing.JTable} component for displaying log messages.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class LogTable extends JTable implements PropertyChangeListener {
-
- static final String[] COLUMN_NAMES = { "Date", "Level", "Message" };
-
- LogRecordModel model;
- TableRowSorter<LogRecordModel> sorter;
-
- Level filterLevel = Level.ALL;
-
- final static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-
- LogTable(ConfigurationModel configurationModel) {
- configurationModel.addPropertyChangeListener(this);
- model = new LogRecordModel();
- setModel(model);
- sorter = new TableRowSorter<LogRecordModel>(model);
- sorter.setRowFilter(new LevelFilter());
- getColumnModel().getColumn(0).setCellRenderer(new DateRenderer());
- setRowSorter(sorter);
- getColumnModel().getColumn(0).setPreferredWidth(142);
- getColumnModel().getColumn(0).setMaxWidth(142);
- getColumnModel().getColumn(1).setPreferredWidth(60);
- getColumnModel().getColumn(1).setMaxWidth(60);
- setEnabled(false);
- }
-
+@SuppressWarnings("serial")
+final class LogTable extends JTable implements PropertyChangeListener {
+
+ /**
+ * The table cell renderer for displaying dates.
+ */
static class DateRenderer extends DefaultTableCellRenderer {
- public void setValue(Object value) {
- setText((value == null) ? "" : formatter.format(value));
- }
- }
-
- class LevelFilter extends RowFilter<LogRecordModel, Integer> {
-
- public boolean include(Entry<? extends LogRecordModel, ? extends Integer> entry) {
- LogRecordModel model = entry.getModel();
- LogRecord record = model.get(entry.getIdentifier());
- if (record.getLevel().intValue() >= filterLevel.intValue()) {
+ @Override
+ public void setValue(final Object value) {
+ setText(value == null ? "" : DATE_FORMAT.format(value));
+ }
+ }
+
+ /**
+ * A filter which determines what level of messages to display in the table.
+ */
+ private class LevelFilter extends RowFilter<LogRecordModel, Integer> {
+
+ /**
+ * Return <code>true</code> to display the entry.
+ *
+ * @param entry the table entry (model with a row ID)
+ */
+ @Override
+ public boolean include(final Entry<? extends LogRecordModel, ? extends Integer> entry) {
+ final LogRecordModel model = entry.getModel();
+ final LogRecord record = model.get(entry.getIdentifier());
+ if (record.getLevel().intValue() >= LogTable.this.filterLevel.intValue()) {
return true;
}
return false;
}
}
-
- static class LogRecordModel extends AbstractTableModel {
-
- List<LogRecord> records = new ArrayList<LogRecord>();
-
- LogRecord get(Integer rowIndex) {
- return records.get(rowIndex);
- }
-
- void add(LogRecord record) {
- records.add(record);
+
+ /**
+ * The table model implementation.
+ */
+ static class LogRecordModel extends AbstractTableModel {
+
+ /**
+ * The list of {@link java.util.logging.LogRecord} objects to display in the table.
+ */
+ private final List<LogRecord> records = new ArrayList<LogRecord>();
+
+ /**
+ * Add a new {@link java.util.logging.LogRecord} object to the table.
+ *
+ * @param record the new {@link java.util.logging.LogRecord} object
+ */
+ void add(final LogRecord record) {
+ this.records.add(record);
fireTableDataChanged();
}
- @Override
- public int getRowCount() {
- return records.size();
- }
-
+ /**
+ * Clear all the records from the table.
+ */
+ void clear() {
+ this.records.clear();
+ fireTableDataChanged();
+ }
+
+ /**
+ * Get a record by its index.
+ *
+ * @param rowIndex the row index
+ * @return the {@link java.util.logging.LogRecord} object
+ * @throws IndexOutOfBoundsException if rowIndex is invalid
+ */
+ private LogRecord get(final Integer rowIndex) {
+ return this.records.get(rowIndex);
+ }
+
+ /**
+ * Get the class of a column.
+ *
+ * @param columnIndex the column's index
+ * @return the column's class
+ */
+ @Override
+ public Class<?> getColumnClass(final int columnIndex) {
+ switch (columnIndex) {
+ case 0:
+ return Date.class;
+ case 1:
+ return Level.class;
+ case 2:
+ return String.class;
+ default:
+ return Object.class;
+ }
+ }
+
+ /**
+ * Get the number of columns.
+ *
+ * @return the number of columns
+ */
@Override
public int getColumnCount() {
return COLUMN_NAMES.length;
}
- @Override
- public Object getValueAt(int rowIndex, int columnIndex) {
- LogRecord record = records.get(rowIndex);
+ /**
+ * Get the column name.
+ *
+ * @param columnIndex the column index
+ * @return the name of the column
+ */
+ @Override
+ public String getColumnName(final int columnIndex) {
+ return COLUMN_NAMES[columnIndex];
+ }
+
+ /**
+ * Get the number of rows.
+ *
+ * @return the number of rows
+ */
+ @Override
+ public int getRowCount() {
+ return this.records.size();
+ }
+
+ /**
+ * Get a cell value from the table.
+ *
+ * @param rowIndex the row index
+ * @param column the column index
+ * @return the cell value or <code>null</code> if does not exist (e.g. invalid column number)
+ */
+ @Override
+ public Object getValueAt(final int rowIndex, final int columnIndex) {
+ final LogRecord record = this.get(rowIndex);
switch (columnIndex) {
case 0:
return new Date(record.getMillis());
@@ -102,39 +167,70 @@
return null;
}
}
-
- @Override
- public Class<?> getColumnClass(int columnIndex) {
- switch (columnIndex) {
- case 0:
- return Date.class;
- case 1:
- return Level.class;
- case 2:
- return String.class;
- default:
- return Object.class;
- }
- }
-
- @Override
- public String getColumnName(int columnIndex) {
- return COLUMN_NAMES[columnIndex];
- }
-
- void clear() {
- records.clear();
- fireTableDataChanged();
- }
+ }
+
+ /**
+ * The column names.
+ */
+ static final String[] COLUMN_NAMES = { "Date", "Level", "Message" };
+
+ /**
+ * Date formatting.
+ */
+ private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ /**
+ * The current filtering level.
+ */
+ private Level filterLevel = Level.ALL;
+
+ /**
+ * The backing table model.
+ */
+ private final LogRecordModel model;
+
+ /**
+ * The table sorer.
+ */
+ private final TableRowSorter<LogRecordModel> sorter;
+
+ /**
+ * Class constructor.
+ *
+ * @param configurationModel the {@link org.hps.monitoring.application.model.ConfigurationModel} for the application
+ */
+ LogTable(final ConfigurationModel configurationModel) {
+ configurationModel.addPropertyChangeListener(this);
+ this.model = new LogRecordModel();
+ setModel(this.model);
+ this.sorter = new TableRowSorter<LogRecordModel>(this.model);
+ this.sorter.setRowFilter(new LevelFilter());
+ getColumnModel().getColumn(0).setCellRenderer(new DateRenderer());
+ setRowSorter(this.sorter);
+ getColumnModel().getColumn(0).setPreferredWidth(142);
+ getColumnModel().getColumn(0).setMaxWidth(142);
+ getColumnModel().getColumn(1).setPreferredWidth(60);
+ getColumnModel().getColumn(1).setMaxWidth(60);
+ setEnabled(false);
+ }
+
+ /**
+ * Get the table model.
+ *
+ * @return the table model
+ */
+ LogRecordModel getLogRecordModel() {
+ return this.model;
}
/**
* Get change in log level filtering from the configuration model.
*/
- public void propertyChange(PropertyChangeEvent event) {
+ @Override
+ public void propertyChange(final PropertyChangeEvent event) {
if (event.getPropertyName().equals(ConfigurationModel.LOG_LEVEL_FILTER_PROPERTY)) {
- filterLevel = (Level) event.getNewValue();
- model.fireTableDataChanged();
- }
- }
+ this.filterLevel = (Level) event.getNewValue();
+ this.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 Apr 21 14:48:39 2015
@@ -12,42 +12,55 @@
import org.hps.monitoring.application.model.Configuration;
/**
- * This is the front-end for running the monitoring app via a {@link #main(String[])} method.
+ * This is the front-end for running the monitoring application via a {@link #main(String[])} method.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
public final class Main {
- private Main() {
- }
-
- public static void main(String[] args) {
-
+ /**
+ * The main method which starts the monitoring application, which is how users should start the application.
+ *
+ * @param args the command line arguments
+ */
+ public static void main(final String[] args) {
+
// Set up command line parsing.
- Options options = new Options();
+ final Options options = new Options();
options.addOption(new Option("h", false, "Print help."));
options.addOption(new Option("c", true, "Load a properties file with configuration parameters."));
- CommandLineParser parser = new PosixParser();
-
+ final CommandLineParser parser = new PosixParser();
+
// Parse command line arguments.
final CommandLine cl;
try {
cl = parser.parse(options, args);
- } catch (ParseException e) {
+ } catch (final ParseException e) {
throw new RuntimeException("Problem parsing command line options.", e);
}
// Print help and exit.
if (cl.hasOption("h")) {
- HelpFormatter help = new HelpFormatter();
+ final HelpFormatter help = new HelpFormatter();
help.printHelp(" ", options);
System.exit(1);
}
-
+
// Load the connection settings.
Configuration configuration = null;
if (cl.hasOption("c")) {
configuration = new Configuration(new File(cl.getOptionValue("c")));
- }
-
+ }
+
MonitoringApplication.create(configuration);
- }
-}
+ }
+
+ /**
+ * Class constructor, which should not be used.
+ * <p>
+ * Call the {@link #main(String[])} method instead.
+ */
+ private Main() {
+ throw new UnsupportedOperationException("Do not instantiate this class.");
+ }
+}
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 Apr 21 14:48:39 2015
@@ -18,116 +18,173 @@
/**
* This is the primary menu bar for the monitoring application.
- *
- * @author Jeremy McCormick <[log in to unmask]>
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
@SuppressWarnings("serial")
-class MenuBar extends JMenuBar implements PropertyChangeListener, ActionListener {
-
- ConfigurationModel configurationModel;
-
- JMenuItem closeFileItem;
- JMenuItem openFileItem;
- JMenu settingsMenu;
- JMenuItem logItem;
- JMenuItem serverItem;
- JMenu recentFilesMenu;
-
- class RecentFileItem extends JMenuItem {
-
- String path;
-
- RecentFileItem(String path, int mnemonic) {
- setText((mnemonic - KeyEvent.VK_0) + " " + path);
+final class MenuBar extends JMenuBar implements PropertyChangeListener, ActionListener {
+
+ /**
+ * The implementation of {@link javax.swing.JMenuItem} for recent file items.
+ */
+ private class RecentFileItem extends JMenuItem {
+
+ /**
+ * The recent file's path.
+ */
+ private final String path;
+
+ /**
+ * Class constructor with file's path and its numerical mnemonic (0-9).
+ *
+ * @param path the path
+ * @param mnemonic the item's mnemonic shortcut (0-9)
+ */
+ RecentFileItem(final String path, final int mnemonic) {
+ setText(mnemonic - KeyEvent.VK_0 + " " + path);
setMnemonic(mnemonic);
this.path = path;
}
-
- String getPath() {
- return path;
- }
- }
-
- MenuBar(ConfigurationModel configurationModel, ConnectionStatusModel connectionModel, ActionListener listener) {
-
- this.configurationModel = configurationModel;
+
+ /**
+ * Get the file path of the item.
+ *
+ * @return the file path
+ */
+ private String getPath() {
+ return this.path;
+ }
+ }
+
+ /**
+ * Starting mnemonic for recent files (this is equivalent to '0').
+ */
+ private static final int RECENT_FILES_START_INDEX = 48;
+
+ /**
+ * Menu item for closing a file source.
+ */
+ private final JMenuItem closeFileItem;
+
+ /**
+ * The application backing model.
+ */
+ private final ConfigurationModel configurationModel;
+
+ /**
+ * Menu item for logging to a file.
+ */
+ private final JMenuItem logItem;
+
+ /**
+ * Menu item for opening a file data source.
+ */
+ private final JMenuItem openFileItem;
+
+ /**
+ * Menu with list of recent files (10 max).
+ */
+ private final JMenu recentFilesMenu;
+
+ /**
+ * Menu item for activating the remote AIDA server.
+ */
+ private final JMenuItem serverItem;
+
+ /**
+ * Menu item for opening the settings dialog window.
+ */
+ private final JMenu settingsMenu;
+
+ /**
+ * Class constructor.
+ *
+ * @param configurationModel the {@link org.hps.monitoring.application.model.ConfigurationModel} providing the model
+ * @param connectionModel the {@link org.hps.monitoring.application.model.ConnectionStatusModel} providing
+ * connection status
+ * @param listener an {@link ava.awt.event.ActionListener} which is assigned to certain components
+ */
+ MenuBar(final ConfigurationModel configurationModel, final ConnectionStatusModel connectionModel,
+ final ActionListener listener) {
+
+ this.configurationModel = configurationModel;
this.configurationModel.addPropertyChangeListener(this);
-
+
// Need to listen for connection status changes.
- connectionModel.addPropertyChangeListener(this);
-
- JMenu fileMenu = new JMenu("File");
+ connectionModel.addPropertyChangeListener(this);
+
+ final JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic(KeyEvent.VK_F);
add(fileMenu);
-
- openFileItem = new JMenuItem("Open File ...");
- openFileItem.setMnemonic(KeyEvent.VK_P);
- openFileItem.setActionCommand(Commands.OPEN_FILE);
- openFileItem.addActionListener(listener);
- openFileItem.setToolTipText("Open an EVIO or LCIO data file");
- fileMenu.add(openFileItem);
-
- closeFileItem = new JMenuItem("Close File");
- closeFileItem.setMnemonic(KeyEvent.VK_C);
- closeFileItem.setActionCommand(Commands.CLOSE_FILE);
- closeFileItem.addActionListener(listener);
- closeFileItem.setToolTipText("Close the current file data source");
- fileMenu.add(closeFileItem);
-
- recentFilesMenu = new JMenu("RecentFiles");
- recentFilesMenu.setMnemonic(KeyEvent.VK_R);
- recentFilesMenu.setToolTipText("List of recent data files");
- JMenuItem noRecentFilesItem = new JMenuItem("No recent files");
+
+ this.openFileItem = new JMenuItem("Open File ...");
+ this.openFileItem.setMnemonic(KeyEvent.VK_P);
+ this.openFileItem.setActionCommand(Commands.OPEN_FILE);
+ this.openFileItem.addActionListener(listener);
+ this.openFileItem.setToolTipText("Open an EVIO or LCIO data file");
+ fileMenu.add(this.openFileItem);
+
+ this.closeFileItem = new JMenuItem("Close File");
+ this.closeFileItem.setMnemonic(KeyEvent.VK_C);
+ this.closeFileItem.setActionCommand(Commands.CLOSE_FILE);
+ this.closeFileItem.addActionListener(listener);
+ this.closeFileItem.setToolTipText("Close the current file data source");
+ fileMenu.add(this.closeFileItem);
+
+ this.recentFilesMenu = new JMenu("Recent Files");
+ this.recentFilesMenu.setMnemonic(KeyEvent.VK_R);
+ this.recentFilesMenu.setToolTipText("List of recent data files");
+ final JMenuItem noRecentFilesItem = new JMenuItem("No recent files");
noRecentFilesItem.setEnabled(false);
- recentFilesMenu.add(noRecentFilesItem);
- fileMenu.add(recentFilesMenu);
-
+ this.recentFilesMenu.add(noRecentFilesItem);
+ fileMenu.add(this.recentFilesMenu);
+
fileMenu.addSeparator();
-
- JMenuItem exitItem = new JMenuItem("Exit");
+
+ final JMenuItem exitItem = new JMenuItem("Exit");
exitItem.setMnemonic(KeyEvent.VK_X);
exitItem.setActionCommand(Commands.EXIT);
exitItem.addActionListener(listener);
exitItem.setToolTipText("Exit from the application");
fileMenu.add(exitItem);
-
- settingsMenu = new JMenu("Settings");
- settingsMenu.setMnemonic(KeyEvent.VK_S);
- add(settingsMenu);
-
- JMenuItem settingsItem = new JMenuItem("Open Settings Window ...");
+
+ this.settingsMenu = new JMenu("Settings");
+ this.settingsMenu.setMnemonic(KeyEvent.VK_S);
+ add(this.settingsMenu);
+
+ final JMenuItem settingsItem = new JMenuItem("Open Settings Window ...");
settingsItem.setMnemonic(KeyEvent.VK_O);
settingsItem.setActionCommand(Commands.SHOW_SETTINGS);
settingsItem.addActionListener(listener);
settingsItem.setToolTipText("Show settings dialog");
- settingsMenu.add(settingsItem);
-
- JMenuItem loadConfigItem = new JMenuItem("Load Settings ...");
+ this.settingsMenu.add(settingsItem);
+
+ final JMenuItem loadConfigItem = new JMenuItem("Load Settings ...");
loadConfigItem.addActionListener(listener);
loadConfigItem.setMnemonic(KeyEvent.VK_L);
loadConfigItem.setActionCommand(Commands.LOAD_SETTINGS);
loadConfigItem.setToolTipText("Load settings from a properties file");
- settingsMenu.add(loadConfigItem);
-
- JMenuItem saveConfigItem = new JMenuItem("Save Settings ...");
+ this.settingsMenu.add(loadConfigItem);
+
+ final JMenuItem saveConfigItem = new JMenuItem("Save Settings ...");
saveConfigItem.addActionListener(listener);
saveConfigItem.setMnemonic(KeyEvent.VK_S);
saveConfigItem.setActionCommand(Commands.SAVE_SETTINGS);
saveConfigItem.setToolTipText("Save configuration to a properties file");
- settingsMenu.add(saveConfigItem);
-
- JMenuItem defaultSettingsItem = new JMenuItem("Load Default Settings");
+ this.settingsMenu.add(saveConfigItem);
+
+ final JMenuItem defaultSettingsItem = new JMenuItem("Load Default Settings");
defaultSettingsItem.addActionListener(listener);
defaultSettingsItem.setMnemonic(KeyEvent.VK_D);
defaultSettingsItem.setActionCommand(Commands.LOAD_DEFAULT_SETTINGS);
defaultSettingsItem.setToolTipText("Load the default settings");
- settingsMenu.add(defaultSettingsItem);
-
- JMenu plotsMenu = new JMenu("Plots");
+ this.settingsMenu.add(defaultSettingsItem);
+
+ final JMenu plotsMenu = new JMenu("Plots");
plotsMenu.setMnemonic(KeyEvent.VK_P);
add(plotsMenu);
-
- JMenuItem savePlotsItem = new JMenuItem("Save plots ...");
+
+ final JMenuItem savePlotsItem = new JMenuItem("Save plots ...");
savePlotsItem.setMnemonic(KeyEvent.VK_S);
savePlotsItem.setActionCommand(Commands.SAVE_PLOTS);
savePlotsItem.addActionListener(listener);
@@ -135,140 +192,162 @@
savePlotsItem.setToolTipText("Save all plots to a file");
plotsMenu.add(savePlotsItem);
- JMenuItem clearPlotsItem = new JMenuItem("Clear plots");
+ final JMenuItem clearPlotsItem = new JMenuItem("Clear plots");
clearPlotsItem.setMnemonic(KeyEvent.VK_C);
clearPlotsItem.setActionCommand(Commands.CLEAR_PLOTS);
clearPlotsItem.addActionListener(listener);
clearPlotsItem.setEnabled(true);
clearPlotsItem.setToolTipText("Clear the AIDA plots");
plotsMenu.add(clearPlotsItem);
-
- JMenu toolsMenu = new JMenu("Tools");
+
+ final JMenu toolsMenu = new JMenu("Tools");
toolsMenu.setMnemonic(KeyEvent.VK_T);
add(toolsMenu);
-
- JMenuItem screenshotItem = new JMenuItem("Save Screenshot ...");
+
+ final JMenuItem screenshotItem = new JMenuItem("Save Screenshot ...");
screenshotItem.setMnemonic(KeyEvent.VK_S);
screenshotItem.setActionCommand(Commands.SAVE_SCREENSHOT);
screenshotItem.addActionListener(listener);
screenshotItem.setEnabled(true);
screenshotItem.setToolTipText("Save a screenshot to a graphics file");
toolsMenu.add(screenshotItem);
-
- logItem = new JMenuItem("Log to File ...");
- logItem.setMnemonic(KeyEvent.VK_L);
- 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);
-
- serverItem = new JMenuItem("Start AIDA Server ...");
- serverItem.setMnemonic(KeyEvent.VK_A);
- serverItem.setActionCommand(Commands.START_AIDA_SERVER);
- serverItem.setEnabled(true);
- serverItem.setToolTipText("Start AIDA RMI Server");
- serverItem.addActionListener(listener);
- toolsMenu.add(serverItem);
-
- JMenu windowMenu = new JMenu("Window");
+
+ this.logItem = new JMenuItem("Log to File ...");
+ this.logItem.setMnemonic(KeyEvent.VK_L);
+ this.logItem.setActionCommand(Commands.LOG_TO_FILE);
+ this.logItem.addActionListener(listener);
+ this.logItem.setEnabled(true);
+ this.logItem.setToolTipText("Redirect System.out to a file instead of terminal");
+ toolsMenu.add(this.logItem);
+
+ this.serverItem = new JMenuItem("Start AIDA Server ...");
+ this.serverItem.setMnemonic(KeyEvent.VK_A);
+ this.serverItem.setActionCommand(Commands.START_AIDA_SERVER);
+ this.serverItem.setEnabled(true);
+ this.serverItem.setToolTipText("Start AIDA RMI Server");
+ this.serverItem.addActionListener(listener);
+ toolsMenu.add(this.serverItem);
+
+ final JMenu windowMenu = new JMenu("Window");
windowMenu.setMnemonic(KeyEvent.VK_W);
add(windowMenu);
-
- JMenuItem maximizeItem = new JMenuItem("Maximize");
+
+ final JMenuItem maximizeItem = new JMenuItem("Maximize");
maximizeItem.setMnemonic(KeyEvent.VK_M);
maximizeItem.setActionCommand(Commands.MAXIMIZE_WINDOW);
maximizeItem.addActionListener(listener);
maximizeItem.setEnabled(true);
maximizeItem.setToolTipText("Maximize the application window");
windowMenu.add(maximizeItem);
-
- JMenuItem minimizeItem = new JMenuItem("Minimize");
+
+ final JMenuItem minimizeItem = new JMenuItem("Minimize");
minimizeItem.setMnemonic(KeyEvent.VK_I);
minimizeItem.setActionCommand(Commands.MINIMIZE_WINDOW);
minimizeItem.addActionListener(listener);
minimizeItem.setEnabled(true);
minimizeItem.setToolTipText("Minimize the application window");
windowMenu.add(minimizeItem);
-
- JMenuItem defaultsItem = new JMenuItem("Restore Defaults");
+
+ final JMenuItem defaultsItem = new JMenuItem("Restore Defaults");
defaultsItem.setMnemonic(KeyEvent.VK_D);
defaultsItem.setActionCommand(Commands.DEFAULT_WINDOW);
defaultsItem.addActionListener(listener);
defaultsItem.setEnabled(true);
defaultsItem.setToolTipText("Restore the window defaults");
- windowMenu.add(defaultsItem);
- }
-
+ windowMenu.add(defaultsItem);
+ }
+
+ /**
+ * The {@link java.awt.event.ActionEvent} handling which sets GUI values from the model.
+ *
+ * @param the {@link java.awt.event.ActionEvent} to handle
+ */
@Override
- public void propertyChange(PropertyChangeEvent evt) {
- configurationModel.removePropertyChangeListener(this);
- try {
+ public void actionPerformed(final ActionEvent e) {
+ if (e.getActionCommand().equals(Commands.DATA_SOURCE_CHANGED)) {
+ if (!this.configurationModel.getDataSourceType().equals(DataSourceType.ET_SERVER)) {
+ this.closeFileItem.setEnabled(true);
+ } else {
+ this.closeFileItem.setEnabled(false);
+ }
+ }
+ }
+
+ /**
+ * The {@link java.beans.PropertyChangeEvent} handling which sets GUI values from the model.
+ *
+ * @param the {@link java.beans.PropertyChangeEvent} to handle
+ */
+ @Override
+ public void propertyChange(final PropertyChangeEvent evt) {
+ this.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);
+ final ConnectionStatus status = (ConnectionStatus) evt.getNewValue();
+ final boolean connected = status.equals(ConnectionStatus.CONNECTED);
+ this.closeFileItem.setEnabled(!connected);
+ this.openFileItem.setEnabled(!connected);
} else if (evt.getPropertyName().equals(ConfigurationModel.LOG_TO_FILE_PROPERTY)) {
- Boolean logToFile = (Boolean) evt.getNewValue();
- if (logToFile == true) {
+ final Boolean logToFile = (Boolean) evt.getNewValue();
+ if (logToFile) {
// 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");
+ this.logItem.setText("Log to Terminal ...");
+ this.logItem.setActionCommand(Commands.LOG_TO_TERMINAL);
+ this.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");
+ this.logItem.setText("Log to File ...");
+ this.logItem.setActionCommand(Commands.LOG_TO_FILE);
+ this.logItem.setToolTipText("Log messages to a file");
}
} else if (evt.getPropertyName().equals(ConfigurationModel.RECENT_FILES_PROPERTY)) {
- setRecentFiles(configurationModel.getRecentFilesList());
- }
-
+ setRecentFiles(this.configurationModel.getRecentFilesList());
+ }
+
} finally {
- configurationModel.addPropertyChangeListener(this);
- }
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- if (e.getActionCommand().equals(Commands.DATA_SOURCE_CHANGED)) {
- if (!configurationModel.getDataSourceType().equals(DataSourceType.ET_SERVER)) {
- closeFileItem.setEnabled(true);
- } else {
- closeFileItem.setEnabled(false);
- }
- }
- }
-
- void setRecentFiles(List<String> recentFiles) {
- recentFilesMenu.removeAll();
- int fileMnemonic = 48; /* starts at KeyEvent.VK_0 */
- for (String recentFile : recentFiles) {
- RecentFileItem recentFileItem = new RecentFileItem(recentFile, fileMnemonic);
+ this.configurationModel.addPropertyChangeListener(this);
+ }
+ }
+
+ /**
+ * Set the recent file menu items.
+ *
+ * @param recentFiles the list of recent files from the model
+ */
+ private void setRecentFiles(final List<String> recentFiles) {
+ this.recentFilesMenu.removeAll();
+ int fileMnemonic = RECENT_FILES_START_INDEX; /* starts at KeyEvent.VK_0 */
+ for (final String recentFile : recentFiles) {
+ final RecentFileItem recentFileItem = new RecentFileItem(recentFile, fileMnemonic);
recentFileItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- String recentFile = ((RecentFileItem) e.getSource()).getPath();
- DataSourceType dst = DataSourceType.getDataSourceType(recentFile);
- configurationModel.setDataSourcePath(recentFile);
- configurationModel.setDataSourceType(dst);
+ @Override
+ public void actionPerformed(final ActionEvent e) {
+ final String recentFile = ((RecentFileItem) e.getSource()).getPath();
+ final DataSourceType dst = DataSourceType.getDataSourceType(recentFile);
+ MenuBar.this.configurationModel.setDataSourcePath(recentFile);
+ MenuBar.this.configurationModel.setDataSourceType(dst);
}
- });
- recentFilesMenu.add(recentFileItem);
+ });
+ this.recentFilesMenu.add(recentFileItem);
++fileMnemonic;
- }
- }
-
+ }
+ }
+
+ /**
+ * Set state for AIDA server started.
+ */
void startAIDAServer() {
- serverItem.setActionCommand(Commands.STOP_AIDA_SERVER);
- serverItem.setText("Stop AIDA Server");
- serverItem.setToolTipText("Stop the remote AIDA server");
- }
-
+ this.serverItem.setActionCommand(Commands.STOP_AIDA_SERVER);
+ this.serverItem.setText("Stop AIDA Server");
+ this.serverItem.setToolTipText("Stop the remote AIDA server");
+ }
+
+ /**
+ * Set state for AIDA server stopped.
+ */
void stopAIDAServer() {
- serverItem.setActionCommand(Commands.START_AIDA_SERVER);
- serverItem.setText("Start AIDA Server");
- serverItem.setToolTipText("Start the remote AIDA server");
+ this.serverItem.setActionCommand(Commands.START_AIDA_SERVER);
+ this.serverItem.setText("Start AIDA Server");
+ this.serverItem.setToolTipText("Start the remote 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 Apr 21 14:48:39 2015
@@ -3,8 +3,8 @@
import hep.aida.jfree.AnalysisFactory;
import hep.aida.jfree.plotter.PlotterRegion;
import hep.aida.jfree.plotter.PlotterRegionListener;
-import hep.aida.ref.remote.rmi.client.RmiStoreFactory;
-
+
+import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
@@ -19,6 +19,7 @@
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
import java.util.logging.Handler;
import java.util.logging.Level;
@@ -28,7 +29,6 @@
import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
-import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.filechooser.FileFilter;
@@ -59,217 +59,278 @@
import org.lcsim.util.log.DefaultLogFormatter;
/**
- * This is the primary class that implements the monitoring GUI application.
- * It should not be used directly. Instead the {@link Main} class should be
- * used from the command line.
- *
- * @author Jeremy McCormick <[log in to unmask]>
+ * This is the primary class that implements the data monitoring GUI application.
+ * <p>
+ * It should not be used directly. Instead the {@link Main} class should be used from the command line.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
final class MonitoringApplication implements ActionListener, PropertyChangeListener {
- // Statically initialize logging, which will be fully setup later.
- static final Logger logger;
- static {
- logger = Logger.getLogger(MonitoringApplication.class.getSimpleName());
- }
- static final Level DEFAULT_LEVEL = Level.ALL;
-
- // Default log stream.
- MonitoringApplicationStreamHandler streamHandler;
- LogHandler logHandler;
- PrintStream sysOut = System.out;
- PrintStream sysErr = System.err;
-
- // Application error handling.
- ErrorHandler errorHandler;
-
- // The main GUI components inside a JFrame.
- MonitoringApplicationFrame frame;
-
- // The primary data models.
- final RunModel runModel = new RunModel();
- final ConfigurationModel configurationModel = new ConfigurationModel();
- final ConnectionStatusModel connectionModel = new ConnectionStatusModel();
-
- // The default configuration resource embedded in the jar.
- static final String DEFAULT_CONFIGURATION = "/org/hps/monitoring/config/default_config.prop";
-
- // Encapsulation of ET connection and event processing.
- EventProcessing processing;
-
- // Filters for opening files.
- static final FileFilter lcioFilter = new FileNameExtensionFilter("LCIO files", "slcio");
- static final EvioFileFilter evioFilter = new EvioFileFilter();
-
- AIDAServer server = new AIDAServer("hps-monitoring-app");
- static final RmiStoreFactory rsf = new RmiStoreFactory();
-
- /**
- * Default log handler.
+ /**
+ * The default log handler which puts records into the table GUI component.
*/
class LogHandler extends Handler {
+
+ /**
+ * Close the handler.
+ *
+ * @throws SecurityException never
+ */
+ @Override
+ public void close() throws SecurityException {
+ // Does nothing.
+ }
+
+ /**
+ * Flush the handler.
+ */
+ @Override
+ public void flush() {
+ // Does nothing.
+ }
/**
* This method inserts a record into the log table.
*/
- public void publish(LogRecord record) {
+ @Override
+ public void publish(final LogRecord record) {
+ // Add the record to the table's model.
getLogRecordModel().add(record);
}
-
- public void close() throws SecurityException {
- }
-
- public void flush() {
- }
- }
-
- LogRecordModel getLogRecordModel() {
- return frame.logPanel.logTable.model;
- }
-
- LogTable getLogTable() {
- return frame.logPanel.logTable;
- }
-
+ }
+
+ /**
+ * Log handler which publishes messages to a stream (console or file in this case).
+ */
class MonitoringApplicationStreamHandler extends StreamHandler {
-
- MonitoringApplicationStreamHandler(PrintStream ps) {
+
+ /**
+ * Class constructor.
+ *
+ * @param ps the output stream
+ */
+ MonitoringApplicationStreamHandler(final PrintStream ps) {
super(ps, new DefaultLogFormatter());
}
-
- public void publish(LogRecord record) {
+
+ /**
+ * Publish a record which will automatically flush the handler.
+ *
+ * @param record the <code>LogRecord</code> to publish
+ */
+ @Override
+ public void publish(final LogRecord record) {
super.publish(record);
+
+ // FIXME: Is this efficient? Should this always happen here?
flush();
}
-
- public void setOutputStream(OutputStream out) {
+
+ /**
+ * Set the output stream.
+ *
+ * @param out the output stream
+ */
+ @Override
+ public void setOutputStream(final OutputStream out) {
super.setOutputStream(out);
- }
- }
-
+ }
+ }
+
+ /**
+ * The default configuration resource from the jar.
+ */
+ private static final String DEFAULT_CONFIGURATION = "/org/hps/monitoring/config/default_config.prop";
+
+ /**
+ * The default log level (shows all messages).
+ */
+ private static final Level DEFAULT_LEVEL = Level.ALL;
+
+ /**
+ * A filter for selecting EVIO files.
+ */
+ private static final EvioFileFilter EVIO_FILTER = new EvioFileFilter();
+
+ /**
+ * A filter for selecting LCIO files.
+ */
+ private static final FileFilter LCIO_FILTER = new FileNameExtensionFilter("LCIO files", "slcio");
+
+ /**
+ * Global logging object.
+ */
+ private static final Logger LOGGER;
+
+ /**
+ * Saved reference to <code>System.err</code> for convenience.
+ */
+ private static final PrintStream SYS_ERR = System.err;
+
+ /**
+ * Saved reference to <code>System.out</code> for convenience.
+ */
+ private static final PrintStream SYS_OUT = System.out;
+
+ /**
+ * Initialize logging which will be fully configured later.
+ */
+ static {
+ LOGGER = Logger.getLogger(MonitoringApplication.class.getSimpleName());
+ }
+
+ /**
+ * Static utility method for creating new instance.
+ *
+ * @param configuration the application settings
+ * @return the new monitoring application instance
+ */
+ static MonitoringApplication create(final Configuration configuration) {
+ return new MonitoringApplication(configuration);
+ }
+
+ /**
+ * The global configuration model.
+ */
+ private final ConfigurationModel configurationModel = new ConfigurationModel();
+
+ /**
+ * The global connection status model.
+ */
+ private final ConnectionStatusModel connectionModel = new ConnectionStatusModel();
+
+ /**
+ * The error handling object.
+ */
+ private ErrorHandler errorHandler;
+
+ /**
+ * The primary GUI component which is a <code>JFrame</code>.
+ */
+ private MonitoringApplicationFrame frame;
+
+ /**
+ * The current log handler.
+ */
+ private LogHandler logHandler;
+
+ /**
+ * Event processing wrapper.
+ */
+ private EventProcessing processing;
+
+ /**
+ * The model which has information about the current run and events being processed.
+ */
+ private final RunModel runModel = new RunModel();
+
+ /**
+ * A remote AIDA server instance.
+ */
+ private final AIDAServer server = new AIDAServer("hps-monitoring-app");
+
+ /**
+ * The handler for putting messages into the log table.
+ */
+ private MonitoringApplicationStreamHandler streamHandler;
+
/**
* Instantiate and show the monitoring application with the given configuration.
- * @param userConfiguration The Configuration object containing application settings.
- */
- MonitoringApplication(Configuration userConfiguration) {
-
+ *
+ * @param userConfiguration the Configuration object containing application settings
+ */
+ MonitoringApplication(final Configuration userConfiguration) {
+
try {
-
+
// Setup the main GUI component.
- frame = new MonitoringApplicationFrame(this);
-
+ this.frame = new MonitoringApplicationFrame(this);
+
// Add window listener to perform clean shutdown.
- frame.addWindowListener(new WindowListener() {
+ this.frame.addWindowListener(new WindowListener() {
@Override
- public void windowOpened(WindowEvent e) {
+ public void windowActivated(final WindowEvent e) {
}
+ /**
+ * Activate cleanup when window closes.
+ *
+ * @param e the window event
+ */
@Override
- public void windowClosing(WindowEvent e) {
- }
-
- @Override
- public void windowClosed(WindowEvent e) {
+ public void windowClosed(final WindowEvent e) {
exit();
}
@Override
- public void windowIconified(WindowEvent e) {
+ public void windowClosing(final WindowEvent e) {
}
@Override
- public void windowDeiconified(WindowEvent e) {
+ public void windowDeactivated(final WindowEvent e) {
}
@Override
- public void windowActivated(WindowEvent e) {
+ public void windowDeiconified(final WindowEvent e) {
}
@Override
- public void windowDeactivated(WindowEvent e) {
+ public void windowIconified(final WindowEvent e) {
+ }
+
+ @Override
+ public void windowOpened(final WindowEvent e) {
}
});
-
+
// Setup the error handler.
- errorHandler = new ErrorHandler(frame, logger);
-
+ this.errorHandler = new ErrorHandler(this.frame, LOGGER);
+
// Add this class as a listener on the configuration model.
- configurationModel.addPropertyChangeListener(this);
-
+ this.configurationModel.addPropertyChangeListener(this);
+
// Setup the logger.
setupLogger();
-
+
// Setup AIDA plotting and connect it to the GUI.
setupAida();
-
+
// Load the default configuration.
loadConfiguration(new Configuration(DEFAULT_CONFIGURATION), false);
-
+
if (userConfiguration != null) {
// Load user configuration.
loadConfiguration(userConfiguration, true);
- }
-
+ }
+
// Enable the GUI now that initialization is complete.
- frame.setEnabled(true);
-
- logger.info("application initialized successfully");
-
- } catch (Exception e) {
+ this.frame.setEnabled(true);
+
+ LOGGER.info("application initialized successfully");
+
+ } catch (final Exception e) {
// Don't use the ErrorHandler here because we don't know that it initialized successfully.
System.err.println("MonitoringApplication failed to initialize without errors!");
- DialogUtil.showErrorDialog(null, "Error Starting Monitoring Application", "Monitoring application failed to initialize.");
+ DialogUtil.showErrorDialog(null, "Error Starting Monitoring Application",
+ "Monitoring application failed to initialize.");
e.printStackTrace();
System.exit(1);
- }
- }
-
- /**
- * Setup the logger.
- */
- void setupLogger() {
- logger.setUseParentHandlers(false);
- logHandler = new LogHandler();
- logger.addHandler(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");
- }
-
- /**
- * Static utility method for creating new instance.
- * @param configuration The application settings.
- * @return The new monitoring application instance.
- */
- static MonitoringApplication create(Configuration configuration) {
- return new MonitoringApplication(configuration);
- }
-
- /**
- * Handle property changes.
- * @param evt The property change event.
+ }
+ }
+
+ /**
+ * The primary action handler for the application.
+ *
+ * @param e the {@link java.awt.ActionEvent} to handle
*/
@Override
- public void propertyChange(PropertyChangeEvent evt) {
- if (evt.getPropertyName().equals(ConfigurationModel.LOG_LEVEL_PROPERTY)) {
- setLogLevel();
- }
- }
-
- /**
- * The primary action handler for the application.
- * @param e The ActionEvent to handle.
- */
- public void actionPerformed(ActionEvent e) {
-
- //logger.finest("actionPerformed - " + e.getActionCommand());
-
- String command = e.getActionCommand();
+ public void actionPerformed(final ActionEvent e) {
+
+ // logger.finest("actionPerformed - " + e.getActionCommand());
+
+ final String command = e.getActionCommand();
if (Commands.CONNECT.equals(command)) {
startSession();
} else if (Commands.DISCONNECT.equals(command)) {
@@ -278,20 +339,20 @@
savePlots();
} else if (Commands.EXIT.equals(command)) {
// This will trigger the window closing action that cleans everything up.
- frame.dispose();
- } else if (Commands.PAUSE.equals(command)) {
- processing.pause();
+ this.frame.dispose();
+ } else if (Commands.PAUSE.equals(command)) {
+ this.processing.pause();
} else if (Commands.NEXT.equals(command)) {
- processing.next();
+ this.processing.next();
} else if (Commands.RESUME.equals(command)) {
- processing.resume();
+ this.processing.resume();
} else if (Commands.SHOW_SETTINGS.equals(command)) {
showSettingsDialog();
} else if (Commands.LOAD_SETTINGS.equals(command)) {
loadSettings();
} else if (Commands.SAVE_SETTINGS.equals(command)) {
saveSettings();
- } else if (Commands.CLEAR_PLOTS.equals(command)) {
+ } else if (Commands.CLEAR_PLOTS.equals(command)) {
clearPlots();
} else if (Commands.LOAD_DEFAULT_SETTINGS.equals(command)) {
loadDefaultSettings();
@@ -320,545 +381,672 @@
} else if (Commands.STOP_AIDA_SERVER.equals(command)) {
stopAIDAServer();
}
- }
-
- /**
- * Setup AIDA plotting into the GUI components.
- */
- void setupAida() {
- // Register the factory for displaying plots in tabs.
- MonitoringAnalysisFactory.register();
-
- // Set the root tab pane for displaying plots.
- MonitoringPlotFactory.setRootPane(frame.plotPanel.getPlotPane());
-
- // Setup the region listener to connect the plot info window.
- MonitoringPlotFactory.setPlotterRegionListener(new PlotterRegionListener() {
- @Override
- public void regionSelected(PlotterRegion region) {
- if (region != null) {
- frame.plotInfoPanel.setCurrentRegion(region);
- }
+ }
+
+ /**
+ * Redirect <code>System.out</code> and <code>System.err</code> to a file chosen by a file chooser.
+ */
+ private void chooseLogFile() {
+ final JFileChooser fc = new JFileChooser();
+ fc.setAcceptAllFileFilterUsed(false);
+ fc.setDialogTitle("Save Log Messages to File");
+ fc.setCurrentDirectory(new File("."));
+ final int r = fc.showSaveDialog(this.frame);
+ if (r == JFileChooser.APPROVE_OPTION) {
+ final String fileName = fc.getSelectedFile().getPath();
+ if (new File(fileName).exists()) {
+ DialogUtil.showErrorDialog(this.frame, "File Exists", "File already exists.");
+ } else {
+ logToFile(new File(fileName));
}
- });
-
- // Perform global configuration of the JFreeChart back end.
- AnalysisFactory.configure();
- }
-
+ }
+ }
+
+ /**
+ * Clear the current set of AIDA plots in the default data tree.
+ */
+ private void clearPlots() {
+ final int confirmation = DialogUtil.showConfirmationDialog(this.frame,
+ "Are you sure you want to clear the plots", "Clear Plots Confirmation");
+ if (confirmation == JOptionPane.YES_OPTION) {
+ AIDA.defaultInstance().clearAll();
+ DialogUtil.showInfoDialog(this.frame, "Plots Clear", "The AIDA plots were cleared.");
+ }
+ LOGGER.info("plots were cleared");
+ }
+
+ /**
+ * Remove the currently selected file from the data source list.
+ */
+ private void closeFile() {
+ if (!this.configurationModel.getDataSourceType().equals(DataSourceType.ET_SERVER)) {
+ final DataSourceItem item = (DataSourceItem) this.frame.getToolbarPanel().getDataSourceComboBox()
+ .getSelectedItem();
+ if (item.getPath().equals(this.configurationModel.getDataSourcePath())) {
+ this.frame.getToolbarPanel().getDataSourceComboBox()
+ .removeItem(this.frame.getToolbarPanel().getDataSourceComboBox().getSelectedItem());
+ }
+ }
+ }
+
+ /**
+ * Exit from the application from exit menu item or hitting close window button.
+ */
+ private void exit() {
+ if (this.connectionModel.isConnected()) {
+ this.processing.stop();
+ }
+ this.logHandler.setLevel(Level.OFF);
+ LOGGER.info("exiting the application");
+ this.streamHandler.flush();
+ System.exit(0);
+ }
+
+ /**
+ * Get the current configuration model.
+ *
+ * @return the current configuration model
+ */
+ ConfigurationModel getConfigurationModel() {
+ return this.configurationModel;
+ }
+
+ /**
+ * Get the current connection status model.
+ *
+ * @return the current connections status model
+ */
+ ConnectionStatusModel getConnectionModel() {
+ return this.connectionModel;
+ }
+
+ /**
+ * Get the application's error handling object.
+ *
+ * @return the error handling object
+ */
+ ErrorHandler getErrorHandler() {
+ return this.errorHandler;
+ }
+
+ /**
+ * Get the logger.
+ *
+ * @return the logger
+ */
+ Logger getLogger() {
+ return LOGGER;
+ }
+
+ /**
+ * Get the table model for log records.
+ *
+ * @return the table model for log records
+ */
+ LogRecordModel getLogRecordModel() {
+ return this.frame.getLogPanel().getLogTable().getLogRecordModel();
+ }
+
+ /**
+ * Get the log table.
+ *
+ * @return the log table
+ */
+ LogTable getLogTable() {
+ return this.frame.getLogPanel().getLogTable();
+ }
+
+ /**
+ * Get a list of relevant run data from the model for writing to a PDF.
+ *
+ * @return the list of run data from the model
+ */
+ private List<String> getRunData() {
+ final List<String> data = new ArrayList<String>();
+ data.add("Created: " + new Date());
+ data.add("Run Number: " + this.runModel.getRunNumber());
+ data.add("Started: " + this.runModel.getStartDate());
+ data.add("Ended: " + this.runModel.getEndDate());
+ data.add("Length: " + this.runModel.getRunLength() + " seconds");
+ data.add("Total Events: " + this.runModel.getTotalEvents());
+ data.add("Elapsed Time: " + this.runModel.getElapsedTime());
+ data.add("Events Processed: " + this.runModel.getEventsReceived());
+ return data;
+ }
+
+ /**
+ * Get the run model with information about the run and event(s) currently being processed.
+ *
+ * @return the run model
+ */
+ RunModel getRunModel() {
+ return this.runModel;
+ }
+
/**
* This method sets the configuration on the model, which fires a change for every property.
- * @param configuration The new configuration.
- * @param merge True to merge the configuration into the current one rather than replace it.
- */
- void loadConfiguration(Configuration configuration, boolean merge) {
-
+ *
+ * @param configuration the new configuration
+ * @param merge <code>true</code> to merge the configuration into the current one rather than replace it
+ */
+ private void loadConfiguration(final Configuration configuration, final boolean merge) {
+
if (merge) {
// This will merge in additional properties so that default or current settings are preserved.
- configurationModel.merge(configuration);
+ this.configurationModel.merge(configuration);
} else {
// HACK: Clear data source combo box for clean configuration.
- frame.toolbarPanel.dataSourceComboBox.removeAllItems();
-
+ this.frame.getToolbarPanel().getDataSourceComboBox().removeAllItems();
+
// This will reset all configuration properties.
- configurationModel.setConfiguration(configuration);
- }
-
- if (configuration.getFile() != null)
- logger.config("loaded config from file " + configuration.getFile().getPath());
- else
- logger.config("loaded config from resource " + configuration.getResourcePath());
- }
-
+ this.configurationModel.setConfiguration(configuration);
+ }
+
+ if (configuration.getFile() != null) {
+ LOGGER.config("loaded config from file " + configuration.getFile().getPath());
+ } else {
+ LOGGER.config("loaded config from resource " + configuration.getResourcePath());
+ }
+ }
+
+ /**
+ * Load default application settings.
+ */
+ private void loadDefaultSettings() {
+ loadConfiguration(new Configuration(MonitoringApplication.DEFAULT_CONFIGURATION), false);
+ DialogUtil.showInfoDialog(this.frame, "Default Configuration Loaded", "The default configuration was loaded.");
+ LOGGER.config("default settings loaded");
+ }
+
+ /**
+ * Load settings from a properties file using a file chooser.
+ */
+ private void loadSettings() {
+ final JFileChooser fc = new JFileChooser();
+ fc.setDialogTitle("Load Settings");
+ fc.setCurrentDirectory(new File("."));
+ final int r = fc.showDialog(this.frame, "Load ...");
+ if (r == JFileChooser.APPROVE_OPTION) {
+ final File f = fc.getSelectedFile();
+ loadConfiguration(new Configuration(f), true);
+ LOGGER.info("loaded configuration from file: " + f.getPath());
+ DialogUtil.showInfoDialog(this.frame, "Settings Loaded", "Settings were loaded successfully.");
+ }
+ }
+
+ /**
+ * 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
+ */
+ private void logToFile(final File file) {
+ try {
+
+ // Create the output file stream.
+ final 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!
+ this.streamHandler.flush();
+
+ // Replace the current handler with one using the file stream.
+ LOGGER.removeHandler(this.streamHandler);
+ this.streamHandler = new MonitoringApplicationStreamHandler(fileStream);
+ this.streamHandler.setLevel(LOGGER.getLevel());
+ LOGGER.addHandler(this.streamHandler);
+
+ // Set the properties on the model.
+ this.configurationModel.setLogFileName(file.getPath());
+ this.configurationModel.setLogToFile(true);
+
+ LOGGER.info("Saving log messages to " + this.configurationModel.getLogFileName());
+ DialogUtil.showInfoDialog(this.frame, "Logging to File", "Log messages redirected to file" + '\n'
+ + this.configurationModel.getLogFileName());
+
+ } catch (final FileNotFoundException e) {
+ this.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.
+ */
+ private void logToTerminal() {
+
+ // Reset System.out and err back to original streams.
+ System.setOut(MonitoringApplication.SYS_OUT);
+ System.setErr(MonitoringApplication.SYS_ERR);
+
+ // Flush and close the current handler, which is using a file stream.
+ this.streamHandler.flush();
+ this.streamHandler.close();
+
+ // Replace the handler with the one printing to the terminal.
+ LOGGER.removeHandler(this.streamHandler);
+ this.streamHandler = new MonitoringApplicationStreamHandler(System.out);
+ this.streamHandler.setLevel(LOGGER.getLevel());
+ LOGGER.addHandler(this.streamHandler);
+
+ LOGGER.log(Level.INFO, "log messages redirected to terminal");
+
+ // Update the model to indicate logging to file has been disabled.
+ this.configurationModel.setLogToFile(false);
+
+ DialogUtil.showInfoDialog(this.frame, "Log to Terminal", "Log messages will be sent to the terminal.");
+ }
+
+ /**
+ * Maximize the application window.
+ */
+ private void maximizeWindow() {
+ this.frame.setExtendedState(Frame.MAXIMIZED_BOTH);
+ }
+
+ /**
+ * Minimize the application window.
+ */
+ private void minimizeWindow() {
+ this.frame.setExtendedState(Frame.ICONIFIED);
+ }
+
+ /**
+ * Open a file data source using a <code>JFileChooser</code>.
+ */
+ private void openFile() {
+ final JFileChooser fc = new JFileChooser(System.getProperty("user.dir"));
+ fc.setAcceptAllFileFilterUsed(false);
+ fc.addChoosableFileFilter(LCIO_FILTER);
+ fc.addChoosableFileFilter(EVIO_FILTER);
+ fc.setDialogTitle("Select Data File");
+ final int r = fc.showDialog(this.frame, "Select ...");
+ if (r == JFileChooser.APPROVE_OPTION) {
+
+ // Set data source path.
+ final String filePath = fc.getSelectedFile().getPath();
+
+ // Set data source type.
+ final FileFilter filter = fc.getFileFilter();
+ DataSourceType type = null;
+ if (filter == LCIO_FILTER) {
+ type = DataSourceType.LCIO_FILE;
+ } else if (filter == EVIO_FILTER) {
+ type = DataSourceType.EVIO_FILE;
+ } else {
+ // This should never happen.
+ throw new RuntimeException();
+ }
+
+ this.configurationModel.setDataSourcePath(filePath);
+ this.configurationModel.setDataSourceType(type);
+
+ this.configurationModel.addRecentFile(filePath);
+
+ LOGGER.config("set new data source " + filePath + " with type " + type);
+ }
+ }
+
+ /**
+ * Handle property changes.
+ *
+ * @param evt the <code>PropertyChangeEvent</code> to handle
+ */
+ @Override
+ public void propertyChange(final PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals(ConfigurationModel.LOG_LEVEL_PROPERTY)) {
+ setLogLevel();
+ }
+ }
+
/**
* Reset the plots and clear the tabs in the plot window.
*/
- void resetPlots() {
-
+ private void resetPlots() {
+
// Clear global list of registered plotters.
- MonitoringPlotFactory.getPlotterRegistry().clear();
-
+ MonitoringPlotFactory.getPlotterRegistry().clear();
+
// Clear the static AIDA tree in case plots are hanging around from previous sessions.
AIDA.defaultInstance().clearAll();
// Reset plot panel which removes all its tabs.
- frame.plotPanel.reset();
-
- logger.info("plots were cleared");
- }
-
- /**
- * Configure the system status monitor panel for a new job.
- */
- void setupSystemStatusMonitor() {
-
- // Clear the system status monitor table.
- frame.systemStatusPanel.clear();
-
- // Get the global registry of SystemStatus objects.
- SystemStatusRegistry registry = SystemStatusRegistry.getSystemStatusRegistery();
-
- // Process the SystemStatus objects.
- for (SystemStatus systemStatus : registry.getSystemStatuses()) {
- // This will add the status to the two tables.
- frame.systemStatusPanel.addSystemStatus(systemStatus);
- }
-
- logger.info("system status monitor initialized successfully");
- }
-
- /**
- * Start a new monitoring session.
- */
- synchronized void startSession() {
-
- logger.info("starting new session");
-
- try {
-
- // Reset the plot panel and global AIDA state.
- resetPlots();
-
- // The system status registry is cleared here before any event processors
- // which might create a SystemStatus are added to the event processing chain
- // e.g. an LCSim Driver, etc.
- SystemStatusRegistry.getSystemStatusRegistery().clear();
-
- // List of extra composite record processors including the updater for the RunPanel.
- List<CompositeRecordProcessor> processors = new ArrayList<CompositeRecordProcessor>();
- processors.add(frame.dashboardPanel.new EventDashboardUpdater());
-
- // Add Driver to update the trigger diagnostics tables.
- List<Driver> drivers = new ArrayList<Driver>();
- drivers.add(frame.triggerPanel.new TriggerDiagnosticGUIDriver());
-
- // Add listener to push conditions changes to conditions panel.
- List<ConditionsListener> conditionsListeners = new ArrayList<ConditionsListener>();
- conditionsListeners.add(frame.conditionsPanel.new ConditionsPanelListener());
-
- // Instantiate the event processing wrapper.
- processing = new EventProcessing(this, processors, drivers, conditionsListeners);
-
- // Connect to the ET system, if applicable.
- processing.connect();
-
- // Configure event processing from the global application settings, including setup of record loop.
- logger.info("setting up event processing on source " + configurationModel.getDataSourcePath()
- + " with type " + configurationModel.getDataSourceType());
- processing.setup(configurationModel);
-
- // Setup the system status monitor table.
- setupSystemStatusMonitor();
-
- // Start the event processing thread.
- processing.start();
-
- logger.info("new session successfully initialized");
-
- } catch (Exception e) {
-
- // Disconnect from the ET system.
- processing.disconnect();
-
- // Log the error that occurred and show a pop up dialog.
- errorHandler.setError(e).log().printStackTrace().showErrorDialog("There was an error while starting the session."
- + '\n' + "See the log for details.", "Session Error");
-
- logger.severe("failed to start new session");
- }
- }
-
- /**
- * Exit from the application from exit menu item or hitting close window button.
- */
- void exit() {
- if (connectionModel.isConnected()) {
- processing.stop();
- }
- logHandler.setLevel(Level.OFF);
- logger.info("exiting the application");
- streamHandler.flush();
- System.exit(0);
- }
-
+ this.frame.getPlotPanel().reset();
+
+ LOGGER.info("plots were cleared");
+ }
+
+ /**
+ * Restore the default GUI layout.
+ */
+ private void restoreDefaultWindow() {
+ maximizeWindow();
+ this.frame.restoreDefaults();
+ }
+
+ /**
+ * Run the disconnection on a separate thread.
+ */
+ private void runDisconnectThread() {
+ new Thread() {
+ @Override
+ public void run() {
+ LOGGER.fine("disconnect thread is running ...");
+ MonitoringApplication.this.connectionModel.setConnectionStatus(ConnectionStatus.DISCONNECTING);
+ MonitoringApplication.this.processing.stop();
+ LOGGER.fine("disconnect thread finished!");
+ }
+ }.run();
+ }
+
+ /**
+ * Save the log table to a file using a file chooser.
+ */
+ private void saveLogTable() {
+ saveTable(this.frame.getLogPanel().getLogTable());
+ }
+
/**
* Save plots to an AIDA, ROOT or PDF file using a file chooser.
*/
- void savePlots() {
- JFileChooser fc = new JFileChooser();
+ private void savePlots() {
+ final JFileChooser fc = new JFileChooser();
fc.addChoosableFileFilter(new FileNameExtensionFilter("ROOT file", "root"));
- FileFilter filter = new FileNameExtensionFilter("AIDA file", "aida");
+ final FileFilter filter = new FileNameExtensionFilter("AIDA file", "aida");
fc.addChoosableFileFilter(filter);
fc.addChoosableFileFilter(new FileNameExtensionFilter("PDF file", "pdf"));
fc.setAcceptAllFileFilterUsed(false);
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
fc.setFileFilter(filter);
- int r = fc.showSaveDialog(frame);
+ final int r = fc.showSaveDialog(this.frame);
if (r == JFileChooser.APPROVE_OPTION) {
- File selectedFile = fc.getSelectedFile();
+ final File selectedFile = fc.getSelectedFile();
if (!selectedFile.exists()) {
String fileName = fc.getSelectedFile().getAbsolutePath();
- String extension = ((FileNameExtensionFilter) fc.getFileFilter()).getExtensions()[0];
+ final String extension = ((FileNameExtensionFilter) fc.getFileFilter()).getExtensions()[0];
if (!fileName.endsWith(".aida") && !fileName.endsWith(".root") && !fileName.endsWith(".pdf")) {
fileName += "." + extension;
}
try {
- if (extension.equals("pdf")) {
+ if ("pdf".equals(extension)) {
// Write to a single PDF file.
- ExportPdf.write(MonitoringPlotFactory.getPlotterRegistry().getPlotters(), fileName);
+ ExportPdf.write(MonitoringPlotFactory.getPlotterRegistry().getPlotters(), fileName,
+ getRunData());
} else {
// Save plot object data to AIDA or ROOT file.
AIDA.defaultInstance().saveAs(fileName);
}
- logger.info("saved plots to " + fileName);
- DialogUtil.showInfoDialog(frame, "Plots Saved", "Plots were successfully saved to " + '\n' + fileName);
- } catch (IOException e) {
- errorHandler.setError(e).setMessage("Error Saving Plots").printStackTrace().log().showErrorDialog();
+ LOGGER.info("saved plots to " + fileName);
+ DialogUtil.showInfoDialog(this.frame, "Plots Saved", "Plots were successfully saved to " + '\n'
+ + fileName);
+ } catch (final IOException e) {
+ this.errorHandler.setError(e).setMessage("Error Saving Plots").printStackTrace().log()
+ .showErrorDialog();
}
} else {
- DialogUtil.showErrorDialog(frame, "File Exists", "Selected file already exists.");
+ DialogUtil.showErrorDialog(this.frame, "File Exists", "Selected file already exists.");
}
}
}
-
- /**
- * Clear the current set of AIDA plots in the default data tree.
- */
- void clearPlots() {
- int confirmation = DialogUtil.showConfirmationDialog(frame,
- "Are you sure you want to clear the plots", "Clear Plots Confirmation");
- if (confirmation == JOptionPane.YES_OPTION) {
- AIDA.defaultInstance().clearAll();
- DialogUtil.showInfoDialog(frame, "Plots Clear", "The AIDA plots were cleared.");
- }
- logger.info("plots were cleared");
- }
-
- /**
- * Load default application settings.
- */
- void loadDefaultSettings() {
- loadConfiguration(new Configuration(MonitoringApplication.DEFAULT_CONFIGURATION), false);
- DialogUtil.showInfoDialog(frame, "Default Configuration Loaded", "The default configuration was loaded.");
- logger.config("default settings loaded");
- }
-
- /**
- * Show the settings dialog window.
- */
- void showSettingsDialog() {
- frame.settingsDialog.setVisible(true);
- }
-
- /**
- * Open a file data source using a <code>JFileChooser</code>.
- */
- void openFile() {
- JFileChooser fc = new JFileChooser(System.getProperty("user.dir"));
- fc.setAcceptAllFileFilterUsed(false);
- fc.addChoosableFileFilter(lcioFilter);
- fc.addChoosableFileFilter(evioFilter);
- fc.setDialogTitle("Select Data File");
- int r = fc.showDialog(frame, "Select ...");
- if (r == JFileChooser.APPROVE_OPTION) {
-
- // Set data source path.
- final String filePath = fc.getSelectedFile().getPath();
-
- // Set data source type.
- FileFilter filter = fc.getFileFilter();
- DataSourceType type = null;
- if (filter == lcioFilter) {
- type = DataSourceType.LCIO_FILE;
- } else if (filter == evioFilter) {
- type = DataSourceType.EVIO_FILE;
- } else {
- // This should never happen.
- throw new RuntimeException();
- }
-
- configurationModel.setDataSourcePath(filePath);
- configurationModel.setDataSourceType(type);
-
- configurationModel.addRecentFile(filePath);
-
- logger.config("set new data source " + filePath + " with type " + type);
- }
- }
-
- /**
- * Save current settings to a file using a file chooser.
- */
- void saveSettings() {
- JFileChooser fc = new JFileChooser();
- fc.setDialogTitle("Save Configuration");
- fc.setCurrentDirectory(new File("."));
- int r = fc.showSaveDialog(frame);
- if (r == JFileChooser.APPROVE_OPTION) {
- File f = fc.getSelectedFile();
- configurationModel.getConfiguration().writeToFile(f);
- logger.info("saved configuration to file: " + f.getPath());
- DialogUtil.showInfoDialog(frame, "Settings Saved", "Settings were saved successfully.");
- }
- }
-
- /**
- * Load settings from a properties file using a file chooser.
- */
- void loadSettings() {
- JFileChooser fc = new JFileChooser();
- fc.setDialogTitle("Load Settings");
- fc.setCurrentDirectory(new File("."));
- int r = fc.showDialog(frame, "Load ...");
- if (r == JFileChooser.APPROVE_OPTION) {
- File f = fc.getSelectedFile();
- loadConfiguration(new Configuration(f), true);
- logger.info("loaded configuration from file: " + f.getPath());
- DialogUtil.showInfoDialog(frame, "Settings Loaded", "Settings were loaded successfully.");
- }
- }
-
- /**
- * Maximize the application window.
- */
- void maximizeWindow() {
- frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
- }
-
- /**
- * Minimize the application window.
- */
- void minimizeWindow() {
- frame.setExtendedState(JFrame.ICONIFIED);
- }
-
- /**
- * Restore the default GUI layout.
- */
- void restoreDefaultWindow() {
- maximizeWindow();
- frame.restoreDefaults();
- }
-
- /**
- * Remove the currently selected file from the data source list.
- */
- void closeFile() {
- if (!configurationModel.getDataSourceType().equals(DataSourceType.ET_SERVER)) {
- DataSourceItem item = (DataSourceItem) frame.toolbarPanel.dataSourceComboBox.getSelectedItem();
- if (item.getPath().equals(configurationModel.getDataSourcePath())) {
- frame.toolbarPanel.dataSourceComboBox.removeItem(frame.toolbarPanel.dataSourceComboBox.getSelectedItem());
- }
- }
- }
-
+
/**
* Save a screenshot to a file using a file chooser.
*/
- void saveScreenshot() {
- JFileChooser fc = new JFileChooser();
+ private void saveScreenshot() {
+ final JFileChooser fc = new JFileChooser();
fc.setAcceptAllFileFilterUsed(false);
fc.setDialogTitle("Save Screenshot");
- FileNameExtensionFilter pngFilter = new FileNameExtensionFilter("png file (*.png)", "png");
- String format = pngFilter.getExtensions()[0];
+ final FileNameExtensionFilter pngFilter = new FileNameExtensionFilter("png file (*.png)", "png");
+ final String format = pngFilter.getExtensions()[0];
fc.addChoosableFileFilter(pngFilter);
fc.setCurrentDirectory(new File("."));
- int r = fc.showSaveDialog(frame);
- if (r == JFileChooser.APPROVE_OPTION) {
+ final int r = fc.showSaveDialog(this.frame);
+ if (r == JFileChooser.APPROVE_OPTION) {
String fileName = fc.getSelectedFile().getPath();
if (!fileName.endsWith("." + format)) {
fileName += "." + format;
}
- frame.repaint();
- Object lock = new Object();
- synchronized (lock) {
- try {
- lock.wait(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
+ /*
+ * final Object lock = new Object(); synchronized (lock) { try { lock.wait(500); } catch (final
+ * InterruptedException e) { e.printStackTrace(); } }
+ */
+ writeScreenshot(fileName, format);
+ DialogUtil.showInfoDialog(this.frame, "Screenshot Saved", "Screenshot was saved to file" + '\n' + fileName);
+ LOGGER.info("saved screenshot to " + fileName);
+ }
+ }
+
+ /**
+ * Save current settings to a file using a file chooser.
+ */
+ private void saveSettings() {
+ final JFileChooser fc = new JFileChooser();
+ fc.setDialogTitle("Save Configuration");
+ fc.setCurrentDirectory(new File("."));
+ final int r = fc.showSaveDialog(this.frame);
+ if (r == JFileChooser.APPROVE_OPTION) {
+ final File f = fc.getSelectedFile();
+ this.configurationModel.getConfiguration().writeToFile(f);
+ LOGGER.info("saved configuration to file: " + f.getPath());
+ DialogUtil.showInfoDialog(this.frame, "Settings Saved", "Settings were saved successfully.");
+ }
+ }
+
+ /**
+ * Export a JTable's data to a comma-delimited text file using a file chooser.
+ *
+ * @param table the table to export
+ */
+ private void saveTable(final JTable table) {
+ final JFileChooser fc = new JFileChooser();
+ fc.setDialogTitle("Save Table to Text File");
+ fc.setCurrentDirectory(new File("."));
+ final int r = fc.showSaveDialog(this.frame);
+ if (r == JFileChooser.APPROVE_OPTION) {
+ final String fileName = fc.getSelectedFile().getPath();
+ try {
+ TableExporter.export(table, fileName, ',');
+ LOGGER.info("saved table data to " + fileName);
+ DialogUtil.showInfoDialog(this.frame, "Table Data Saved", "The table was exported successfully.");
+ } catch (final IOException e) {
+ DialogUtil.showErrorDialog(this.frame, "Table Export Error", "The table export failed.");
+ LOGGER.warning("failed to save table data to " + fileName);
+ }
+ }
+ }
+
+ /**
+ * Set the log level from the configuration model.
+ */
+ private void setLogLevel() {
+ final Level newLevel = this.configurationModel.getLogLevel();
+ if (LOGGER.getLevel() != newLevel) {
+ LOGGER.setLevel(newLevel);
+ LOGGER.log(Level.INFO, "Log Level was changed to <" + this.configurationModel.getLogLevel().toString()
+ + ">");
+ }
+ }
+
+ /**
+ * Setup AIDA plotting into the GUI components.
+ */
+ private void setupAida() {
+ // Register the factory for displaying plots in tabs.
+ MonitoringAnalysisFactory.register();
+
+ // Set the root tab pane for displaying plots.
+ MonitoringPlotFactory.setRootPane(this.frame.getPlotPanel().getPlotPane());
+
+ // Setup the region listener to connect the plot info window.
+ MonitoringPlotFactory.setPlotterRegionListener(new PlotterRegionListener() {
+ @Override
+ public void regionSelected(final PlotterRegion region) {
+ if (region != null) {
+ MonitoringApplication.this.frame.getPlotInfoPanel().setCurrentRegion(region);
}
}
- writeScreenshot(fileName, format);
- DialogUtil.showInfoDialog(frame, "Screenshot Saved", "Screenshot was saved to file" + '\n' + fileName);
- logger.info("saved screenshot to " + fileName);
- }
+ });
+
+ // Perform global configuration of the JFreeChart back end.
+ AnalysisFactory.configure();
+ }
+
+ /**
+ * Setup the logger.
+ */
+ private void setupLogger() {
+ LOGGER.setUseParentHandlers(false);
+ this.logHandler = new LogHandler();
+ LOGGER.addHandler(this.logHandler);
+ this.streamHandler = new MonitoringApplicationStreamHandler(System.out);
+ LOGGER.addHandler(this.streamHandler);
+ for (final Handler handler : LOGGER.getHandlers()) {
+ handler.setLevel(DEFAULT_LEVEL);
+ }
+ LOGGER.setLevel(DEFAULT_LEVEL);
+ LOGGER.info("logging initialized");
+ }
+
+ /**
+ * Configure the system status monitor panel for a new job.
+ */
+ private void setupSystemStatusMonitor() {
+
+ // Clear the system status monitor table.
+ this.frame.getSystemStatusPanel().clear();
+
+ // Get the global registry of SystemStatus objects.
+ final SystemStatusRegistry registry = SystemStatusRegistry.getSystemStatusRegistery();
+
+ // Process the SystemStatus objects.
+ for (final SystemStatus systemStatus : registry.getSystemStatuses()) {
+ // This will add the status to the two tables.
+ this.frame.getSystemStatusPanel().addSystemStatus(systemStatus);
+ }
+
+ LOGGER.info("system status monitor initialized successfully");
+ }
+
+ /**
+ * Show the settings dialog window.
+ */
+ private void showSettingsDialog() {
+ this.frame.getSettingsDialog().setVisible(true);
+ }
+
+ /**
+ * Start the AIDA server instance.
+ */
+ private void startAIDAServer() {
+ if (this.configurationModel.hasValidProperty(ConfigurationModel.AIDA_SERVER_NAME_PROPERTY)) {
+ this.server.setName(this.configurationModel.getAIDAServerName());
+ }
+ final boolean started = this.server.start();
+ if (started) {
+ this.frame.getApplicationMenu().startAIDAServer();
+ LOGGER.info("AIDA server started at " + this.server.getName());
+ DialogUtil
+ .showInfoDialog(this.frame, "AIDA Server Started", "The remote AIDA server started successfully.");
+ } else {
+ LOGGER.warning("AIDA server failed to start");
+ DialogUtil.showErrorDialog(this.frame, "Failed to Start AIDA Server",
+ "The remote AIDA server failed to start.");
+ }
+ }
+
+ /**
+ * Start a new monitoring session.
+ */
+ private synchronized void startSession() {
+
+ LOGGER.info("starting new session");
+
+ try {
+
+ // Reset the plot panel and global AIDA state.
+ resetPlots();
+
+ // The system status registry is cleared here before any event processors
+ // which might create a SystemStatus are added to the event processing chain
+ // e.g. an LCSim Driver, etc.
+ SystemStatusRegistry.getSystemStatusRegistery().clear();
+
+ // List of extra composite record processors including the updater for the RunPanel.
+ final List<CompositeRecordProcessor> processors = new ArrayList<CompositeRecordProcessor>();
+ processors.add(this.frame.getEventDashboard().new EventDashboardUpdater());
+
+ // Add Driver to update the trigger diagnostics tables.
+ final List<Driver> drivers = new ArrayList<Driver>();
+ drivers.add(this.frame.getTriggerPanel().new TriggerDiagnosticGUIDriver());
+
+ // Add listener to push conditions changes to conditions panel.
+ final List<ConditionsListener> conditionsListeners = new ArrayList<ConditionsListener>();
+ conditionsListeners.add(this.frame.getConditionsPanel().new ConditionsPanelListener());
+
+ // Instantiate the event processing wrapper.
+ this.processing = new EventProcessing(this, processors, drivers, conditionsListeners);
+
+ // Connect to the ET system, if applicable.
+ this.processing.connect();
+
+ // Configure event processing from the global application settings, including setup of record loop.
+ LOGGER.info("setting up event processing on source " + this.configurationModel.getDataSourcePath()
+ + " with type " + this.configurationModel.getDataSourceType());
+ this.processing.setup(this.configurationModel);
+
+ // Setup the system status monitor table.
+ setupSystemStatusMonitor();
+
+ // Start the event processing thread.
+ this.processing.start();
+
+ LOGGER.info("new session successfully initialized");
+
+ } catch (final Exception e) {
+
+ // Disconnect from the ET system.
+ this.processing.disconnect();
+
+ // Log the error that occurred and show a pop up dialog.
+ this.errorHandler
+ .setError(e)
+ .log()
+ .printStackTrace()
+ .showErrorDialog(
+ "There was an error while starting the session." + '\n' + "See the log for details.",
+ "Session Error");
+
+ LOGGER.severe("failed to start new session");
+ }
+ }
+
+ /**
+ * Stop the AIDA server instance.
+ */
+ private void stopAIDAServer() {
+ this.server.disconnect();
+ this.frame.getApplicationMenu().stopAIDAServer();
+ LOGGER.info("AIDA server was stopped");
+ DialogUtil.showInfoDialog(this.frame, "AIDA Server Stopped", "The AIDA server was stopped.");
}
/**
* Save a screenshot to an output file.
- * @param fileName The name of the output file.
- */
- void writeScreenshot(String fileName, String format) {
- BufferedImage image = new BufferedImage(frame.getWidth(), frame.getHeight(), BufferedImage.TYPE_INT_RGB);
- frame.paint(image.getGraphics());
+ *
+ * @param fileName the name of the output file
+ * @param format the output file format (must be accepted by <code>ImageIO</code>)
+ */
+ private void writeScreenshot(final String fileName, final String format) {
+ this.frame.repaint();
+ final BufferedImage image = new BufferedImage(this.frame.getWidth(), this.frame.getHeight(),
+ BufferedImage.TYPE_INT_RGB);
+ this.frame.paint(image.getGraphics());
try {
ImageIO.write(image, format, new File(fileName));
- } catch (IOException e) {
- errorHandler.setError(e).setMessage("Failed to save screenshot.").printStackTrace().log().showErrorDialog();
- }
- }
-
- /**
- * Set the log level from the configuration model.
- */
- void setLogLevel() {
- Level newLevel = configurationModel.getLogLevel();
- if (logger.getLevel() != newLevel) {
- logger.setLevel(newLevel);
- logger.log(Level.INFO, "Log Level was changed to <" + configurationModel.getLogLevel().toString() + ">");
- }
- }
-
- /**
- * Export a JTable's data to a comma-delimited text file using a file chooser.
- */
- void saveTable(JTable table) {
- JFileChooser fc = new JFileChooser();
- fc.setDialogTitle("Save Table to Text File");
- fc.setCurrentDirectory(new File("."));
- int r = fc.showSaveDialog(frame);
- if (r == JFileChooser.APPROVE_OPTION) {
- String fileName = fc.getSelectedFile().getPath();
- try {
- TableExporter.export(table, fileName, ',');
- logger.info("saved table data to " + fileName);
- DialogUtil.showInfoDialog(frame, "Table Data Saved", "The table was exported successfully.");
- } catch (IOException e) {
- DialogUtil.showErrorDialog(frame, "Table Export Error", "The table export failed.");
- logger.warning("failed to save table data to " + fileName);
- }
- }
- }
-
- /**
- * Save the log table to a file using a file chooser.
- */
- void saveLogTable() {
- saveTable(frame.logPanel.logTable);
- }
-
- /**
- * 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.");
- }
-
- /**
- * Start the AIDA server instance.
- */
- void startAIDAServer() {
- if (configurationModel.hasValidProperty(ConfigurationModel.AIDA_SERVER_NAME_PROPERTY)) {
- server.setName(configurationModel.getAIDAServerName());
- }
- boolean started = server.start();
- if (started) {
- frame.menu.startAIDAServer();
- logger.info("AIDA server started at " + server.getName());
- DialogUtil.showInfoDialog(frame, "AIDA Server Started", "The remote AIDA server started successfully.");
- } else {
- logger.warning("AIDA server failed to start");
- DialogUtil.showErrorDialog(frame, "Failed to Start AIDA Server", "The remote AIDA server failed to start.");
- }
- }
-
- /**
- * Stop the AIDA server instance.
- */
- void stopAIDAServer() {
- server.disconnect();
- frame.menu.stopAIDAServer();
- logger.info("AIDA server was stopped");
- DialogUtil.showInfoDialog(frame, "AIDA Server Stopped", "The AIDA server was stopped.");
- }
-
- /**
- * Run the disconnection on a separate thread.
- */
- void runDisconnectThread() {
- new Thread() {
- public void run() {
- logger.fine("disconnect thread is running ...");
- connectionModel.setConnectionStatus(ConnectionStatus.DISCONNECTING);
- MonitoringApplication.this.processing.stop();
- logger.fine("disconnect thread finished!");
- }
- }.run();
- }
-}
+ } catch (final IOException e) {
+ this.errorHandler.setError(e).setMessage("Failed to save screenshot.").printStackTrace().log()
+ .showErrorDialog();
+ }
+ }
+}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java Tue Apr 21 14:48:39 2015
@@ -2,6 +2,7 @@
import java.awt.BorderLayout;
import java.awt.Dimension;
+import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
@@ -12,132 +13,283 @@
/**
* This class instantiates the primary GUI components of the monitoring application.
- *
- * @author Jeremy McCormick <[log in to unmask]>
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
@SuppressWarnings("serial")
-class MonitoringApplicationFrame extends JFrame {
-
- EventDashboard dashboardPanel;
- PlotPanel plotPanel;
- PlotInfoPanel plotInfoPanel;
- LogPanel logPanel;
- TriggerDiagnosticsPanel triggerPanel;
- ConditionsPanel conditionsPanel;
- SystemStatusPanel systemStatusPanel;
- ToolbarPanel toolbarPanel;
- MenuBar menu;
-
- JSplitPane mainSplitPane;
- JSplitPane rightSplitPane;
- JSplitPane leftSplitPane;
-
- SettingsDialog settingsDialog;
-
- static final Rectangle BOUNDS = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
- static final int PIXEL_WIDTH_MAX = (int) BOUNDS.getWidth();
- static final int PIXEL_HEIGHT_MAX = (int) BOUNDS.getHeight();
-
- /**
- *
- * @param listener
- */
- public MonitoringApplicationFrame(
- MonitoringApplication application) {
-
+final class MonitoringApplicationFrame extends JFrame {
+
+ /**
+ * The current graphics bounds.
+ */
+ private static final Rectangle BOUNDS = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
+
+ /**
+ * The maximum height of a window in pixels.
+ */
+ private static final int PIXEL_HEIGHT_MAX = (int) BOUNDS.getHeight();
+
+ /**
+ * The maximum width of a window in pixels.
+ */
+ private static final int PIXEL_WIDTH_MAX = (int) BOUNDS.getWidth();
+
+ /**
+ * The conditions panel.
+ */
+ private final ConditionsPanel conditionsPanel;
+
+ /**
+ * The dashboard panel.
+ */
+ private final EventDashboard dashboardPanel;
+
+ /**
+ * The left split pane that divides the dashboard and the tabs.
+ */
+ private final JSplitPane leftSplitPane;
+
+ /**
+ * The log panel.
+ */
+ private final LogPanel logPanel;
+
+ /**
+ * The primary split pain dividing the left and right panels.
+ */
+ private final JSplitPane mainSplitPane;
+
+ /**
+ * The application's menu bar.
+ */
+ private final MenuBar menu;
+
+ /**
+ * The plot info panel.
+ */
+ private final PlotInfoPanel plotInfoPanel;
+
+ /**
+ * The plot panel.
+ */
+ private final PlotPanel plotPanel;
+
+ /**
+ * The right split pane showing plots and statistics.
+ */
+ private final JSplitPane rightSplitPane;
+
+ /**
+ * The settings dialog window.
+ */
+ private final SettingsDialog settingsDialog;
+
+ /**
+ * The system status panel which shows under the tabs.
+ */
+ private final SystemStatusPanel systemStatusPanel;
+
+ /**
+ * The toolbar panel with the buttons, data source and connection information.
+ */
+ private final ToolbarPanel toolbarPanel;
+
+ /**
+ * The trigger diagnostics panel.
+ */
+ private final TriggerDiagnosticsPanel triggerPanel;
+
+ /**
+ * Class constructor.
+ *
+ * @param application the associated application object
+ */
+ public MonitoringApplicationFrame(final MonitoringApplication application) {
+
// Disable interaction until specifically enabled externally after initialization.
- setEnabled(false);
-
+ this.setEnabled(false);
+
// Create the content panel.
- JPanel contentPanel = new JPanel();
- setContentPane(contentPanel);
+ final JPanel contentPanel = new JPanel();
+ this.setContentPane(contentPanel);
contentPanel.setLayout(new BorderLayout());
contentPanel.setOpaque(true);
contentPanel.setPreferredSize(new Dimension(PIXEL_WIDTH_MAX, PIXEL_HEIGHT_MAX));
-
+
// Create the top panel.
- toolbarPanel = new ToolbarPanel(application.configurationModel, application.connectionModel, application);
- contentPanel.add(toolbarPanel, BorderLayout.NORTH);
-
+ this.toolbarPanel = new ToolbarPanel(application.getConfigurationModel(), application.getConnectionModel(),
+ application);
+ contentPanel.add(this.toolbarPanel, BorderLayout.NORTH);
+
// Create the bottom panel.
- JPanel bottomPanel = new JPanel();
+ final JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BorderLayout());
contentPanel.add(bottomPanel, BorderLayout.CENTER);
-
+
// Create the left panel.
- JPanel leftPanel = new JPanel();
+ final JPanel leftPanel = new JPanel();
leftPanel.setLayout(new BorderLayout());
-
+
// Create the run dashboard.
- dashboardPanel = new EventDashboard(application.runModel);
+ this.dashboardPanel = new EventDashboard(application.getRunModel());
// Create the tabbed pane for content in bottom of left panel such as log table and system monitor.
- JTabbedPane tableTabbedPane = new JTabbedPane();
-
+ final JTabbedPane tableTabbedPane = new JTabbedPane();
+
// Create the log table and add it to the tabs.
- logPanel = new LogPanel(application.configurationModel, application);
- tableTabbedPane.addTab("Log Messages", logPanel);
-
+ this.logPanel = new LogPanel(application.getConfigurationModel(), application);
+ tableTabbedPane.addTab("Log Messages", this.logPanel);
+
// Create the system monitor.
- //systemStatusTable = new SystemStatusTable();
- systemStatusPanel = new SystemStatusPanel();
- tableTabbedPane.addTab("System Status Monitor", systemStatusPanel);
-
+ // systemStatusTable = new SystemStatusTable();
+ this.systemStatusPanel = new SystemStatusPanel();
+ tableTabbedPane.addTab("System Status Monitor", this.systemStatusPanel);
+
// Add the trigger diagnostics tables.
- triggerPanel = new TriggerDiagnosticsPanel();
- tableTabbedPane.addTab("Trigger Diagnostics", triggerPanel);
-
+ this.triggerPanel = new TriggerDiagnosticsPanel();
+ tableTabbedPane.addTab("Trigger Diagnostics", this.triggerPanel);
+
// Add the conditions panel.
- conditionsPanel = new ConditionsPanel();
- tableTabbedPane.addTab("Detector Conditions", conditionsPanel);
-
+ this.conditionsPanel = new ConditionsPanel();
+ tableTabbedPane.addTab("Detector Conditions", this.conditionsPanel);
+
// Vertical split pane in left panel.
- leftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, dashboardPanel, tableTabbedPane);
- leftSplitPane.setDividerLocation(250);
- leftPanel.add(leftSplitPane, BorderLayout.CENTER);
-
+ this.leftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, this.dashboardPanel, tableTabbedPane);
+ this.leftSplitPane.setDividerLocation(250);
+ leftPanel.add(this.leftSplitPane, BorderLayout.CENTER);
+
// Create the right panel.
- JPanel rightPanel = new JPanel();
+ final JPanel rightPanel = new JPanel();
rightPanel.setLayout(new BorderLayout());
-
+
// Create the plot info panel.
- plotInfoPanel = new PlotInfoPanel();
-
+ this.plotInfoPanel = new PlotInfoPanel();
+
// Create the plot panel.
- plotPanel = new PlotPanel();
- plotInfoPanel.saveButton.addActionListener(plotPanel);
-
+ this.plotPanel = new PlotPanel();
+ this.plotInfoPanel.addActionListener(this.plotPanel);
+
// Create the right panel vertical split pane for displaying plots and their information and statistics.
- rightSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, plotPanel, plotInfoPanel);
- rightSplitPane.setDividerLocation(680);
- rightPanel.add(rightSplitPane, BorderLayout.CENTER);
-
+ this.rightSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, this.plotPanel, this.plotInfoPanel);
+ this.rightSplitPane.setDividerLocation(680);
+ rightPanel.add(this.rightSplitPane, BorderLayout.CENTER);
+
// Create the main horizontal split pane for dividing the left and right panels.
- mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel);
- mainSplitPane.setDividerLocation(600);
- bottomPanel.add(mainSplitPane, BorderLayout.CENTER);
-
+ this.mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel);
+ this.mainSplitPane.setDividerLocation(600);
+ bottomPanel.add(this.mainSplitPane, BorderLayout.CENTER);
+
// Create the menu bar.
- menu = new MenuBar(application.configurationModel, application.connectionModel, application);
- setJMenuBar(menu);
- toolbarPanel.dataSourceComboBox.addActionListener(menu);
-
+ this.menu = new MenuBar(application.getConfigurationModel(), application.getConnectionModel(), application);
+ this.setJMenuBar(this.menu);
+ this.toolbarPanel.getDataSourceComboBox().addActionListener(this.menu);
+
// Setup the settings dialog box (invisible until activated).
- settingsDialog = new SettingsDialog(application.configurationModel, application);
-
- // Setup the frame now that all components have been added.
- pack();
- setExtendedState(JFrame.MAXIMIZED_BOTH);
- setVisible(true);
- }
-
+ this.settingsDialog = new SettingsDialog(application.getConfigurationModel(), application);
+
+ // Setup the frame now that all components have been added.
+ this.pack();
+ this.setExtendedState(Frame.MAXIMIZED_BOTH);
+ this.setVisible(true);
+ }
+
+ /**
+ * Get the application menu.
+ *
+ * @return the application menu
+ */
+ MenuBar getApplicationMenu() {
+ return this.menu;
+ }
+
+ /**
+ * Get the panel showing conditions information.
+ *
+ * @return the conditions panel
+ */
+ ConditionsPanel getConditionsPanel() {
+ return this.conditionsPanel;
+ }
+
+ /**
+ * Get the panel for the dashboard.
+ *
+ * @return the dashboard panel
+ */
+ EventDashboard getEventDashboard() {
+ return this.dashboardPanel;
+ }
+
+ /**
+ * Get the panel that shows the log table and controls.
+ *
+ * @return the log panel
+ */
+ LogPanel getLogPanel() {
+ return this.logPanel;
+ }
+
+ /**
+ * Get the plot info panel that shows plot statistics.
+ *
+ * @return the plot info panel
+ */
+ PlotInfoPanel getPlotInfoPanel() {
+ return this.plotInfoPanel;
+ }
+
+ /**
+ * Get the plot panel for displaying AIDA plots.
+ *
+ * @return the plot panel
+ */
+ PlotPanel getPlotPanel() {
+ return this.plotPanel;
+ }
+
+ /**
+ * Get the settings dialog window.
+ *
+ * @return the settings dialog window
+ */
+ SettingsDialog getSettingsDialog() {
+ return this.settingsDialog;
+ }
+
+ /**
+ * Get the system status panel.
+ *
+ * @return the system status panel
+ */
+ SystemStatusPanel getSystemStatusPanel() {
+ return this.systemStatusPanel;
+ }
+
+ /**
+ * Get the toolbar panel with the buttons etc.
+ *
+ * @return the toolbar panel
+ */
+ ToolbarPanel getToolbarPanel() {
+ return this.toolbarPanel;
+ }
+
+ /**
+ * Get the trigger diagnostics panel.
+ *
+ * @return the trigger diagnostics panel
+ */
+ TriggerDiagnosticsPanel getTriggerPanel() {
+ return this.triggerPanel;
+ }
+
/**
* Restore default window settings.
*/
void restoreDefaults() {
- setExtendedState(JFrame.MAXIMIZED_BOTH);
- mainSplitPane.resetToPreferredSizes();
- leftSplitPane.resetToPreferredSizes();
- rightSplitPane.resetToPreferredSizes();
- }
-}
+ this.setExtendedState(Frame.MAXIMIZED_BOTH);
+ this.mainSplitPane.resetToPreferredSizes();
+ this.leftSplitPane.resetToPreferredSizes();
+ this.rightSplitPane.resetToPreferredSizes();
+ }
+}
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 Apr 21 14:48:39 2015
@@ -38,149 +38,284 @@
/**
* <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 application.
+ * This is a GUI component for showing the statistics and other information about an AIDA plot when it is clicked on in
+ * the monitoring application.
* <p>
* The information in the table is updated dynamically via the <code>AIDAObserver</code> API on the AIDA object.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class PlotInfoPanel extends JPanel implements AIDAListener, ActionListener, FunctionListener {
-
- JComboBox<Object> plotComboBox;
- JTable infoTable = new JTable();
- DefaultTableModel model;
- JButton saveButton;
-
- PlotterRegion currentRegion;
- Object currentObject;
-
- static final int MAX_ROWS = 13;
- static final int MIN_WIDTH = 400;
- static final int MIN_HEIGHT = 300;
- static final String[] COLUMN_NAMES = { "Field", "Value" };
- static final String PLOT_SELECTED = "PlotSelected";
-
- Timer timer = new Timer();
+@SuppressWarnings("serial")
+final class PlotInfoPanel extends JPanel implements AIDAListener, ActionListener, FunctionListener, AddActionListener {
+
+ /**
+ * The names of the two columns.
+ */
+ private static final String[] COLUMN_NAMES = {"Field", "Value"};
+
+ /**
+ * The maximum number of rows in the table.
+ */
+ private static final int MAX_ROWS = 13;
+
+ /**
+ * Minimum height of panel in pixels.
+ */
+ private static final int MIN_HEIGHT = 300;
+
+ /**
+ * Minimum width of panel in pixels.
+ */
+ private static final int MIN_WIDTH = 400;
+
+ /**
+ * The currently selected AIDA object.
+ */
+ private Object currentObject;
+
+ /**
+ * The currently selected plotter region.
+ */
+ private PlotterRegion currentRegion;
+
+ /**
+ * The table showing plot statistics.
+ */
+ private final JTable infoTable = new JTable();
+
+ /**
+ * The default table model.
+ */
+ private DefaultTableModel model;
+
+ /**
+ * The combo box for selecting the object from the region.
+ */
+ private JComboBox<Object> plotComboBox;
+
+ /**
+ * The button for saving plot graphics..
+ */
+ private JButton saveButton;
+
+ /**
+ * The timer for updating the table.
+ */
+ private final Timer timer = new Timer();
/**
* Class constructor, which will setup the GUI components.
*/
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({"unchecked"})
PlotInfoPanel() {
-
- setLayout(new FlowLayout(FlowLayout.CENTER));
-
- JPanel leftPanel = new JPanel();
+
+ this.setLayout(new FlowLayout(FlowLayout.CENTER));
+
+ final JPanel leftPanel = new JPanel();
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS));
leftPanel.setPreferredSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
-
- Dimension filler = new Dimension(0, 10);
-
+
+ final Dimension filler = new Dimension(0, 10);
+
// Save button.
- saveButton = new JButton("Save Plots ...");
- saveButton.setActionCommand(Commands.SAVE_SELECTED_PLOTS);
- saveButton.setAlignmentX(CENTER_ALIGNMENT);
- leftPanel.add(saveButton);
-
+ this.saveButton = new JButton("Save Current Plot Tab ...");
+ this.saveButton.setActionCommand(Commands.SAVE_SELECTED_PLOTS);
+ this.saveButton.setAlignmentX(CENTER_ALIGNMENT);
+ leftPanel.add(this.saveButton);
+
leftPanel.add(new Box.Filler(filler, filler, filler));
// Combo box for selecting plotted object.
- plotComboBox = new JComboBox<Object>() {
+ this.plotComboBox = new JComboBox<Object>() {
+ @Override
public Dimension getMaximumSize() {
- Dimension max = super.getMaximumSize();
- max.height = getPreferredSize().height;
+ final Dimension max = super.getMaximumSize();
+ max.height = this.getPreferredSize().height;
return max;
}
};
- plotComboBox.setActionCommand(PLOT_SELECTED);
- plotComboBox.setAlignmentX(CENTER_ALIGNMENT);
- plotComboBox.setRenderer(new BasicComboBoxRenderer() {
+ this.plotComboBox.setActionCommand(Commands.PLOT_SELECTED);
+ this.plotComboBox.setAlignmentX(CENTER_ALIGNMENT);
+ this.plotComboBox.setRenderer(new BasicComboBoxRenderer() {
+ @Override
@SuppressWarnings("rawtypes")
- public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ public Component getListCellRendererComponent(final JList list, final Object value, final int index,
+ final boolean isSelected, final boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value != null) {
- String title = getObjectTitle(value);
- setText(value.getClass().getSimpleName() + " - " + title);
+ final String title = PlotInfoPanel.this.getObjectTitle(value);
+ this.setText(value.getClass().getSimpleName() + " - " + title);
} else {
- setText("Click on a plot region ...");
+ this.setText("Click on a plot region ...");
}
return this;
}
});
- plotComboBox.addActionListener(this);
- leftPanel.add(plotComboBox);
-
+ this.plotComboBox.addActionListener(this);
+ leftPanel.add(this.plotComboBox);
+
leftPanel.add(new Box.Filler(filler, filler, filler));
-
+
// Table with plot info.
- String data[][] = new String[0][0];
- model = new DefaultTableModel(data, COLUMN_NAMES);
- model.setColumnIdentifiers(COLUMN_NAMES);
- infoTable.setModel(model);
- ((DefaultTableModel)infoTable.getModel()).setRowCount(MAX_ROWS);
- infoTable.setAlignmentX(CENTER_ALIGNMENT);
- leftPanel.add(infoTable);
-
- add(leftPanel);
- }
-
- /**
- * This method will be called when the backing AIDA object is updated and a state change is
- * fired via the <code>AIDAObservable</code> API. The table is updated to reflect the new state
- * of the object.
- * @param evt The EventObject pointing to the backing AIDA object.
+ final String[][] data = new String[0][0];
+ this.model = new DefaultTableModel(data, COLUMN_NAMES);
+ this.model.setColumnIdentifiers(COLUMN_NAMES);
+ this.infoTable.setModel(this.model);
+ ((DefaultTableModel) this.infoTable.getModel()).setRowCount(MAX_ROWS);
+ this.infoTable.setAlignmentX(CENTER_ALIGNMENT);
+ leftPanel.add(this.infoTable);
+
+ this.add(leftPanel);
+ }
+
+ /**
+ * Implementation of <code>actionPerformed</code> to handle the selection of a new object from the combo box.
+ *
+ * @param e the {@link java.awt.event.ActionEvent} to handle
*/
@Override
- public void stateChanged(final EventObject evt) {
-
- // Make a timer task for running the update.
- TimerTask task = new TimerTask() {
- public void run() {
-
- // Is the state change from the current AIDAObservable?
- if (evt.getSource() != currentObject) {
- // Assume this means that a different AIDAObservable was selected in the GUI.
- return;
- }
-
- // Update the table values on the Swing EDT.
- runUpdateTable();
-
- // Set the observable to valid so subsequent state changes are received.
- ((AIDAObservable) currentObject).setValid((AIDAListener) PlotInfoPanel.this);
- }
- };
-
- /*
- * Schedule the task to run in ~0.5 seconds. If the Runnable runs immediately, somehow the
- * observable state gets permanently set to invalid and additional state changes will not be
- * received!
- */
- timer.schedule(task, 500);
- }
-
- /**
- * Implementation of <code>actionPerformed</code> to handle the selection of a new object from
- * the combo box.
+ public void actionPerformed(final ActionEvent e) {
+ // Is there a new item selected in the combo box?
+ if (Commands.PLOT_SELECTED.equals(e.getActionCommand())) {
+ if (this.plotComboBox.getSelectedItem() != null) {
+ // Set the current object from the combo box value, to update the GUI state.
+ this.setCurrentObject(this.plotComboBox.getSelectedItem());
+ }
+ }
+ }
+
+ /**
+ * Assign an action listener to certain components.
+ *
+ * @param listener the action listener to add
*/
@Override
- public void actionPerformed(ActionEvent e) {
- // Is there a new item selected in the combo box?
- if (PLOT_SELECTED.equals(e.getActionCommand())) {
- if (plotComboBox.getSelectedItem() != null) {
- // Set the current object from the combo box value, to update the GUI state.
- setCurrentObject(plotComboBox.getSelectedItem());
- }
- }
- }
-
- /**
- * Get the title of an AIDA object. Unfortunately there is no base type with this information,
- * so it is read manually from each possible type.
- * @param object The AIDA object.
- * @return The title of the object from its title method or value of its toString method, if
- * none exists.
- */
- String getObjectTitle(Object object) {
+ public void addActionListener(final ActionListener listener) {
+ this.saveButton.addActionListener(listener);
+ }
+
+ /**
+ * Add this object as an <code>AIDAListener</code> on the current <code>AIDAObservable</code>.
+ */
+ private void addListener() {
+ if (this.currentObject instanceof AIDAObservable && !(this.currentObject instanceof FunctionDispatcher)) {
+ // Setup a listener on the current AIDA object.
+ final AIDAObservable observable = (AIDAObservable) this.currentObject;
+ observable.addListener(this);
+ observable.setValid(this);
+ observable.setConnected(true);
+ } else if (this.currentObject instanceof IFunction) {
+ if (this.currentObject instanceof FunctionDispatcher) {
+ ((FunctionDispatcher) this.currentObject).addFunctionListener(this);
+ }
+ }
+ }
+
+ /**
+ * Add a row to the info table.
+ *
+ * @param field the field name
+ * @param value the field value
+ */
+ private void addRow(final String field, final Object value) {
+ this.model.insertRow(this.infoTable.getRowCount(), new Object[] {field, value});
+ }
+
+ /**
+ * Add rows to the info table from the state of a 2D cloud.
+ *
+ * @param cloud the AIDA object
+ */
+ private void addRows(final ICloud2D cloud) {
+ this.addRow("title", cloud.title());
+ this.addRow("entries", cloud.entries());
+ this.addRow("max entries", cloud.maxEntries());
+ this.addRow("x lower edge", cloud.lowerEdgeX());
+ this.addRow("x upper edge", cloud.upperEdgeX());
+ this.addRow("y lower edge", cloud.lowerEdgeY());
+ this.addRow("y upper edge", cloud.upperEdgeY());
+ this.addRow("x mean", String.format("%.10f%n", cloud.meanX()));
+ this.addRow("y mean", String.format("%.10f%n", cloud.meanY()));
+ this.addRow("x rms", String.format("%.10f%n", cloud.rmsX()));
+ this.addRow("y rms", String.format("%.10f%n", cloud.rmsY()));
+ }
+
+ /**
+ * Add rows to the info table from the state of a function.
+ *
+ * @param function the AIDA function object
+ */
+ private void addRows(final IFunction function) {
+ this.addRow("title", function.title());
+
+ // Add generically the values of all function parameters.
+ for (final String parameter : function.parameterNames()) {
+ this.addRow(parameter, function.parameter(parameter));
+ }
+ }
+
+ /**
+ * Add rows to the info table from the state of a 1D histogram.
+ *
+ * @param histogram the AIDA object
+ */
+ private void addRows(final IHistogram1D histogram) {
+ this.addRow("title", histogram.title());
+ this.addRow("bins", histogram.axis().bins());
+ this.addRow("entries", histogram.entries());
+ this.addRow("mean", String.format("%.10f%n", histogram.mean()));
+ this.addRow("rms", String.format("%.10f%n", histogram.rms()));
+ this.addRow("sum bin heights", histogram.sumBinHeights());
+ this.addRow("max bin height", histogram.maxBinHeight());
+ this.addRow("overflow entries", histogram.binEntries(IAxis.OVERFLOW_BIN));
+ this.addRow("underflow entries", histogram.binEntries(IAxis.UNDERFLOW_BIN));
+ }
+
+ /**
+ * Add rows to the info table from the state of a 2D histogram.
+ *
+ * @param histogram the AIDA object
+ */
+ private void addRows(final IHistogram2D histogram) {
+ this.addRow("title", histogram.title());
+ this.addRow("x bins", histogram.xAxis().bins());
+ this.addRow("y bins", histogram.yAxis().bins());
+ this.addRow("entries", histogram.entries());
+ this.addRow("x mean", String.format("%.10f%n", histogram.meanX()));
+ this.addRow("y mean", String.format("%.10f%n", histogram.meanY()));
+ this.addRow("x rms", String.format("%.10f%n", histogram.rmsX()));
+ this.addRow("y rms", String.format("%.10f%n", histogram.rmsY()));
+ this.addRow("sum bin heights", histogram.sumBinHeights());
+ this.addRow("max bin height", histogram.maxBinHeight());
+ this.addRow("x overflow entries", histogram.binEntriesX(IAxis.OVERFLOW_BIN));
+ this.addRow("y overflow entries", histogram.binEntriesY(IAxis.OVERFLOW_BIN));
+ this.addRow("x underflow entries", histogram.binEntriesX(IAxis.UNDERFLOW_BIN));
+ this.addRow("y underflow entries", histogram.binEntriesY(IAxis.UNDERFLOW_BIN));
+ }
+
+ /**
+ * Callback for updating from changed to <code>IFunction</code> object.
+ *
+ * @param event the change event (unused in this method)
+ */
+ @Override
+ public void functionChanged(final FunctionChangedEvent event) {
+ try {
+ this.runUpdateTable();
+ } catch (final Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Get the title of an AIDA object. Unfortunately there is no base type with this information, so it is read
+ * manually from each possible type.
+ *
+ * @param object the AIDA object
+ * @return the title of the object from its title method or value of its <code>toString</code> method, if none
+ * exists
+ */
+ private String getObjectTitle(final Object object) {
if (object instanceof IBaseHistogram) {
return ((IBaseHistogram) object).title();
} else if (object instanceof IDataPointSet) {
@@ -193,226 +328,166 @@
}
/**
- * Set the current plotter region, which will rebuild the GUI accordingly.
- * @param region The current plotter region.
- */
- synchronized void setCurrentRegion(PlotterRegion region) {
- if (region != currentRegion) {
- currentRegion = region;
- updateComboBox();
- setCurrentObject(plotComboBox.getSelectedItem());
- setupContentPane();
- }
- }
-
- /**
- * Configure the frame's content panel from current component settings.
- */
- void setupContentPane() {
- plotComboBox.setSize(plotComboBox.getPreferredSize());
- infoTable.setSize(infoTable.getPreferredSize());
- setVisible(true);
- }
-
- /**
- * Update the info table from the state of the current AIDA object.
- */
- void updateTable() {
- model.setRowCount(0);
- if (currentObject instanceof IHistogram1D) {
- addRows((IHistogram1D) currentObject);
- } else if (currentObject instanceof IHistogram2D) {
- addRows((IHistogram2D) currentObject);
- } else if (currentObject instanceof ICloud2D) {
- addRows((ICloud2D) currentObject);
- } else if (currentObject instanceof ICloud1D) {
- if (((ICloud1D) currentObject).isConverted()) {
- addRows(((ICloud1D) currentObject).histogram());
- }
- } else if (currentObject instanceof IFunction) {
- addRows((IFunction) currentObject);
- }
- }
-
- /**
- * Run the {@link #updateTable()} method on the Swing EDT.
- */
- void runUpdateTable() {
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- updateTable();
- }
- });
- }
-
- /**
- * Update the combo box contents with the plots from the current region.
- */
- void updateComboBox() {
- plotComboBox.removeAllItems();
- List<Object> objects = currentRegion.getPlottedObjects();
- for (Object object : objects) {
- if (isValidObject(object)) {
- plotComboBox.addItem(object);
- }
- }
- }
-
- boolean isValidObject(Object object) {
- if (object == null)
+ * Return <code>true</code> if the object is a valid AIDA object.
+ *
+ * @param object the object
+ * @return <code>true</code> if object is a valid AIDA object
+ */
+ private boolean isValidObject(final Object object) {
+ if (object == null) {
return false;
+ }
if (object instanceof IBaseHistogram || object instanceof IFunction || object instanceof IDataPointSet) {
return true;
- }
+ }
return false;
}
/**
- * Add rows to the info table from the state of a 1D histogram.
- * @param histogram The AIDA object.
- */
- void addRows(IHistogram1D histogram) {
- addRow("title", histogram.title());
- addRow("bins", histogram.axis().bins());
- addRow("entries", histogram.entries());
- addRow("mean", String.format("%.10f%n", histogram.mean()));
- addRow("rms", String.format("%.10f%n", histogram.rms()));
- addRow("sum bin heights", histogram.sumBinHeights());
- addRow("max bin height", histogram.maxBinHeight());
- addRow("overflow entries", histogram.binEntries(IAxis.OVERFLOW_BIN));
- addRow("underflow entries", histogram.binEntries(IAxis.UNDERFLOW_BIN));
- }
-
- /**
- * Add rows to the info table from the state of a 2D histogram.
- * @param histogram The AIDA object.
- */
- void addRows(IHistogram2D histogram) {
- addRow("title", histogram.title());
- addRow("x bins", histogram.xAxis().bins());
- addRow("y bins", histogram.yAxis().bins());
- addRow("entries", histogram.entries());
- addRow("x mean", String.format("%.10f%n", histogram.meanX()));
- addRow("y mean", String.format("%.10f%n", histogram.meanY()));
- addRow("x rms", String.format("%.10f%n", histogram.rmsX()));
- addRow("y rms", String.format("%.10f%n", histogram.rmsY()));
- addRow("sum bin heights", histogram.sumBinHeights());
- addRow("max bin height", histogram.maxBinHeight());
- addRow("x overflow entries", histogram.binEntriesX(IAxis.OVERFLOW_BIN));
- addRow("y overflow entries", histogram.binEntriesY(IAxis.OVERFLOW_BIN));
- addRow("x underflow entries", histogram.binEntriesX(IAxis.UNDERFLOW_BIN));
- addRow("y underflow entries", histogram.binEntriesY(IAxis.UNDERFLOW_BIN));
- }
-
- /**
- * Add rows to the info table from the state of a 2D cloud.
- * @param cloud The AIDA object.
- */
- void addRows(ICloud2D cloud) {
- addRow("title", cloud.title());
- addRow("entries", cloud.entries());
- addRow("max entries", cloud.maxEntries());
- addRow("x lower edge", cloud.lowerEdgeX());
- addRow("x upper edge", cloud.upperEdgeX());
- addRow("y lower edge", cloud.lowerEdgeY());
- addRow("y upper edge", cloud.upperEdgeY());
- addRow("x mean", String.format("%.10f%n", cloud.meanX()));
- addRow("y mean", String.format("%.10f%n", cloud.meanY()));
- addRow("x rms", String.format("%.10f%n", cloud.rmsX()));
- addRow("y rms", String.format("%.10f%n", cloud.rmsY()));
- }
-
- /**
- * Add rows to the info table from the state of a 2D cloud.
- * @param cloud The AIDA object.
- */
- void addRows(IFunction function) {
- addRow("title", function.title());
-
- // Add generically the values of all function parameters.
- for (String parameter : function.parameterNames()) {
- addRow(parameter, function.parameter(parameter));
- }
- }
-
- /**
- * Add a row to the info table.
- * @param field The field name.
- * @param value The field value.
- */
- void addRow(String field, Object value) {
- model.insertRow(infoTable.getRowCount(), new Object[] { field, value });
- }
-
- /**
- * Set the current AIDA object that backs this GUI, i.e. an IHistogram1D etc.
- * @param object The backing AIDA object.
- */
- synchronized void setCurrentObject(Object object) {
-
- if (object == null)
+ * Remove this as a listener on the current AIDA object.
+ */
+ private void removeListener() {
+ if (this.currentObject != null) {
+ if (this.currentObject instanceof AIDAObservable && !(this.currentObject instanceof IFunction)) {
+ // Remove this object as an listener on the AIDA observable.
+ ((AIDAObservable) this.currentObject).removeListener(this);
+ } else if (this.currentObject instanceof FunctionDispatcher) {
+ // Remove this object as function listener.
+ ((FunctionDispatcher) this.currentObject).removeFunctionListener(this);
+ }
+ }
+ }
+
+ /**
+ * Run the {@link #updateTable()} method on the Swing EDT.
+ */
+ private void runUpdateTable() {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ PlotInfoPanel.this.updateTable();
+ }
+ });
+ }
+
+ /**
+ * Set the current AIDA object that backs this GUI, i.e. an IHistogram1D or other plot object etc.
+ *
+ * @param object the backing AIDA object
+ */
+ private synchronized void setCurrentObject(final Object object) {
+
+ if (object == null) {
throw new IllegalArgumentException("The object arg is null!");
-
- if (object == currentObject)
+ }
+
+ if (object == this.currentObject) {
return;
+ }
// Remove the AIDAListener from the previous object.
- removeListener();
+ this.removeListener();
// Set the current object reference.
- currentObject = object;
+ this.currentObject = object;
// Update the table immediately with information from the current object.
// We need to wait for this the first time, so we know the preferred size
// of the table GUI component when resizing the content pane.
- updateTable();
+ this.updateTable();
// Add an AIDAListener to the AIDA object via the AIDAObservable API.
- addListener();
- }
-
- /**
- * Remove this as a listener on the current AIDA object.
- */
- void removeListener() {
- if (currentObject != null) {
- if (currentObject instanceof AIDAObservable && !(currentObject instanceof IFunction)) {
- // Remove this object as an listener on the AIDA observable.
- ((AIDAObservable) currentObject).removeListener(this);
- } else if (currentObject instanceof FunctionDispatcher) {
- // Remove this object as function listener.
- ((FunctionDispatcher)currentObject).removeFunctionListener(this);
- }
- }
- }
-
- /**
- * Add this object as an <code>AIDAListener</code> on the current <code>AIDAObservable</code>.
- */
- void addListener() {
- if (currentObject instanceof AIDAObservable && !(currentObject instanceof FunctionDispatcher)) {
- // Setup a listener on the current AIDA object.
- AIDAObservable observable = (AIDAObservable) currentObject;
- observable.addListener(this);
- observable.setValid(this);
- observable.setConnected(true);
- } else if (currentObject instanceof IFunction) {
- if (currentObject instanceof FunctionDispatcher) {
- ((FunctionDispatcher)currentObject).addFunctionListener(this);
- }
- }
- }
-
- /**
- * Callback for updating from changed to <code>IFunction</code> object.
- * @param event The change event (unused in this method).
+ this.addListener();
+ }
+
+ /**
+ * Set the current plotter region, which will rebuild the GUI accordingly.
+ *
+ * @param region The current plotter region.
+ */
+ synchronized void setCurrentRegion(final PlotterRegion region) {
+ if (region != this.currentRegion) {
+ this.currentRegion = region;
+ this.updateComboBox();
+ this.setCurrentObject(this.plotComboBox.getSelectedItem());
+ this.setupContentPane();
+ }
+ }
+
+ /**
+ * Configure the frame's content panel from current component settings.
+ */
+ private void setupContentPane() {
+ this.plotComboBox.setSize(this.plotComboBox.getPreferredSize());
+ this.infoTable.setSize(this.infoTable.getPreferredSize());
+ this.setVisible(true);
+ }
+
+ /**
+ * This method will be called when the backing AIDA object is updated and a state change is fired via the
+ * <code>AIDAObservable</code> API. The table is updated to reflect the new state of the object.
+ *
+ * @param evt the EventObject pointing to the backing AIDA object
*/
@Override
- public void functionChanged(FunctionChangedEvent event) {
- try {
- runUpdateTable();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
+ public void stateChanged(final EventObject evt) {
+
+ // Make a timer task for running the update.
+ final TimerTask task = new TimerTask() {
+ @Override
+ public void run() {
+
+ // Is the state change from the current AIDAObservable?
+ if (evt.getSource() != PlotInfoPanel.this.currentObject) {
+ // Assume this means that a different AIDAObservable was selected in the GUI.
+ return;
+ }
+
+ // Update the table values on the Swing EDT.
+ PlotInfoPanel.this.runUpdateTable();
+
+ // Set the observable to valid so subsequent state changes are received.
+ ((AIDAObservable) PlotInfoPanel.this.currentObject).setValid(PlotInfoPanel.this);
+ }
+ };
+
+ /*
+ * Schedule the task to run in ~0.5 seconds. If the Runnable runs immediately, somehow the observable state gets
+ * permanently set to invalid and additional state changes will not be received!
+ */
+ this.timer.schedule(task, 500);
+ }
+
+ /**
+ * Update the combo box contents with the plots from the current region.
+ */
+ private void updateComboBox() {
+ this.plotComboBox.removeAllItems();
+ final List<Object> objects = this.currentRegion.getPlottedObjects();
+ for (final Object object : objects) {
+ if (this.isValidObject(object)) {
+ this.plotComboBox.addItem(object);
+ }
+ }
+ }
+
+ /**
+ * Update the info table from the state of the current AIDA object.
+ */
+ private void updateTable() {
+ this.model.setRowCount(0);
+ if (this.currentObject instanceof IHistogram1D) {
+ this.addRows((IHistogram1D) this.currentObject);
+ } else if (this.currentObject instanceof IHistogram2D) {
+ this.addRows((IHistogram2D) this.currentObject);
+ } else if (this.currentObject instanceof ICloud2D) {
+ this.addRows((ICloud2D) this.currentObject);
+ } else if (this.currentObject instanceof ICloud1D) {
+ if (((ICloud1D) this.currentObject).isConverted()) {
+ this.addRows(((ICloud1D) this.currentObject).histogram());
+ }
+ } else if (this.currentObject instanceof IFunction) {
+ this.addRows((IFunction) this.currentObject);
+ }
+ }
+}
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 Apr 21 14:48:39 2015
@@ -6,83 +6,130 @@
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
+import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
+import javax.swing.filechooser.FileNameExtensionFilter;
import org.hps.monitoring.application.util.DialogUtil;
+import org.hps.monitoring.plotting.ExportPdf;
import org.hps.monitoring.plotting.MonitoringPlotFactory;
/**
* This is the panel containing the tabs with the monitoring plots.
- * @author Jeremy McCormick <[log in to unmask]>
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class PlotPanel extends JPanel implements ActionListener {
-
- private JTabbedPane plotPane;
-
+@SuppressWarnings("serial")
+final class PlotPanel extends JPanel implements ActionListener {
+
+ /**
+ * The tabs containing the plots.
+ */
+ private final JTabbedPane plotPane;
+
+ /**
+ * Class constructor.
+ */
public PlotPanel() {
- setLayout(new BorderLayout());
- plotPane = new JTabbedPane();
- plotPane.setPreferredSize(getPreferredSize());
- add(plotPane, BorderLayout.CENTER);
- }
-
- JTabbedPane getPlotPane() {
- return plotPane;
+ this.setLayout(new BorderLayout());
+ this.plotPane = new JTabbedPane();
+ this.plotPane.setPreferredSize(this.getPreferredSize());
+ this.add(this.plotPane, BorderLayout.CENTER);
}
/**
- * Get the indices of the current selected tabs.
- * @return The indices of the current tabs.
+ * Handle an {@link java.awt.event.ActionEvent}.
+ *
+ * @param event the {@link java.awt.event.ActionEvent} to handle
*/
- int[] getSelectedTabs() {
- int[] indices = new int[2];
- indices[0] = plotPane.getSelectedIndex();
- Component component = plotPane.getSelectedComponent();
- if (component instanceof JTabbedPane) {
- indices[1] = ((JTabbedPane)component).getSelectedIndex();
- }
- return indices;
- }
-
- public void actionPerformed(ActionEvent event) {
+ @Override
+ public void actionPerformed(final ActionEvent event) {
if (event.getActionCommand().equals(Commands.SAVE_SELECTED_PLOTS)) {
- int[] indices = getSelectedTabs();
- IPlotter plotter = MonitoringPlotFactory.getPlotterRegistry().find(indices[0], indices[1]);
+ final int[] indices = this.getSelectedTabIndices();
+ final IPlotter plotter = MonitoringPlotFactory.getPlotterRegistry().find(indices[0], indices[1]);
if (plotter != null) {
- savePlotter(plotter);
+ this.savePlotter(plotter);
} else {
DialogUtil.showErrorDialog(this, "Error Finding Plots", "No plots found in selected tab.");
}
}
}
-
- static final String DEFAULT_FORMAT = "png";
- void savePlotter(IPlotter plotter) {
- JFileChooser fc = new JFileChooser();
+
+ /**
+ * Get the tabbed pane with the plots.
+ *
+ * @return the tabbed pane with the plots
+ */
+ JTabbedPane getPlotPane() {
+ return this.plotPane;
+ }
+
+ /**
+ * Get the currently selected plot tab.
+ *
+ * @return the currently selected plot tab
+ */
+ Component getSelectedTab() {
+ return ((JTabbedPane) this.plotPane.getSelectedComponent()).getSelectedComponent();
+ }
+
+ /**
+ * Get the indices of the current selected tabs.
+ *
+ * @return The indices of the current tabs.
+ */
+ private int[] getSelectedTabIndices() {
+ final int[] indices = new int[2];
+ indices[0] = this.plotPane.getSelectedIndex();
+ final Component component = this.plotPane.getSelectedComponent();
+ if (component instanceof JTabbedPane) {
+ indices[1] = ((JTabbedPane) component).getSelectedIndex();
+ }
+ return indices;
+ }
+
+ /**
+ * Remove all tabs from the plot pane.
+ */
+ void reset() {
+ this.plotPane.removeAll();
+ }
+
+ /**
+ * Save the plotter from a tab to a graphics file.
+ *
+ * @param plotter the plotter to save
+ */
+ private void savePlotter(final IPlotter plotter) {
+ final JFileChooser fc = new JFileChooser();
fc.setAcceptAllFileFilterUsed(false);
fc.setDialogTitle("Save Plots - " + plotter.title());
fc.setCurrentDirectory(new File("."));
- int r = fc.showSaveDialog(this);
- if (r == JFileChooser.APPROVE_OPTION) {
+ fc.setAcceptAllFileFilterUsed(false);
+ fc.setFileFilter(new FileNameExtensionFilter("PNG file", "png"));
+ fc.addChoosableFileFilter(new FileNameExtensionFilter("JPG file", "jpg"));
+ fc.addChoosableFileFilter(new FileNameExtensionFilter("GIF file", "gif"));
+ final int r = fc.showSaveDialog(this);
+ if (r == JFileChooser.APPROVE_OPTION) {
String path = fc.getSelectedFile().getPath();
- if (path.lastIndexOf(".") == -1) {
- path += "." + DEFAULT_FORMAT;
+ final FileNameExtensionFilter filter = (FileNameExtensionFilter) fc.getFileFilter();
+ if (!path.endsWith("." + filter.getExtensions()[0])) {
+ path += "." + filter.getExtensions()[0];
}
+ final BufferedImage image = ExportPdf.getImage(this.getSelectedTab());
try {
- plotter.writeToFile(path);
- } catch (IOException e) {
+ ImageIO.write(image, filter.getExtensions()[0], new File(path));
+ DialogUtil.showInfoDialog(this, "Plots Saved", "Plots from panel were saved to" + '\n' + path);
+ } catch (final IOException e) {
e.printStackTrace();
DialogUtil.showErrorDialog(this, "Error Saving Plots", "There was an error saving the plots.");
}
- }
+ }
}
-
- void reset() {
- plotPane.removeAll();
- }
-}
+}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SettingsDialog.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SettingsDialog.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SettingsDialog.java Tue Apr 21 14:48:39 2015
@@ -9,35 +9,50 @@
import org.hps.monitoring.application.model.ConfigurationModel;
/**
- * The modal dialog for entering settings. It contains a <code>JPanel</code> with the different
- * settings sub-tabs.
+ * The modal dialog for entering application settings.
+ * <p>
+ * It contains a <code>JPanel</code> with the different settings sub-tabs.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class SettingsDialog extends JDialog {
+@SuppressWarnings("serial")
+final class SettingsDialog extends JDialog {
- final SettingsPanel settingsPanel;
+ /**
+ * The panel with the settings.
+ */
+ private final SettingsPanel settingsPanel;
- public SettingsDialog(ConfigurationModel configurationModel, ActionListener listener) {
+ /**
+ * Class constructor.
+ *
+ * @param configurationModel the configuration model with global settings
+ * @param listener the action listener assigned to certain components
+ */
+ public SettingsDialog(final ConfigurationModel configurationModel, final ActionListener listener) {
// Initialize the GUI panel.
- settingsPanel = new SettingsPanel(this, configurationModel, listener);
-
+ this.settingsPanel = new SettingsPanel(this, configurationModel, listener);
+
// Configure the frame.
- setTitle("Settings");
- setContentPane(settingsPanel);
- setResizable(false);
- setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
- setModalityType(ModalityType.APPLICATION_MODAL);
- pack();
+ this.setTitle("Settings");
+ this.setContentPane(this.settingsPanel);
+ this.setResizable(false);
+ this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+ this.setModalityType(ModalityType.APPLICATION_MODAL);
+ this.pack();
// Add window listener for turning invisible when closing.
- addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- setVisible(false);
+ this.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(final WindowEvent e) {
+ SettingsDialog.this.setVisible(false);
}
-
- public void windowOpened(WindowEvent event) {
- SettingsDialog.this.setLocationRelativeTo(null);
+
+ @Override
+ public void windowOpened(final WindowEvent event) {
+ SettingsDialog.this.setLocationRelativeTo(null);
}
- });
+ });
}
}
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 Apr 21 14:48:39 2015
@@ -16,54 +16,82 @@
/**
* The container component with the tabs that have job and connection settings.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class SettingsPanel extends JPanel implements ActionListener {
+@SuppressWarnings("serial")
+final class SettingsPanel extends JPanel implements ActionListener {
- JTabbedPane tabs;
- JobSettingsPanel jobPanel;
- ConnectionSettingsPanel connectionPanel;
- static final String OKAY_COMMAND = "settingsOkay";
+ /**
+ * The panel with connection settings.
+ */
+ private final ConnectionSettingsPanel connectionPanel;
- JDialog parent;
+ /**
+ * The panel with general job settings.
+ */
+ private final JobSettingsPanel jobPanel;
- SettingsPanel(JDialog parent, ConfigurationModel configurationModel, ActionListener listener) {
+ /**
+ * The parent dialog window.
+ */
+ private final JDialog parent;
+
+ /**
+ * The tabs with the sub-panels.
+ */
+ private final JTabbedPane tabs;
+
+ /**
+ * Class constructor.
+ *
+ * @param parent the parent dialog window
+ * @param configurationModel the global configuration model
+ * @param listener the action listener assigned to certain components
+ */
+ SettingsPanel(final JDialog parent, final ConfigurationModel configurationModel, final ActionListener listener) {
this.parent = parent;
-
- connectionPanel = new ConnectionSettingsPanel();
- jobPanel = new JobSettingsPanel(configurationModel);
-
+
+ this.connectionPanel = new ConnectionSettingsPanel();
+ this.jobPanel = new JobSettingsPanel(configurationModel);
+
// Push configuration to sub-components.
- connectionPanel.setConfigurationModel(configurationModel);
- jobPanel.setConfigurationModel(configurationModel);
-
+ this.connectionPanel.setConfigurationModel(configurationModel);
+ this.jobPanel.setConfigurationModel(configurationModel);
+
// Add ActionListener to sub-components.
- connectionPanel.addActionListener(listener);
- jobPanel.addActionListener(listener);
-
+ this.connectionPanel.addActionListener(listener);
+ this.jobPanel.addActionListener(listener);
+
this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
- tabs = new JTabbedPane();
- tabs.addTab("Connection Settings", connectionPanel);
- tabs.addTab("Job Settings", jobPanel);
- add(tabs);
+ this.tabs = new JTabbedPane();
+ this.tabs.addTab("Connection Settings", this.connectionPanel);
+ this.tabs.addTab("Job Settings", this.jobPanel);
+ this.add(this.tabs);
- JButton okayButton = new JButton("Okay");
- okayButton.setActionCommand(OKAY_COMMAND);
+ final JButton okayButton = new JButton("Okay");
+ okayButton.setActionCommand(Commands.SETTINGS_OKAY_COMMAND);
okayButton.addActionListener(this);
- add(Box.createRigidArea(new Dimension(1, 5)));
- JPanel buttonsPanel = new JPanel();
+ this.add(Box.createRigidArea(new Dimension(1, 5)));
+ final JPanel buttonsPanel = new JPanel();
buttonsPanel.add(okayButton);
buttonsPanel.setLayout(new FlowLayout());
- add(buttonsPanel);
- add(Box.createRigidArea(new Dimension(1, 5)));
+ this.add(buttonsPanel);
+ this.add(Box.createRigidArea(new Dimension(1, 5)));
}
+ /**
+ * Handle action events.
+ *
+ * @param e the action event to handle
+ */
@Override
- public void actionPerformed(ActionEvent e) {
- if (e.getActionCommand().equals(OKAY_COMMAND)) {
- parent.setVisible(false);
+ public void actionPerformed(final ActionEvent e) {
+ if (e.getActionCommand().equals(Commands.SETTINGS_OKAY_COMMAND)) {
+ this.parent.setVisible(false);
}
- }
+ }
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusEventsTable.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusEventsTable.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusEventsTable.java Tue Apr 21 14:48:39 2015
@@ -1,6 +1,3 @@
-/**
- *
- */
package org.hps.monitoring.application;
import java.awt.Component;
@@ -22,125 +19,190 @@
/**
* This is a table that shows every system status change in a different row.
- *
- * @author Jeremy McCormick <[log in to unmask]>
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-public class SystemStatusEventsTable extends JTable {
-
- SystemStatusEventsTableModel tableModel = new SystemStatusEventsTableModel();
-
+@SuppressWarnings("serial")
+final class SystemStatusEventsTable extends JTable {
+
+ /**
+ * The model for the system status events table.
+ */
+ static class SystemStatusEventsTableModel extends DefaultTableModel implements SystemStatusListener {
+
+ /**
+ * The classes of the table columns.
+ */
+ private final Class<?>[] columnClasses = {Date.class, Subsystem.class, SystemStatus.class, String.class,
+ String.class};
+
+ /**
+ * The names of the columns.
+ */
+ private final String[] columnNames = {"Date", "Subsystem", "Status Code", "Description", "Message"};
+
+ /**
+ * The list of statuses shown in the table.
+ */
+ private final List<SystemStatus> statuses = new ArrayList<SystemStatus>();
+
+ /**
+ * Class constructor.
+ */
+ SystemStatusEventsTableModel() {
+ }
+
+ /**
+ * Register the listener on this status.
+ *
+ * @param status the system status
+ */
+ void addSystemStatus(final SystemStatus status) {
+ status.addListener(this);
+ }
+
+ /**
+ * Clear all the records from the table.
+ */
+ void clear() {
+ this.statuses.clear();
+ this.setRowCount(0);
+ }
+
+ /**
+ * Get the column class.
+ *
+ * @param columnIndex the column index
+ */
+ @Override
+ public Class<?> getColumnClass(final int columnIndex) {
+ return this.columnClasses[columnIndex];
+ }
+
+ /**
+ * Get the column count.
+ *
+ * @return the column count
+ */
+ @Override
+ public int getColumnCount() {
+ return this.columnNames.length;
+ }
+
+ /**
+ * Get the column name.
+ *
+ * @param columnIndex the column index
+ */
+ @Override
+ public String getColumnName(final int columnIndex) {
+ return this.columnNames[columnIndex];
+ }
+
+ /**
+ * Get the row count.
+ *
+ * @return the row count
+ */
+ @Override
+ public int getRowCount() {
+ if (this.statuses != null) {
+ return this.statuses.size();
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Get a cell value from the table.
+ *
+ * @param rowIndex the row index
+ * @param columnIndex the column index
+ * @return the cell value at the rowIndex and columnIndex
+ */
+ @Override
+ public Object getValueAt(final int rowIndex, final int columnIndex) {
+ final SystemStatus status = this.statuses.get(rowIndex);
+ switch (columnIndex) {
+ case 0:
+ return new Date(status.getLastChangedMillis());
+ case 1:
+ return status.getSubsystem();
+ case 2:
+ return status.getStatusCode();
+ case 3:
+ return status.getDescription();
+ case 4:
+ return status.getMessage();
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Update the table with status changes.
+ *
+ * @param status the system status
+ */
+ @Override
+ public void statusChanged(final SystemStatus status) {
+ final SystemStatus newStatus = new SystemStatusImpl(status);
+ this.statuses.add(newStatus);
+ this.fireTableDataChanged();
+ }
+ }
+
+ /**
+ * The table model.
+ */
+ private final SystemStatusEventsTableModel tableModel = new SystemStatusEventsTableModel();
+
+ /**
+ * Class constructor.
+ */
SystemStatusEventsTable() {
- setModel(tableModel);
-
+ this.setModel(this.tableModel);
+
// Date formatting.
- getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer() {
+ this.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer() {
final SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM-dd-yyyy HH:mm:ss.SSS");
@Override
- public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ public Component getTableCellRendererComponent(final JTable table, Object value, final boolean isSelected,
+ final boolean hasFocus, final int row, final int column) {
if (value instanceof Date) {
- value = dateFormat.format(value);
+ value = this.dateFormat.format(value);
}
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
});
-
+
// Rendering of system status cells using different background colors.
- getColumnModel().getColumn(2).setCellRenderer(new DefaultTableCellRenderer() {
+ this.getColumnModel().getColumn(2).setCellRenderer(new DefaultTableCellRenderer() {
@Override
- public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
+ public Component getTableCellRendererComponent(final JTable table, final Object value,
+ final boolean isSelected, final boolean hasFocus, final int row, final int col) {
// Cells are by default rendered as a JLabel.
- JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
+ final JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
+ row, col);
// Color code the cell by its status.
- StatusCode statusCode = (StatusCode) value;
+ final StatusCode statusCode = (StatusCode) value;
label.setBackground(statusCode.getColor());
return label;
}
});
}
-
- void registerListener() {
+
+ /**
+ * Get the system status events table model.
+ *
+ * @return the system status events table model
+ */
+ SystemStatusEventsTableModel getSystemStatusEventsTableModel() {
+ return this.tableModel;
}
-
- static class SystemStatusEventsTableModel extends DefaultTableModel implements SystemStatusListener {
-
- List<SystemStatus> statuses = new ArrayList<SystemStatus>();
-
- String[] columnNames = { "Date", "Subsystem", "Status Code", "Description", "Message" };
- Class<?>[] columnClasses = { Date.class, Subsystem.class, SystemStatus.class, String.class, String.class };
-
- SystemStatusEventsTableModel() {
- }
-
- @Override
- public String getColumnName(int column) {
- return columnNames[column];
- }
-
- @Override
- public Class<?> getColumnClass(int column) {
- return columnClasses[column];
- }
-
- /**
- * Update the table with status changes.
- * @param status The system status.
- */
- @Override
- public void statusChanged(SystemStatus status) {
- SystemStatus newStatus = new SystemStatusImpl(status);
- statuses.add(newStatus);
- fireTableDataChanged();
- }
-
- /**
- * Register the listener on this status.
- * @param status The system status.
- */
- void addSystemStatus(SystemStatus status) {
- status.addListener(this);
- }
-
- @Override
- public int getColumnCount() {
- return columnNames.length;
- }
-
- @Override
- public int getRowCount() {
- if (statuses != null) {
- return statuses.size();
- } else {
- return 0;
- }
- }
-
- @Override
- public Object getValueAt(int row, int column) {
- SystemStatus status = statuses.get(row);
- switch (column) {
- case 0:
- return new Date(status.getLastChangedMillis());
- case 1:
- return status.getSubsystem();
- case 2:
- return status.getStatusCode();
- case 3:
- return status.getDescription();
- case 4:
- return status.getMessage();
- default:
- return null;
- }
- }
-
- public void clear() {
- this.statuses.clear();
- this.setRowCount(0);
- }
- }
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusPanel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusPanel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusPanel.java Tue Apr 21 14:48:39 2015
@@ -1,5 +1,5 @@
/**
- *
+ *
*/
package org.hps.monitoring.application;
@@ -13,39 +13,54 @@
import org.hps.monitoring.subsys.SystemStatus;
/**
- * This is a panel showing the two tables for viewing the system statuses,
- * one showing the current state of all system status monitors and the other
- * all system status change events.
- *
- * @author Jeremy McCormick <[log in to unmask]>
+ * This is a panel showing the two tables for viewing the system statuses, one showing the current state of all system
+ * status monitors and the other with all system status change events.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-public class SystemStatusPanel extends JPanel {
-
- SystemStatusTable statusTable = new SystemStatusTable();
- SystemStatusEventsTable eventsTable = new SystemStatusEventsTable();
-
- SystemStatusPanel() {
+@SuppressWarnings("serial")
+final class SystemStatusPanel extends JPanel {
+
+ /**
+ * The system status events table.
+ */
+ private final SystemStatusEventsTable eventsTable = new SystemStatusEventsTable();
+
+ /**
+ * The system status table.
+ */
+ private final SystemStatusTable statusTable = new SystemStatusTable();
+
+ /**
+ * Class constructor.
+ */
+ SystemStatusPanel() {
super(new BorderLayout());
- JSplitPane splitPane = new JSplitPane(
- JSplitPane.VERTICAL_SPLIT,
- new JScrollPane(statusTable),
- new JScrollPane(eventsTable));
+ final JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, new JScrollPane(this.statusTable),
+ new JScrollPane(this.eventsTable));
splitPane.setDividerLocation(50);
- add(splitPane,
- BorderLayout.CENTER);
- }
-
- void addSystemStatus(SystemStatus status) {
+ this.add(splitPane, BorderLayout.CENTER);
+ }
+
+ /**
+ * Add a system status.
+ *
+ * @param status the system status to add
+ */
+ void addSystemStatus(final SystemStatus status) {
// Register listeners of table models on this status.
- statusTable.getTableModel().addSystemStatus(status);
- eventsTable.tableModel.addSystemStatus(status);
+ this.statusTable.getTableModel().addSystemStatus(status);
+ this.eventsTable.getSystemStatusEventsTableModel().addSystemStatus(status);
}
-
+
+ /**
+ * Clear all the table records.
+ */
void clear() {
// Clear the system status monitor table.
- statusTable.getTableModel().clear();
+ this.statusTable.getTableModel().clear();
// Clear the system status events table.
- ((SystemStatusEventsTableModel)eventsTable.getModel()).clear();
+ ((SystemStatusEventsTableModel) this.eventsTable.getModel()).clear();
}
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusTable.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusTable.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusTable.java Tue Apr 21 14:48:39 2015
@@ -17,102 +17,152 @@
/**
* This table shows the current state of {@link org.hps.monitoring.subsys.SystemStatus} objects.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class SystemStatusTable extends JTable {
-
- SystemStatusTable() {
-
- setModel(new SystemStatusTableModel());
-
- // Rendering of system status cells using different background colors.
- getColumnModel().getColumn(SystemStatusTableModel.STATUS_COL).setCellRenderer(new DefaultTableCellRenderer() {
-
- @Override
- public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
-
- // Cells are by default rendered as a JLabel.
- JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
-
- // Color code the cell by its status.
- StatusCode statusCode = StatusCode.valueOf((String) value);
- label.setBackground(statusCode.getColor());
- return label;
- }
- });
-
- // Date formatting for last changed.
- getColumnModel().getColumn(SystemStatusTableModel.LAST_CHANGED_COL).setCellRenderer(new DefaultTableCellRenderer() {
-
- final SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM-dd-yyyy HH:mm:ss.SSS");
-
- @Override
- public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
- if (value instanceof Date) {
- value = dateFormat.format(value);
- }
- return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
- }
- });
-
- // Button for clearing system statuses.
- getColumnModel().getColumn(SystemStatusTableModel.RESET_COL).setCellRenderer(new ButtonRenderer("Clear"));
- addMouseListener(new JTableButtonMouseListener(this));
- getColumn("Clearable").setWidth(0);
- getColumn("Clearable").setMinWidth(0);
- getColumn("Clearable").setMaxWidth(0);
-
- // Column widths.
- getColumnModel().getColumn(SystemStatusTableModel.ACTIVE_COL).setPreferredWidth(8);
- getColumnModel().getColumn(SystemStatusTableModel.STATUS_COL).setPreferredWidth(10);
- getColumnModel().getColumn(SystemStatusTableModel.SYSTEM_COL).setPreferredWidth(10);
- // TODO: Add default width setting for every column.
-
- setAutoCreateRowSorter(true);
- }
-
- public SystemStatusTableModel getTableModel() {
- return (SystemStatusTableModel) getModel();
- }
+@SuppressWarnings("serial")
+final class SystemStatusTable extends JTable {
/**
- * Renders a button if the status is clearable.
+ * Renders a button if the status is clear-able.
*/
private class ButtonRenderer extends JButton implements TableCellRenderer {
- public ButtonRenderer(String label) {
+ /**
+ * Class constructor.
+ *
+ * @param label the label of the button
+ */
+ public ButtonRenderer(final String label) {
this.setText(label);
}
- public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
- boolean clearable = (Boolean) table.getModel().getValueAt(row, SystemStatusTableModel.CLEARABLE_COL);
- if (clearable)
+ /**
+ * Get the renderer for the table cell.
+ *
+ * @param table the table
+ * @param value the object from the table cell
+ * @param isSelected <code>true</code> if cell is selected
+ * @param hasFocus <code>true</code> if cell has focus
+ * @param rowIndex the row index
+ * @param columnIndex the column index
+ */
+ @Override
+ public Component getTableCellRendererComponent(final JTable table, final Object value,
+ final boolean isSelected, final boolean hasFocus, final int rowIndex, final int columnIndex) {
+ final boolean clearable = (Boolean) table.getModel().getValueAt(rowIndex,
+ SystemStatusTableModel.CLEARABLE_COLUMN_INDEX);
+ if (clearable) {
return this;
- else
+ } else {
return null;
+ }
}
}
/**
- * Fires a mouse click event when the clear button is pressed, which in turn will activate the
- * action event for the button. The <code>ActionListener</code> then sets the
- * <code>StatusCode</code> to <code>CLEARED</code>.
+ * Fires a mouse click event when the clear button is pressed, which in turn will activate the action event for the
+ * button. The <code>ActionListener</code> then sets the <code>StatusCode</code> to <code>CLEARED</code>.
*/
private static class JTableButtonMouseListener extends MouseAdapter {
+
+ /**
+ * The table.
+ */
private final JTable table;
- public JTableButtonMouseListener(JTable table) {
+ /**
+ * Class constructor.
+ *
+ * @param table the table for the listener
+ */
+ public JTableButtonMouseListener(final JTable table) {
this.table = table;
}
- public void mouseClicked(MouseEvent e) {
- int column = table.getColumnModel().getColumnIndexAtX(e.getX());
- int row = e.getY() / table.getRowHeight();
- if (row < table.getRowCount() && row >= 0 && column < table.getColumnCount() && column >= 0) {
- Object value = table.getValueAt(row, column);
+ /**
+ * Implement mouse clicked action.
+ *
+ * @param e the mouse event
+ */
+ @Override
+ public void mouseClicked(final MouseEvent e) {
+ final int column = this.table.getColumnModel().getColumnIndexAtX(e.getX());
+ final int row = e.getY() / this.table.getRowHeight();
+ if (row < this.table.getRowCount() && row >= 0 && column < this.table.getColumnCount() && column >= 0) {
+ final Object value = this.table.getValueAt(row, column);
if (value instanceof JButton) {
((JButton) value).doClick();
}
}
}
}
-}
+
+ /**
+ * Class constructor.
+ */
+ SystemStatusTable() {
+
+ this.setModel(new SystemStatusTableModel());
+
+ // Rendering of system status cells using different background colors.
+ this.getColumnModel().getColumn(SystemStatusTableModel.STATUS_COLUMN_INDEX)
+ .setCellRenderer(new DefaultTableCellRenderer() {
+
+ @Override
+ public Component getTableCellRendererComponent(final JTable table, final Object value,
+ final boolean isSelected, final boolean hasFocus, final int row, final int col) {
+
+ // Cells are by default rendered as a JLabel.
+ final JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected,
+ hasFocus, row, col);
+
+ // Color code the cell by its status.
+ final StatusCode statusCode = StatusCode.valueOf((String) value);
+ label.setBackground(statusCode.getColor());
+ return label;
+ }
+ });
+
+ // Date formatting for last changed.
+ this.getColumnModel().getColumn(SystemStatusTableModel.LAST_CHANGED_COLUMN_INDEX)
+ .setCellRenderer(new DefaultTableCellRenderer() {
+
+ final SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM-dd-yyyy HH:mm:ss.SSS");
+
+ @Override
+ public Component getTableCellRendererComponent(final JTable table, Object value,
+ final boolean isSelected, final boolean hasFocus, final int row, final int column) {
+ if (value instanceof Date) {
+ value = this.dateFormat.format(value);
+ }
+ return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+ }
+ });
+
+ // Button for clearing system statuses.
+ this.getColumnModel().getColumn(SystemStatusTableModel.RESET_COLUMN_INDEX)
+ .setCellRenderer(new ButtonRenderer("Clear"));
+ this.addMouseListener(new JTableButtonMouseListener(this));
+ this.getColumn("Clearable").setWidth(0);
+ this.getColumn("Clearable").setMinWidth(0);
+ this.getColumn("Clearable").setMaxWidth(0);
+
+ // Column widths.
+ this.getColumnModel().getColumn(SystemStatusTableModel.ACTIVE_COLUMN_INDEX).setPreferredWidth(8);
+ this.getColumnModel().getColumn(SystemStatusTableModel.STATUS_COLUMN_INDEX).setPreferredWidth(10);
+ this.getColumnModel().getColumn(SystemStatusTableModel.SYSTEM_COLUMN_INDEX).setPreferredWidth(10);
+ // TODO: Add default width setting for every column.
+
+ this.setAutoCreateRowSorter(true);
+ }
+
+ /**
+ * Get the tqble model.
+ *
+ * @return the table model
+ */
+ public SystemStatusTableModel getTableModel() {
+ return (SystemStatusTableModel) this.getModel();
+ }
+}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ToolbarPanel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ToolbarPanel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ToolbarPanel.java Tue Apr 21 14:48:39 2015
@@ -13,21 +13,37 @@
/**
* A GUI component for the top-level toolbar of the monitoring app.
- *
- * @author Jeremy McCormick <[log in to unmask]>
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-public class ToolbarPanel extends JPanel {
+@SuppressWarnings("serial")
+final class ToolbarPanel extends JPanel {
- DataSourceComboBox dataSourceComboBox;
- JPanel buttonsPanel;
+ /**
+ * The panel with the buttons.
+ */
+ private final JPanel buttonsPanel;
- ToolbarPanel(ConfigurationModel configurationModel, ConnectionStatusModel connectionModel, ActionListener listener) {
+ /**
+ * The combo box with the list of data sources.
+ */
+ private final DataSourceComboBox dataSourceComboBox;
- setLayout(new FlowLayout(FlowLayout.LEFT));
-
- JPanel containerPanel = new JPanel();
+ /**
+ * Class constructor.
+ *
+ * @param configurationModel the configuration model for the application
+ * @param connectionModel the connection status model
+ * @param listener the action listener to assign to certain components
+ */
+ ToolbarPanel(final ConfigurationModel configurationModel, final ConnectionStatusModel connectionModel,
+ final ActionListener listener) {
+
+ this.setLayout(new FlowLayout(FlowLayout.LEFT));
+
+ final JPanel containerPanel = new JPanel();
containerPanel.setLayout(new GridBagLayout());
-
+
// Create the connection status panel.
GridBagConstraints gbs = new GridBagConstraints();
gbs.anchor = GridBagConstraints.WEST;
@@ -36,30 +52,38 @@
gbs.weightx = 0.5;
gbs.fill = GridBagConstraints.BOTH;
gbs.insets = new Insets(10, 0, 0, 10);
- JPanel connectionPanel = new ConnectionStatusPanel(connectionModel);
+ final JPanel connectionPanel = new ConnectionStatusPanel(connectionModel);
containerPanel.add(connectionPanel, gbs);
// Create the buttons panel.
- buttonsPanel = new EventButtonsPanel(connectionModel, listener);
+ this.buttonsPanel = new EventButtonsPanel(connectionModel, listener);
gbs.anchor = GridBagConstraints.WEST;
gbs.gridx = 1;
gbs.gridy = 0;
gbs.weightx = 0.5;
gbs.fill = GridBagConstraints.BOTH;
gbs.insets = new Insets(0, 0, 0, 10);
- containerPanel.add(buttonsPanel, gbs);
+ containerPanel.add(this.buttonsPanel, gbs);
// Add the data source combo box.
- dataSourceComboBox = new DataSourceComboBox(configurationModel, connectionModel);
+ this.dataSourceComboBox = new DataSourceComboBox(configurationModel, connectionModel);
gbs = new GridBagConstraints();
gbs.anchor = GridBagConstraints.WEST;
gbs.gridx = 2;
gbs.gridy = 0;
gbs.weightx = 1.0;
gbs.fill = GridBagConstraints.HORIZONTAL;
- containerPanel.add(dataSourceComboBox, gbs);
-
- add(containerPanel);
+ containerPanel.add(this.dataSourceComboBox, gbs);
+
+ this.add(containerPanel);
}
+ /**
+ * Get the combo box with the data sources
+ *
+ * @return the combo box with the data sources
+ */
+ DataSourceComboBox getDataSourceComboBox() {
+ return this.dataSourceComboBox;
+ }
}
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 Apr 21 14:48:39 2015
@@ -7,7 +7,7 @@
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
-import org.hps.analysis.trigger.DiagSnapshot;
+import org.hps.analysis.trigger.data.DiagnosticSnapshot;
import org.hps.monitoring.trigger.ClusterTablePanel;
import org.hps.monitoring.trigger.DiagnosticUpdatable;
import org.hps.monitoring.trigger.EfficiencyTablePanel;
@@ -18,63 +18,94 @@
/**
* This is a panel containing the trigger diagnostics tables.
- *
- * @author Jeremy McCormick <[log in to unmask]>
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-class TriggerDiagnosticsPanel extends JPanel {
+@SuppressWarnings("serial")
+final class TriggerDiagnosticsPanel extends JPanel {
- JTabbedPane tabs = new JTabbedPane();
- ClusterTablePanel clusterPanel = new ClusterTablePanel();
- SinglesTablePanel singlesPanel = new SinglesTablePanel();
- PairTablePanel pairsPanel = new PairTablePanel();
- EfficiencyTablePanel efficiencyPanel = new EfficiencyTablePanel();
-
- List<DiagnosticUpdatable> updateList = new ArrayList<DiagnosticUpdatable>();
-
- TriggerDiagnosticsPanel() {
- setLayout(new BorderLayout());
-
- tabs.addTab("Clusters", clusterPanel);
- tabs.addTab("Singles", singlesPanel);
- tabs.addTab("Pairs", pairsPanel);
- tabs.addTab("Efficiency", efficiencyPanel);
-
- updateList.add(clusterPanel);
- updateList.add(singlesPanel);
- updateList.add(pairsPanel);
- updateList.add(efficiencyPanel);
-
- add(tabs, BorderLayout.CENTER);
- }
-
/**
* Driver for updating the tables.
*/
class TriggerDiagnosticGUIDriver extends Driver {
- // FIXME: Hard-coded collection name.
+ /**
+ * Default name of trigger diagnostics collection.
+ */
private String diagnosticCollectionName = "DiagnosticSnapshot";
-
+
@Override
- public void process(EventHeader event) {
+ public void process(final EventHeader event) {
// Updates are only performed if a diagnostic snapshot object
// exists. Otherwise, do nothing.
- if(event.hasCollection(DiagSnapshot.class, diagnosticCollectionName)) {
+ if (event.hasCollection(DiagnosticSnapshot.class, this.diagnosticCollectionName)) {
// Get the snapshot collection.
- List<DiagSnapshot> snapshotList = event.get(DiagSnapshot.class, diagnosticCollectionName);
-
- // Get the snapshot. There will only ever be one.
- DiagSnapshot snapshot = snapshotList.get(0);
-
+ final List<DiagnosticSnapshot> snapshotList = event.get(DiagnosticSnapshot.class,
+ this.diagnosticCollectionName);
+
// Update the GUI panels.
- for (DiagnosticUpdatable update : updateList) {
- update.updatePanel(snapshot);
+ for (final DiagnosticUpdatable update : TriggerDiagnosticsPanel.this.updateList) {
+ update.updatePanel(snapshotList.get(1), snapshotList.get(0));
}
- }
+ }
}
-
- void setDiagnosticCollectionName(String name) {
- diagnosticCollectionName = name;
+
+ /**
+ * Set the name of the trigger diagnostics collection.
+ *
+ * @param name the name of the trigger diagnostics collection
+ */
+ void setDiagnosticCollectionName(final String name) {
+ this.diagnosticCollectionName = name;
}
- }
+ }
+
+ /**
+ * The panel with cluster statistics.
+ */
+ private final ClusterTablePanel clusterPanel = new ClusterTablePanel();
+
+ /**
+ * The panel with efficiency statistics.
+ */
+ private final EfficiencyTablePanel efficiencyPanel = new EfficiencyTablePanel();
+
+ /**
+ * The panel with pairs statistics.
+ */
+ private final PairTablePanel pairsPanel = new PairTablePanel();
+
+ /**
+ * The panel with singles statistics.
+ */
+ private final SinglesTablePanel singlesPanel = new SinglesTablePanel();
+
+ /**
+ * The tabs containing the statistics panels.
+ */
+ private final JTabbedPane tabs = new JTabbedPane();
+
+ /**
+ * The list of objects that can be updated with trigger diagnostics.
+ */
+ private final List<DiagnosticUpdatable> updateList = new ArrayList<DiagnosticUpdatable>();
+
+ /**
+ * Class constructor.
+ */
+ TriggerDiagnosticsPanel() {
+ this.setLayout(new BorderLayout());
+
+ this.tabs.addTab("Clusters", this.clusterPanel);
+ this.tabs.addTab("Singles", this.singlesPanel);
+ this.tabs.addTab("Pairs", this.pairsPanel);
+ this.tabs.addTab("Efficiency", this.efficiencyPanel);
+
+ this.updateList.add(this.clusterPanel);
+ this.updateList.add(this.singlesPanel);
+ this.updateList.add(this.pairsPanel);
+ this.updateList.add(this.efficiencyPanel);
+
+ this.add(this.tabs, BorderLayout.CENTER);
+ }
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/AbstractModel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/AbstractModel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/AbstractModel.java Tue Apr 21 14:48:39 2015
@@ -10,97 +10,38 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javassist.Modifier;
+import org.lcsim.util.log.DefaultLogFormatter;
+import org.lcsim.util.log.LogUtil;
+
/**
* An abstract class which updates a set of listeners when there are property changes to a backing model.
- * @author Jeremy McCormick <[log in to unmask]>
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
public abstract class AbstractModel {
- protected PropertyChangeSupport propertyChangeSupport;
-
- public AbstractModel() {
- propertyChangeSupport = new PropertyChangeSupport(this);
- }
-
- public void addPropertyChangeListener(PropertyChangeListener listener) {
- propertyChangeSupport.addPropertyChangeListener(listener);
- }
-
- public void removePropertyChangeListener(PropertyChangeListener listener) {
- propertyChangeSupport.removePropertyChangeListener(listener);
- }
-
- protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
- propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
- }
-
- protected void firePropertyChange(PropertyChangeEvent evt) {
- propertyChangeSupport.firePropertyChange(evt);
- }
-
- abstract public String[] getPropertyNames();
-
- void firePropertiesChanged(Collection<String> properties) {
- propertyLoop: for (String property : properties) {
- Method getMethod = null;
- for (Method method : getClass().getMethods()) {
- if (method.getName().equals("get" + property)) {
- getMethod = method;
- break;
- }
- }
- //System.out.println(getMethod.getName());
- try {
- Object value = null;
- try {
- value = getMethod.invoke(this, (Object[]) null);
- //System.out.println(" value = " + value);
- } catch (NullPointerException e) {
- // This means there is no get method for the property which is a throwable error.
- throw new RuntimeException("Property " + property + " is missing a get method.", e);
- } catch (InvocationTargetException e) {
- // Is the cause of the problem an illegal argument to the method?
- if (e.getCause() instanceof IllegalArgumentException) {
- // For this error, assume that the key itself is missing from the configuration which is a warning.
- System.err.println("The key " + property + " is not set in the configuration.");
- continue propertyLoop;
- } else {
- e.printStackTrace();
- throw new RuntimeException(e);
- }
- }
- if (value != null) {
- firePropertyChange(property, value, value);
- for (PropertyChangeListener listener : propertyChangeSupport.getPropertyChangeListeners()) {
- // FIXME: For some reason calling the propertyChangeSupport methods directly here doesn't work!
- listener.propertyChange(new PropertyChangeEvent(this, property, value, value));
- }
- }
- } catch (IllegalAccessException | IllegalArgumentException e) {
- e.printStackTrace();
- throw new RuntimeException(e);
- }
- }
- }
-
- public void fireModelChanged() {
- firePropertiesChanged(Arrays.asList(getPropertyNames()));
- }
+ /**
+ * Setup logging.
+ */
+ private static final Logger LOGGER = LogUtil.create(AbstractModel.class.getName(), new DefaultLogFormatter(),
+ Level.INFO);
/**
- * This method will statically extract property names from a class, which in this package's conventions are statically declared,
- * public strings that end with "_PROPERTY".
- *
- * @param type The class with the properties.
- * @return The list of property names.
+ * This method will extract property names from a class, which in this package's conventions are statically
+ * declared, public strings that end with the sub-string "_PROPERTY".
+ *
+ * @param type the class with the properties settings
+ * @return the list of property names
*/
- protected static String[] getPropertyNames(Class<? extends AbstractModel> type) {
- List<String> fields = new ArrayList<String>();
- for (Field field : type.getDeclaredFields()) {
- int modifiers = field.getModifiers();
+ protected static String[] getPropertyNames(final Class<? extends AbstractModel> type) {
+ final List<String> fields = new ArrayList<String>();
+ for (final Field field : type.getDeclaredFields()) {
+ final int modifiers = field.getModifiers();
if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers) && field.getName().endsWith("_PROPERTY")) {
try {
fields.add((String) field.get(null));
@@ -111,4 +52,135 @@
}
return fields.toArray(new String[] {});
}
-}
+
+ /**
+ * The property change support object.
+ */
+ private final PropertyChangeSupport propertyChangeSupport;
+
+ /**
+ * Class constructor.
+ */
+ public AbstractModel() {
+ this.propertyChangeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * Add a property change listener.
+ *
+ * @param listener the property change listener
+ */
+ public void addPropertyChangeListener(final PropertyChangeListener listener) {
+ this.propertyChangeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * Fire property change events.
+ */
+ public void fireModelChanged() {
+ this.firePropertiesChanged(Arrays.asList(this.getPropertyNames()));
+ }
+
+ /**
+ * Fire property change for a list of named properties.
+ *
+ * @param properties the list of property names
+ */
+ void firePropertiesChanged(final Collection<String> properties) {
+ for (final String property : properties) {
+
+ // Find the getter for this property.
+ Method getMethod = null;
+ for (final Method method : this.getClass().getMethods()) {
+ if (method.getName().equals("get" + property)) {
+ getMethod = method;
+ break;
+ }
+ }
+
+ // Is there a valid get method for the property?
+ if (getMethod != null) {
+ LOGGER.fine("property: " + property + ", method: " + getMethod.getName());
+ try {
+ Object value = null;
+ try {
+ value = getMethod.invoke(this, (Object[]) null);
+ } catch (final InvocationTargetException e) {
+ // Is the cause of the problem an illegal argument to the method?
+ if (e.getCause() instanceof IllegalArgumentException) {
+ // Property key is not in the configuration (this should not happen under normal
+ // circumstances).
+ LOGGER.log(Level.WARNING, "Property key missing from configuration: " + property, e);
+ continue;
+ } else {
+ // Something else went wrong, which we assume is a fatal error.
+ LOGGER.log(Level.SEVERE, "Error setting property: " + property, e);
+ throw new RuntimeException("Error setting property: " + property, e);
+ }
+ }
+ if (value != null) {
+ this.firePropertyChange(property, value, value);
+ for (final PropertyChangeListener listener : this.propertyChangeSupport
+ .getPropertyChangeListeners()) {
+ // FIXME: For some reason calling the propertyChangeSupport methods directly here doesn't
+ // work!
+ listener.propertyChange(new PropertyChangeEvent(this, property, value, value));
+ }
+ }
+ } catch (IllegalAccessException | IllegalArgumentException e) {
+ // This should not usually happen.
+ LOGGER.log(Level.SEVERE, "Error setting property: " + property, e);
+ throw new RuntimeException("Error setting property: " + property, e);
+ }
+ } else {
+ // There was no getter found for the property which is a non-fatal warning.
+ LOGGER.log(Level.WARNING, "Unknown property in configuration: " + property);
+ }
+ }
+ }
+
+ /**
+ * Fire a property change event.
+ *
+ * @param evt the property change event
+ */
+ protected void firePropertyChange(final PropertyChangeEvent evt) {
+ this.propertyChangeSupport.firePropertyChange(evt);
+ }
+
+ /**
+ * Fire a property change.
+ *
+ * @param propertyName the name of the property
+ * @param oldValue the old property value
+ * @param newValue the new property value
+ */
+ protected void firePropertyChange(final String propertyName, final Object oldValue, final Object newValue) {
+ this.propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
+ }
+
+ /**
+ * Get the property change support object.
+ *
+ * @return the property change support object
+ */
+ PropertyChangeSupport getPropertyChangeSupport() {
+ return this.propertyChangeSupport;
+ }
+
+ /**
+ * Get the list of the property names for this model.
+ *
+ * @return the list of the property names for this model
+ */
+ abstract public String[] getPropertyNames();
+
+ /**
+ * Remove a property change listener from the model.
+ *
+ * @param listener the property change listener to remove
+ */
+ public void removePropertyChangeListener(final PropertyChangeListener listener) {
+ this.propertyChangeSupport.removePropertyChangeListener(listener);
+ }
+}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/Configuration.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/Configuration.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/Configuration.java Tue Apr 21 14:48:39 2015
@@ -9,210 +9,244 @@
import java.util.Set;
/**
- * This class provides a list of key, value pairs backed by a <code>Properties</code> object. The
- * getter and setter methods for these values are not public, because the
- * {@link org.hps.monitoring.application.model.ConfigurationModel} class should be used instead
- * to get or set application configuration values.
+ * This class provides a list of key, value pairs backed by a <code>Properties</code> object. The getter and setter
+ * methods for these values are not public, because the {@link org.hps.monitoring.application.model.ConfigurationModel}
+ * class should be used instead to get or set application configuration values.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
public final class Configuration {
- Properties properties;
- File file;
- String resourcePath;
-
+ /**
+ * The file containing the keys and values.
+ */
+ private File file;
+
+ /**
+ * The Java properties file.
+ */
+ private Properties properties;
+
+ /**
+ * The path to an embedded properties resource from a jar.
+ */
+ private String resourcePath;
+
+ /**
+ * Class constructor.
+ */
Configuration() {
- properties = new Properties();
- }
-
- /**
- * Load a configuration from a properties file.
- * @param file The properties file.
- */
- public Configuration(File file) {
+ this.properties = new Properties();
+ }
+
+ /**
+ * Class constructor.
+ * <p>
+ * Loads a configuration from a properties file.
+ *
+ * @param file the properties file
+ */
+ public Configuration(final File file) {
this.file = file;
try {
- properties = new Properties();
- properties.load(new FileInputStream(this.file));
- } catch (IOException e) {
+ this.properties = new Properties();
+ this.properties.load(new FileInputStream(this.file));
+ } catch (final IOException e) {
throw new RuntimeException("Error parsing properties file.", e);
}
}
/**
+ * Class constructor.
+ * <p>
* Load a configuration from a resource path pointing to a properties file.
- * @param resourcePath The resource path to the properties file.
- */
- public Configuration(String resourcePath) {
+ *
+ * @param resourcePath the resource path to the properties file
+ */
+ public Configuration(final String resourcePath) {
this.resourcePath = resourcePath;
- InputStream is = this.getClass().getResourceAsStream(this.resourcePath);
- try {
- properties = new Properties();
- properties.load(is);
- } catch (IOException e) {
+ final InputStream is = this.getClass().getResourceAsStream(this.resourcePath);
+ try {
+ this.properties = new Properties();
+ this.properties.load(is);
+ } catch (final IOException e) {
throw new RuntimeException("Error parsing properties resource.", e);
}
}
/**
+ * Check if the properties contains the key and if it has a non-null value.
+ *
+ * @param key the properties key
+ * @return <code>true</code> if properties key is valid
+ */
+ boolean checkKey(final String key) {
+ return this.hasKey(key) && this.properties.getProperty(key) != null;
+ }
+
+ /**
+ * Get a key value as a string.
+ *
+ * @param key the key to lookup
+ * @return the value or null if does not exist
+ */
+ String get(final String key) {
+ if (this.checkKey(key)) {
+ // Return the key value for properties that are set.
+ return this.properties.getProperty(key);
+ } else {
+ // Return null for unset properties.
+ return null;
+ }
+ }
+
+ /**
+ * Get a key value as a boolean.
+ *
+ * @param key the key to lookup
+ * @return the value or null if does not exist
+ */
+ Boolean getBoolean(final String key) {
+ if (this.checkKey(key)) {
+ return Boolean.parseBoolean(this.properties.getProperty(key));
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get a key value as a double.
+ *
+ * @param key the key to lookup
+ * @return the value as a <code>Double</code> or <code>null</code> if does not exist
+ */
+ Double getDouble(final String key) {
+ if (this.checkKey(key)) {
+ return Double.parseDouble(this.properties.getProperty(key));
+ } else {
+ return null;
+ }
+ }
+
+ /**
* Get the file associated with this configuration or <code>null</code> if not set.
- * @return The file associated with the configuration.
+ *
+ * @return the file associated with the configuration
*/
public File getFile() {
- return file;
- }
-
- /**
- * Get the resource path associated with this configuration or <code>null</code> if not
- * applicable.
- * @return The resource path of this configuration.
+ return this.file;
+ }
+
+ /**
+ * Get a key value as an integer.
+ *
+ * @param key the key to lookup
+ * @return the value as an <code>Integer</code> or <code>null</code> if does not exist
+ */
+ Integer getInteger(final String key) {
+ if (this.checkKey(key)) {
+ return Integer.parseInt(this.properties.getProperty(key));
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get the property keys.
+ *
+ * @return the collection of property keys
+ */
+ public Set<String> getKeys() {
+ return this.properties.stringPropertyNames();
+ }
+
+ /**
+ * Get a key value as a Long.
+ *
+ * @param key the key to lookup
+ * @return the key value as a <code>Long</code>
+ */
+ Long getLong(final String key) {
+ if (this.checkKey(key)) {
+ return Long.parseLong(this.properties.getProperty(key));
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get the resource path associated with this configuration or <code>null</code> if not applicable.
+ *
+ * @return the resource path of this configuration
*/
public String getResourcePath() {
- return resourcePath;
- }
-
- /**
- * True if configuration has value for the key.
- * @param key The key.
- * @return True if configuration has value for the key.
- */
- boolean hasKey(String key) {
- try {
- return properties.containsKey(key);
- } catch (java.lang.NullPointerException e) {
+ return this.resourcePath;
+ }
+
+ /**
+ * Return <code>true</code> if configuration has value for the key.
+ *
+ * @param key the key
+ * @return <code>true</code> if configuration has value for the key
+ */
+ boolean hasKey(final String key) {
+ try {
+ return this.properties.containsKey(key);
+ } catch (final java.lang.NullPointerException e) {
return false;
}
}
/**
- * Get a key value as a string.
- * @param key The key to lookup.
- * @return The value or null if does not exist.
- */
- String get(String key) {
- if (checkKey(key)) {
- // Return the key value for properties that are set.
- return properties.getProperty(key);
- } else {
- // Return null for unset properties.
- return null;
- }
- }
-
- /**
- * Get a key value as a boolean.
- * @param key The key to lookup.
- * @return The value or null if does not exist.
- */
- Boolean getBoolean(String key) {
- if (checkKey(key)) {
- return Boolean.parseBoolean(properties.getProperty(key));
- } else {
- return null;
- }
- }
-
- /**
- * Get a key value as a double.
- * @param key The key to lookup.
- * @return The value or null if does not exist.
- */
- Double getDouble(String key) {
- if (checkKey(key)) {
- return Double.parseDouble(properties.getProperty(key));
- } else {
- return null;
- }
- }
-
- /**
- * Get a key value as an integer.
- * @param key The key to lookup.
- * @return The value or null if does not exist.
- */
- Integer getInteger(String key) {
- if (checkKey(key)) {
- return Integer.parseInt(properties.getProperty(key));
- } else {
- return null;
- }
- }
-
- /**
- * Get a key value as a Long.
- * @param key The key to lookup.
- * @param key The value or null if does not exist.
- * @return
- */
- Long getLong(String key) {
- if (checkKey(key)) {
- return Long.parseLong(properties.getProperty(key));
- } else {
- return null;
- }
+ * Merge in values from another configuration into this one which will override properties that already exist with
+ * new values.
+ *
+ * @param configuration the configuration with the properties to merge
+ */
+ void merge(final Configuration configuration) {
+ for (final String property : configuration.getKeys()) {
+ this.set(property, configuration.get(property));
+ }
+ }
+
+ /**
+ * Remove a configuration value.
+ *
+ * @param key the key of the value
+ */
+ void remove(final String key) {
+ this.properties.remove(key);
+ }
+
+ /**
+ * Set a configuration value.
+ *
+ * @param key the key for lookup
+ * @param value the value to assign to that key
+ */
+ void set(final String key, final Object value) {
+ this.properties.put(key, String.valueOf(value));
+ }
+
+ /**
+ * Convert this object to a string by printing out its properties list.
+ */
+ @Override
+ public String toString() {
+ return this.properties.toString();
}
/**
* Write this configuration to a file and set that file as the current one.
+ *
* @param file The output file.
*/
- public void writeToFile(File file) {
+ public void writeToFile(final File file) {
this.file = file;
try {
- properties.store(new FileOutputStream(this.file), null);
- } catch (IOException e) {
+ this.properties.store(new FileOutputStream(this.file), null);
+ } catch (final IOException e) {
throw new RuntimeException("Error saving properties file.", e);
}
}
-
- /**
- * Check if the properties contains the key and if it has a non-null value.
- * @param key The properties key.
- * @return True if properties key is valid.
- */
- boolean checkKey(String key) {
- return hasKey(key) && properties.getProperty(key) != null;
- }
-
- /**
- * Set a configuration value.
- * @param key The key for lookup.
- * @param value The value to assign to that key.
- */
- void set(String key, Object value) {
- properties.put(key, String.valueOf(value));
- }
-
- /**
- * Remove a configuration value.
- * @param key The key of the value.
- */
- void remove(String key) {
- properties.remove(key);
- }
-
- /**
- * Convert this object to a string by printing out its properties list.
- */
- public String toString() {
- return properties.toString();
- }
-
- /**
- * Get the property keys.
- * @return The collection of property keys.
- */
- public Set<String> getKeys() {
- return properties.stringPropertyNames();
- }
-
- /**
- * Merge in values from another configuration into this one which will override
- * properties that already exist with new values.
- * @param configuration The configuration with the properties to merge.
- */
- void merge(Configuration configuration) {
- for (String property : configuration.getKeys()) {
- this.set(property, configuration.get(property));
- }
- }
}
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 Apr 21 14:48:39 2015
@@ -9,497 +9,1072 @@
import org.jlab.coda.et.enums.Mode;
/**
- * A model of the global configuration parameters that can be used to automatically update the GUI
- * from a configuration or push changes from GUI components into the current configuration.
+ * A model of the global configuration parameters that can be used to automatically update the GUI from a configuration
+ * or push changes from GUI components into the current configuration.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
public final class ConfigurationModel extends AbstractModel {
- Configuration configuration;
-
- // Job setting properties.
+ /**
+ * Name of AIDA server.
+ */
public static final String AIDA_SERVER_NAME_PROPERTY = "AIDAServerName";
+
+ /**
+ * ET blocking setting.
+ */
+ public static final String BLOCKING_PROPERTY = "Blocking";
+
+ /**
+ * ET chunk size (number of events per ET <code>getEvents</code>).
+ */
+ public static final String CHUNK_SIZE_PROPERTY = "ChunkSize";
+
+ /**
+ * Conditions tag.
+ */
public static final String CONDITIONS_TAG_PROPERTY = "ConditionsTag";
+
+ /**
+ * The list of all property names.
+ */
+ static final String[] CONFIG_PROPERTIES = AbstractModel.getPropertyNames(ConfigurationModel.class);
+
+ /**
+ * The data source path which is a file path if using a file source (EVIO or LCIO file.
+ */
+ public static final String DATA_SOURCE_PATH_PROPERTY = "DataSourcePath";
+
+ /**
+ * The data source type (EVIO, LCIO or ET).
+ *
+ * @see org.hps.record.enums.DataSourceType
+ * @return the data source type
+ */
+ public static final String DATA_SOURCE_TYPE_PROPERTY = "DataSourceType";
+
+ /**
+ * The detector alias which is pointing to a local compact.xml detector file.
+ */
+ public static final String DETECTOR_ALIAS_PROPERTY = "DetectorAlias";
+
+ /**
+ * The name of a detector model to use from the jar file.
+ */
public static final String DETECTOR_NAME_PROPERTY = "DetectorName";
- public static final String DETECTOR_ALIAS_PROPERTY = "DetectorAlias";
+
+ /**
+ * Flag to enable disconnecting when an EVIO END event is received.
+ */
+ public static final String DISCONNECT_ON_END_RUN_PROPERTY = "DisconnectOnEndRun";
+
+ /**
+ * Flag to enable disconnecting if an event processing error occurs.
+ */
public static final String DISCONNECT_ON_ERROR_PROPERTY = "DisconnectOnError";
- public static final String DISCONNECT_ON_END_RUN_PROPERTY = "DisconnectOnEndRun";
+
+ /**
+ * The name of the ET system which is generally a file on disk.
+ */
+ public static final String ET_NAME_PROPERTY = "EtName";
+
+ /**
+ * The name of the event builder for converting from EVIO to LCIO events.
+ */
public static final String EVENT_BUILDER_PROPERTY = "EventBuilderClassName";
+
+ /**
+ * Flag to freeze conditions system after initialization.
+ */
public static final String FREEZE_CONDITIONS_PROPERTY = "FreezeConditions";
+
+ /**
+ * The ET host property (TCP/IP host name).
+ */
+ public static final String HOST_PROPERTY = "Host";
+
+ /**
+ * The name of the output log file.
+ */
public static final String LOG_FILE_NAME_PROPERTY = "LogFileName";
+
+ /**
+ * The filter level for displaying records in the log table.
+ */
+ public static final String LOG_LEVEL_FILTER_PROPERTY = "LogLevelFilter";
+
+ /**
+ * The global log level.
+ */
public static final String LOG_LEVEL_PROPERTY = "LogLevel";
- public static final String LOG_LEVEL_FILTER_PROPERTY = "LogLevelFilter";
+
+ /**
+ * Flag to log to a file.
+ */
public static final String LOG_TO_FILE_PROPERTY = "LogToFile";
+
+ /**
+ * Max events after which session will be automatically ended.
+ */
public static final String MAX_EVENTS_PROPERTY = "MaxEvents";
+
+ /**
+ * The maximum number of recent files (hard-coded to 10 to match 0-9 shortcut mnemonics).
+ */
+ private static final int MAX_RECENT_FILES = 10;
+
+ /**
+ * The ET TCP/IP port.
+ */
+ public static final String PORT_PROPERTY = "Port";
+
+ /**
+ * The ET pre-scaling value which throttles event rate.
+ */
+ public static final String PRESCALE_PROPERTY = "Prescale";
+
+ /**
+ * The processing stage(s) to execute (ET, EVIO or LCIO).
+ */
+ public static final String PROCESSING_STAGE_PROPERTY = "ProcessingStage";
+
+ /**
+ * The ET queue size.
+ */
+ public static final String QUEUE_SIZE_PROPERTY = "QueueSize";
+
+ /**
+ * The list of recent files.
+ */
public static final String RECENT_FILES_PROPERTY = "RecentFiles";
+
+ /**
+ * The ET station name.
+ */
+ public static final String STATION_NAME_PROPERTY = "StationName";
+
+ /**
+ * The ET station position.
+ */
+ public static final String STATION_POSITION_PROPERTY = "StationPosition";
+
+ /**
+ * The steering file.
+ */
+ public static final String STEERING_FILE_PROPERTY = "SteeringFile";
+
+ /**
+ * The steering resource.
+ */
+ public static final String STEERING_RESOURCE_PROPERTY = "SteeringResource";
+
+ /**
+ * The steering type (file or resource).
+ */
public static final String STEERING_TYPE_PROPERTY = "SteeringType";
- public static final String STEERING_FILE_PROPERTY = "SteeringFile";
- public static final String STEERING_RESOURCE_PROPERTY = "SteeringResource";
+
+ /**
+ * A user run number to use for initializing the conditions system.
+ */
public static final String USER_RUN_NUMBER_PROPERTY = "UserRunNumber";
- // Data source properties.
- public static final String DATA_SOURCE_TYPE_PROPERTY = "DataSourceType";
- public static final String DATA_SOURCE_PATH_PROPERTY = "DataSourcePath";
- public static final String PROCESSING_STAGE_PROPERTY = "ProcessingStage";
-
- // ET connection parameters.
- public static final String ET_NAME_PROPERTY = "EtName";
- public static final String HOST_PROPERTY = "Host";
- public static final String PORT_PROPERTY = "Port";
- public static final String BLOCKING_PROPERTY = "Blocking";
+ /**
+ * The verbose setting for the ET system.
+ */
public static final String VERBOSE_PROPERTY = "Verbose";
- public static final String STATION_NAME_PROPERTY = "StationName";
- public static final String CHUNK_SIZE_PROPERTY = "ChunkSize";
- public static final String QUEUE_SIZE_PROPERTY = "QueueSize";
- public static final String STATION_POSITION_PROPERTY = "StationPosition";
+
+ /**
+ * The ET wait mode.
+ */
public static final String WAIT_MODE_PROPERTY = "WaitMode";
+
+ /**
+ * The ET wait time (if using timed wait mode).
+ */
public static final String WAIT_TIME_PROPERTY = "WaitTime";
- public static final String PRESCALE_PROPERTY = "Prescale";
-
- // Action command to get notified after configuration change is performed.
- public static final String CONFIGURATION_CHANGED = "configurationChanged";
-
- static final String[] CONFIG_PROPERTIES = AbstractModel.getPropertyNames(ConfigurationModel.class);
-
+
+ /**
+ * The underlying properties for the model.
+ */
+ private Configuration configuration;
+
+ /**
+ * Class constructor.
+ * <p>
+ * Create a new model without any initial property settings.
+ */
public ConfigurationModel() {
this.configuration = new Configuration();
}
- public ConfigurationModel(Configuration configuration) {
+ /**
+ * Class constructor.
+ * <p>
+ * Sets the properties from a configuration (file or resource).
+ *
+ * @param configuration the configuration containing property settings
+ */
+ public ConfigurationModel(final Configuration configuration) {
this.configuration = configuration;
- fireModelChanged();
- }
-
- public void setConfiguration(Configuration configuration) {
- this.configuration = configuration;
- fireModelChanged();
- }
-
+ this.fireModelChanged();
+ }
+
+ /**
+ * Add a single recent file.
+ *
+ * @param recentFile the recent file to add
+ */
+ public void addRecentFile(final String recentFile) {
+ if (!this.configuration.checkKey(RECENT_FILES_PROPERTY)) {
+ this.configuration.set(RECENT_FILES_PROPERTY, recentFile);
+ this.firePropertyChange(RECENT_FILES_PROPERTY, null, recentFile);
+ } else {
+ final List<String> recentFilesList = this.getRecentFilesList();
+ if (!recentFilesList.contains(recentFile)) {
+ if (this.getRecentFilesList().size() >= MAX_RECENT_FILES) {
+ // Bump the first file from the list if max recent files is exceeded (10 files).
+ recentFilesList.remove(0);
+ this.setRecentFilesList(recentFilesList);
+ }
+ final String oldValue = this.configuration.get(RECENT_FILES_PROPERTY);
+ final String recentFiles = oldValue + "\n" + recentFile;
+ this.configuration.set(RECENT_FILES_PROPERTY, recentFiles);
+ this.firePropertyChange(RECENT_FILES_PROPERTY, oldValue, recentFile);
+ }
+ }
+
+ }
+
+ /**
+ * Fire property change for all property keys.
+ */
+ @Override
+ public void fireModelChanged() {
+ this.firePropertiesChanged(this.configuration.getKeys());
+ }
+
+ /**
+ * Get the AIDA server name.
+ *
+ * @return the AIDA server name
+ */
+ public String getAIDAServerName() {
+ return this.configuration.get(AIDA_SERVER_NAME_PROPERTY);
+ }
+
+ /**
+ * Get the ET blocking setting.
+ *
+ * @return the ET blocking setting
+ */
+ public Boolean getBlocking() {
+ return this.configuration.getBoolean(BLOCKING_PROPERTY);
+ }
+
+ /**
+ * Get the ET chunk size, which is the number of events that will be retrieved at once from the server.
+ *
+ * @return the ET chunk size
+ */
+ public Integer getChunkSize() {
+ return this.configuration.getInteger(CHUNK_SIZE_PROPERTY);
+ }
+
+ /**
+ * Get the conditions system tag.
+ *
+ * @return the conditions system tag
+ */
+ public String getConditionsTag() {
+ return this.configuration.get(CONDITIONS_TAG_PROPERTY);
+ }
+
+ /**
+ * Get the underlying configuration containing properties.
+ *
+ * @return the underlying configuration with properties settings
+ */
public Configuration getConfiguration() {
return this.configuration;
}
- public Level getLogLevel() {
- return Level.parse(configuration.get(LOG_LEVEL_PROPERTY));
- }
-
- public void setLogLevel(Level level) {
- Level oldValue = getLogLevel();
- configuration.set(LOG_LEVEL_PROPERTY, level.getName());
- firePropertyChange(LOG_LEVEL_PROPERTY, oldValue, getLogLevel());
- }
-
- public Level getLogLevelFilter() {
- return Level.parse(configuration.get(LOG_LEVEL_FILTER_PROPERTY));
- }
-
- public void setLogLevelFilter(Level level) {
- Level oldValue = getLogLevelFilter();
- configuration.set(LOG_LEVEL_FILTER_PROPERTY, level.getName());
- firePropertyChange(LOG_LEVEL_FILTER_PROPERTY, oldValue, getLogLevelFilter());
- }
-
- public SteeringType getSteeringType() {
- return SteeringType.valueOf(configuration.get(STEERING_TYPE_PROPERTY));
- }
-
- public void setSteeringType(SteeringType steeringType) {
- SteeringType oldValue = getSteeringType();
- configuration.set(STEERING_TYPE_PROPERTY, steeringType.name());
- firePropertyChange(STEERING_TYPE_PROPERTY, oldValue, getSteeringType());
- }
-
- public String getSteeringFile() {
- return configuration.get(STEERING_FILE_PROPERTY);
- }
-
- public void setSteeringFile(String steeringFile) {
- String oldValue = getSteeringFile();
- configuration.set(STEERING_FILE_PROPERTY, steeringFile);
- firePropertyChange(STEERING_FILE_PROPERTY, oldValue, getSteeringFile());
- }
-
- public String getSteeringResource() {
- return configuration.get(STEERING_RESOURCE_PROPERTY);
- }
-
- public void setSteeringResource(String steeringResource) {
- String oldValue = getSteeringResource();
- configuration.set(STEERING_RESOURCE_PROPERTY, steeringResource);
- firePropertyChange(STEERING_RESOURCE_PROPERTY, oldValue, steeringResource);
- }
-
- public String getDetectorName() {
- return configuration.get(DETECTOR_NAME_PROPERTY);
- }
-
- public void setDetectorName(String detectorName) {
- String oldValue = getDetectorName();
- configuration.set(DETECTOR_NAME_PROPERTY, detectorName);
- firePropertyChange(DETECTOR_NAME_PROPERTY, oldValue, getDetectorName());
- }
-
- public String getDetectorAlias() {
- return configuration.get(DETECTOR_ALIAS_PROPERTY);
- }
-
- public void setDetectorAlias(String detectorAlias) {
- String oldValue = null;
- if (hasPropertyKey(DETECTOR_ALIAS_PROPERTY)) {
- oldValue = getDetectorAlias();
- }
- configuration.set(DETECTOR_ALIAS_PROPERTY, detectorAlias);
- firePropertyChange(DETECTOR_ALIAS_PROPERTY, oldValue, getDetectorAlias());
- }
-
- public String getEventBuilderClassName() {
- return configuration.get(EVENT_BUILDER_PROPERTY);
- }
-
- public void setEventBuilderClassName(String eventBuilderClassName) {
- String oldValue = getEventBuilderClassName();
- configuration.set(EVENT_BUILDER_PROPERTY, eventBuilderClassName);
- firePropertyChange(EVENT_BUILDER_PROPERTY, oldValue, getEventBuilderClassName());
- }
-
- public Boolean getLogToFile() {
- return configuration.getBoolean(LOG_TO_FILE_PROPERTY);
- }
-
- public void setLogToFile(Boolean logToFile) {
- Boolean oldValue = getLogToFile();
- configuration.set(LOG_TO_FILE_PROPERTY, logToFile);
- firePropertyChange(LOG_TO_FILE_PROPERTY, oldValue, getLogToFile());
- }
-
- public String getLogFileName() {
- return configuration.get(LOG_FILE_NAME_PROPERTY);
- }
-
- public void setLogFileName(String logFileName) {
- String oldValue = getLogFileName();
- configuration.set(LOG_FILE_NAME_PROPERTY, logFileName);
- firePropertyChange(LOG_FILE_NAME_PROPERTY, oldValue, getLogFileName());
- }
-
- public Boolean getDisconnectOnError() {
- return configuration.getBoolean(DISCONNECT_ON_ERROR_PROPERTY);
- }
-
- public void setDisconnectOnError(Boolean disconnectOnError) {
- Boolean oldValue = getDisconnectOnError();
- configuration.set(DISCONNECT_ON_ERROR_PROPERTY, disconnectOnError);
- firePropertyChange(DISCONNECT_ON_ERROR_PROPERTY, oldValue, getDisconnectOnError());
- }
-
- public Boolean getDisconnectOnEndRun() {
- return configuration.getBoolean(DISCONNECT_ON_END_RUN_PROPERTY);
- }
-
- public void setDisconnectOnEndRun(Boolean disconnectOnEndRun) {
- Boolean oldValue = getDisconnectOnEndRun();
- configuration.set(DISCONNECT_ON_END_RUN_PROPERTY, disconnectOnEndRun);
- firePropertyChange(DISCONNECT_ON_END_RUN_PROPERTY, oldValue, getDisconnectOnEndRun());
- }
-
+ /**
+ * Get the data source path.
+ *
+ * @return the data source path
+ */
+ public String getDataSourcePath() {
+ return this.configuration.get(DATA_SOURCE_PATH_PROPERTY);
+ }
+
+ /**
+ * Get the data source type (EVIO, LCIO or ET).
+ *
+ * @return the data source type
+ */
public DataSourceType getDataSourceType() {
- if (configuration.checkKey(DATA_SOURCE_TYPE_PROPERTY)) {
- return DataSourceType.valueOf(configuration.get(DATA_SOURCE_TYPE_PROPERTY));
+ if (this.configuration.checkKey(DATA_SOURCE_TYPE_PROPERTY)) {
+ return DataSourceType.valueOf(this.configuration.get(DATA_SOURCE_TYPE_PROPERTY));
} else {
return null;
}
}
- public void setDataSourceType(DataSourceType dataSourceType) {
- DataSourceType oldValue = getDataSourceType();
- configuration.set(DATA_SOURCE_TYPE_PROPERTY, dataSourceType);
- firePropertyChange(DATA_SOURCE_TYPE_PROPERTY, oldValue, getDataSourceType());
- }
-
- public String getDataSourcePath() {
- return configuration.get(DATA_SOURCE_PATH_PROPERTY);
- }
-
- public void setDataSourcePath(String dataSourcePath) {
- String oldValue = getDataSourcePath();
- configuration.set(DATA_SOURCE_PATH_PROPERTY, dataSourcePath);
- firePropertyChange(DATA_SOURCE_PATH_PROPERTY, oldValue, getDataSourcePath());
- }
-
- /*
- public void setDataSource(String dataSource) {
- setDataSourcePath(dataSource);
- DataSourceType dst = DataSourceType.getDataSourceType(dataSource);
- setDataSourceType(dst);
- }
- */
-
+ /**
+ * Get the detector alias which is a compact.xml file on disk.
+ *
+ * @return the detector alias
+ */
+ public String getDetectorAlias() {
+ return this.configuration.get(DETECTOR_ALIAS_PROPERTY);
+ }
+
+ /**
+ * Get the detector name.
+ *
+ * @return the detector name
+ */
+ public String getDetectorName() {
+ return this.configuration.get(DETECTOR_NAME_PROPERTY);
+ }
+
+ /**
+ * Get the disconnect on end run flag.
+ *
+ * @return the disconnect on end run flag
+ */
+ public Boolean getDisconnectOnEndRun() {
+ return this.configuration.getBoolean(DISCONNECT_ON_END_RUN_PROPERTY);
+ }
+
+ /**
+ * Get the disconnect on error flag.
+ *
+ * @return the disconnect on error flag
+ */
+ public Boolean getDisconnectOnError() {
+ return this.configuration.getBoolean(DISCONNECT_ON_ERROR_PROPERTY);
+ }
+
+ /**
+ * Get the ET system name.
+ *
+ * @return the ET system name
+ */
+ public String getEtName() {
+ return this.configuration.get(ET_NAME_PROPERTY);
+ }
+
+ /**
+ * Get the ET path from concatenating the ET system name, host and post (which is just used for the GUI).
+ *
+ * @return the ET path
+ */
+ public String getEtPath() {
+ return this.getEtName() + "@" + this.getHost() + ":" + this.getPort();
+ }
+
+ /**
+ * Get the event builder class name.
+ *
+ * @return the event builder class name
+ */
+ public String getEventBuilderClassName() {
+ return this.configuration.get(EVENT_BUILDER_PROPERTY);
+ }
+
+ /**
+ * Get the freeze conditions setting which will cause conditions system to be frozen after initialization with the
+ * currently selected run number and detector name.
+ *
+ * @return the freeze conditions setting
+ */
+ public Boolean getFreezeConditions() {
+ return this.configuration.getBoolean(FREEZE_CONDITIONS_PROPERTY);
+ }
+
+ /**
+ * Get the ET host name.
+ *
+ * @return the ET host name
+ */
+ public String getHost() {
+ return this.configuration.get(HOST_PROPERTY);
+ }
+
+ /**
+ * Get the log file name.
+ *
+ * @return the log file name
+ */
+ public String getLogFileName() {
+ return this.configuration.get(LOG_FILE_NAME_PROPERTY);
+ }
+
+ /**
+ * Get the global log level.
+ *
+ * @return the global log level
+ */
+ public Level getLogLevel() {
+ return Level.parse(this.configuration.get(LOG_LEVEL_PROPERTY));
+ }
+
+ /**
+ * Get the log level filter for displaying messages in the log table.
+ *
+ * @return the log level filter
+ */
+ public Level getLogLevelFilter() {
+ return Level.parse(this.configuration.get(LOG_LEVEL_FILTER_PROPERTY));
+ }
+
+ /**
+ * Get the log to file setting which redirects monitoring application log messages from the console to a file.
+ *
+ * @return the log to file setting
+ */
+ public Boolean getLogToFile() {
+ return this.configuration.getBoolean(LOG_TO_FILE_PROPERTY);
+ }
+
+ /**
+ * Get the maximum number of events before disconnecting.
+ *
+ * @return the maximum number of events before disconnecting
+ */
+ public Long getMaxEvents() {
+ return this.configuration.getLong(MAX_EVENTS_PROPERTY);
+ }
+
+ /**
+ * Get the ET TCP/IP port value.
+ *
+ * @return the ET TCP/IP port value
+ */
+ public Integer getPort() {
+ return this.configuration.getInteger(PORT_PROPERTY);
+ }
+
+ /**
+ * Get the ET station prescale value.
+ *
+ * @return the ET station prescale value
+ */
+ public Integer getPrescale() {
+ return this.configuration.getInteger(PRESCALE_PROPERTY);
+ }
+
+ /**
+ * Get the processing stage.
+ * <p>
+ * Each level will execute the preceding ones, e.g. LCIO exectures EVIO, ET and LCIO event processing
+ *
+ * @return the processing stage to execute
+ */
public ProcessingStage getProcessingStage() {
- if (configuration.get(PROCESSING_STAGE_PROPERTY) == null)
+ if (this.configuration.get(PROCESSING_STAGE_PROPERTY) == null) {
throw new RuntimeException(PROCESSING_STAGE_PROPERTY + " is null!!!");
- return ProcessingStage.valueOf(configuration.get(PROCESSING_STAGE_PROPERTY));
- }
-
- public void setProcessingStage(ProcessingStage processingStage) {
- ProcessingStage oldValue = getProcessingStage();
- configuration.set(PROCESSING_STAGE_PROPERTY, processingStage);
- firePropertyChange(PROCESSING_STAGE_PROPERTY, oldValue, getProcessingStage());
- }
-
- public String getEtName() {
- return configuration.get(ET_NAME_PROPERTY);
- }
-
- public void setEtName(String etName) {
- String oldValue = getEtName();
- configuration.set(ET_NAME_PROPERTY, etName);
- firePropertyChange(ET_NAME_PROPERTY, oldValue, getEtName());
- }
-
- public String getHost() {
- return configuration.get(HOST_PROPERTY);
- }
-
- public void setHost(String host) {
- String oldValue = getHost();
- configuration.set(HOST_PROPERTY, host);
- firePropertyChange(HOST_PROPERTY, oldValue, getHost());
- }
-
- public Integer getPort() {
- return configuration.getInteger(PORT_PROPERTY);
- }
-
- public void setPort(Integer port) {
- Integer oldValue = getPort();
- configuration.set(PORT_PROPERTY, port);
- firePropertyChange(PORT_PROPERTY, oldValue, getPort());
- }
-
- public Boolean getBlocking() {
- return configuration.getBoolean(BLOCKING_PROPERTY);
- }
-
- public void setBlocking(Boolean blocking) {
- Boolean oldValue = getBlocking();
- configuration.set(BLOCKING_PROPERTY, blocking);
- firePropertyChange(BLOCKING_PROPERTY, oldValue, getBlocking());
- }
-
- public Boolean getVerbose() {
- return configuration.getBoolean(VERBOSE_PROPERTY);
- }
-
- public void setVerbose(Boolean verbose) {
- Boolean oldValue = getVerbose();
- configuration.set(VERBOSE_PROPERTY, verbose);
- firePropertyChange(VERBOSE_PROPERTY, oldValue, getVerbose());
- }
-
- public String getStationName() {
- return configuration.get(STATION_NAME_PROPERTY);
- }
-
- public void setStationName(String stationName) {
- String oldValue = getStationName();
- configuration.set(STATION_NAME_PROPERTY, stationName);
- firePropertyChange(STATION_NAME_PROPERTY, oldValue, getStationName());
- }
-
- public Integer getChunkSize() {
- return configuration.getInteger(CHUNK_SIZE_PROPERTY);
- }
-
- public void setChunkSize(Integer chunkSize) {
- Integer oldValue = getChunkSize();
- configuration.set(CHUNK_SIZE_PROPERTY, chunkSize);
- firePropertyChange(CHUNK_SIZE_PROPERTY, oldValue, getChunkSize());
- }
-
+ }
+ return ProcessingStage.valueOf(this.configuration.get(PROCESSING_STAGE_PROPERTY));
+ }
+
+ /**
+ * Get the property names in the configuration.
+ *
+ * @return the property names in the configuration
+ */
+ @Override
+ public String[] getPropertyNames() {
+ return CONFIG_PROPERTIES;
+ }
+
+ /**
+ * Get the ET queue size.
+ *
+ * @return the ET queue size
+ */
public Integer getQueueSize() {
- return configuration.getInteger(QUEUE_SIZE_PROPERTY);
- }
-
- public void setQueueSize(Integer queueSize) {
- Integer oldValue = getQueueSize();
- configuration.set(QUEUE_SIZE_PROPERTY, queueSize);
- firePropertyChange(QUEUE_SIZE_PROPERTY, oldValue, getQueueSize());
- }
-
- public Integer getStationPosition() {
- return configuration.getInteger(STATION_POSITION_PROPERTY);
- }
-
- public void setStationPosition(Integer stationPosition) {
- Integer oldValue = getStationPosition();
- configuration.set(STATION_POSITION_PROPERTY, stationPosition);
- firePropertyChange(STATION_POSITION_PROPERTY, oldValue, getStationPosition());
- }
-
- public Mode getWaitMode() {
- return Mode.valueOf(configuration.get(WAIT_MODE_PROPERTY));
- }
-
- public void setWaitMode(Mode waitMode) {
- Mode oldValue = getWaitMode();
- configuration.set(WAIT_MODE_PROPERTY, waitMode.name());
- firePropertyChange(WAIT_MODE_PROPERTY, oldValue, getWaitMode());
- }
-
- public Integer getWaitTime() {
- return configuration.getInteger(WAIT_TIME_PROPERTY);
- }
-
- public void setWaitTime(Integer waitTime) {
- Integer oldValue = getWaitTime();
- configuration.set(WAIT_TIME_PROPERTY, waitTime);
- firePropertyChange(WAIT_TIME_PROPERTY, oldValue, getWaitTime());
- }
-
- public Integer getPrescale() {
- return configuration.getInteger(PRESCALE_PROPERTY);
- }
-
- public void setPrescale(Integer prescale) {
- Integer oldValue = getPrescale();
- configuration.set(PRESCALE_PROPERTY, prescale);
- firePropertyChange(PRESCALE_PROPERTY, oldValue, getPrescale());
- }
-
- public void setUserRunNumber(Integer userRunNumber) {
- Integer oldValue = null;
- if (hasPropertyKey(USER_RUN_NUMBER_PROPERTY)) {
- oldValue = getUserRunNumber();
- }
- configuration.set(USER_RUN_NUMBER_PROPERTY, userRunNumber);
- firePropertyChange(USER_RUN_NUMBER_PROPERTY, oldValue, getUserRunNumber());
- }
-
- public Integer getUserRunNumber() {
- return configuration.getInteger(USER_RUN_NUMBER_PROPERTY);
- }
-
- public void setFreezeConditions(Boolean freezeConditions) {
- Boolean oldValue = null;
- if (hasPropertyKey(FREEZE_CONDITIONS_PROPERTY)) {
- oldValue = getFreezeConditions();
- }
- configuration.set(FREEZE_CONDITIONS_PROPERTY, freezeConditions);
- firePropertyChange(FREEZE_CONDITIONS_PROPERTY, oldValue, freezeConditions);
- }
-
- public Boolean getFreezeConditions() {
- return configuration.getBoolean(FREEZE_CONDITIONS_PROPERTY);
- }
-
- public void setMaxEvents(Long maxEvents) {
- Long oldValue = getMaxEvents();
- configuration.set(MAX_EVENTS_PROPERTY, maxEvents);
- firePropertyChange(MAX_EVENTS_PROPERTY, oldValue, getMaxEvents());
- }
-
- public Long getMaxEvents() {
- return configuration.getLong(MAX_EVENTS_PROPERTY);
- }
-
- 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 setAIDAServerName(String AIDAServerName) {
- String oldValue = getAIDAServerName();
- configuration.set(AIDA_SERVER_NAME_PROPERTY, AIDAServerName);
- firePropertyChange(AIDA_SERVER_NAME_PROPERTY, oldValue, getAIDAServerName());
- }
-
- public String getAIDAServerName() {
- return configuration.get(AIDA_SERVER_NAME_PROPERTY);
- }
-
+ return this.configuration.getInteger(QUEUE_SIZE_PROPERTY);
+ }
+
+ /**
+ * Get recent files as a string with paths separated by the '\n' string.
+ *
+ * @return the recent files as a delimited string
+ */
public String getRecentFiles() {
- if (configuration.hasKey(RECENT_FILES_PROPERTY)) {
- return configuration.get(RECENT_FILES_PROPERTY);
+ if (this.configuration.hasKey(RECENT_FILES_PROPERTY)) {
+ return this.configuration.get(RECENT_FILES_PROPERTY);
} else {
return null;
- }
- }
-
+ }
+ }
+
+ /**
+ * Get the recent files list.
+ * <p>
+ * This is actually just a copy from the property, so to set the recent file list call
+ * {@link #setRecentFiles(String)}.
+ *
+ * @return the recent files list
+ */
public List<String> getRecentFilesList() {
- List<String> recentFilesList = new ArrayList<String>();
- if (configuration.hasKey(RECENT_FILES_PROPERTY)) {
- for (String recentFile : configuration.get(RECENT_FILES_PROPERTY).split("\n")) {
+ final List<String> recentFilesList = new ArrayList<String>();
+ if (this.configuration.hasKey(RECENT_FILES_PROPERTY)) {
+ for (final String recentFile : this.configuration.get(RECENT_FILES_PROPERTY).split("\n")) {
recentFilesList.add(recentFile);
}
}
return recentFilesList;
}
-
- public void addRecentFile(String recentFile) {
- if (!configuration.checkKey(RECENT_FILES_PROPERTY)) {
- configuration.set(RECENT_FILES_PROPERTY, recentFile);
- firePropertyChange(RECENT_FILES_PROPERTY, null, recentFile);
- } else {
- List<String> recentFilesList = getRecentFilesList();
- if (!recentFilesList.contains(recentFile)) {
- if (getRecentFilesList().size() >= 10) {
- throw new IllegalArgumentException("Maximum number of recent files reached.");
- }
- String oldValue = configuration.get(RECENT_FILES_PROPERTY);
- String recentFiles = oldValue + "\n" + recentFile;
- configuration.set(RECENT_FILES_PROPERTY, recentFiles);
- firePropertyChange(RECENT_FILES_PROPERTY, oldValue, recentFile);
+
+ /**
+ * Get the ET station name.
+ *
+ * @return the ET station name
+ */
+ public String getStationName() {
+ return this.configuration.get(STATION_NAME_PROPERTY);
+ }
+
+ /**
+ * Get the ET station position.
+ *
+ * @return the ET station position
+ */
+ public Integer getStationPosition() {
+ return this.configuration.getInteger(STATION_POSITION_PROPERTY);
+ }
+
+ /**
+ * Get the steering file location (if using a file on disk).
+ *
+ * @return the XML file steering path
+ */
+ public String getSteeringFile() {
+ return this.configuration.get(STEERING_FILE_PROPERTY);
+ }
+
+ /**
+ * Get the steering resource (if using a jar resource).
+ *
+ * @return the steering resource location
+ */
+ public String getSteeringResource() {
+ return this.configuration.get(STEERING_RESOURCE_PROPERTY);
+ }
+
+ /**
+ * Get whether the steering is a file or resource.
+ *
+ * @return whether the steering is a file or resource
+ */
+ public SteeringType getSteeringType() {
+ return SteeringType.valueOf(this.configuration.get(STEERING_TYPE_PROPERTY));
+ }
+
+ /**
+ * Get the user run number for configuring the conditions system.
+ *
+ * @return the user run number for configuring the conditions system
+ */
+ public Integer getUserRunNumber() {
+ return this.configuration.getInteger(USER_RUN_NUMBER_PROPERTY);
+ }
+
+ /**
+ * Get the ET verbose flag.
+ *
+ * @return the ET verbose flag
+ */
+ public Boolean getVerbose() {
+ return this.configuration.getBoolean(VERBOSE_PROPERTY);
+ }
+
+ /**
+ * Get the ET wait mode.
+ *
+ * @return the ET wait mode
+ */
+ public Mode getWaitMode() {
+ return Mode.valueOf(this.configuration.get(WAIT_MODE_PROPERTY));
+ }
+
+ /**
+ * Get the ET wait time.
+ *
+ * @return the ET wait time
+ */
+ public Integer getWaitTime() {
+ return this.configuration.getInteger(WAIT_TIME_PROPERTY);
+ }
+
+ /**
+ * Return <code>true</code> if the given property key exists.
+ *
+ * @param key the property key
+ * @return <code>true</code> if property key exists (still might be <code>null</code>)
+ */
+ public boolean hasPropertyKey(final String key) {
+ return this.configuration.hasKey(key);
+ }
+
+ /**
+ * Return <code>true</code> if the given property key exists and is non-null.
+ *
+ * @param key the property key
+ * @return <code>true</code> if the property key exists and is non-null
+ */
+ public boolean hasValidProperty(final String key) {
+ return this.configuration.checkKey(key);
+ }
+
+ /**
+ * Merge another properties configuration into this one.
+ * <p>
+ * Settings from the merged properties will override this one.
+ *
+ * @param configuration the properties configuration to merge in
+ */
+ public void merge(final Configuration configuration) {
+ this.configuration.merge(configuration);
+ this.firePropertiesChanged(configuration.getKeys());
+ }
+
+ /**
+ * Remove the given property which should remove its key and value.
+ *
+ * @param property the property to remove
+ */
+ public void remove(final String property) {
+ if (this.hasPropertyKey(property)) {
+ final Object oldValue = this.configuration.get(property);
+ if (oldValue != null) {
+ this.configuration.remove(property);
+ this.firePropertyChange(property, oldValue, null);
}
}
-
- }
-
- public void setRecentFiles(String recentFiles) {
+ }
+
+ /**
+ * Set the name of the AIDA server.
+ *
+ * @param aidaServerName the name of the AIDA server
+ */
+ public void setAIDAServerName(final String aidaServerName) {
+ final String oldValue = this.getAIDAServerName();
+ this.configuration.set(AIDA_SERVER_NAME_PROPERTY, aidaServerName);
+ this.firePropertyChange(AIDA_SERVER_NAME_PROPERTY, oldValue, this.getAIDAServerName());
+ }
+
+ /**
+ * Set whether the ET station is blocking (generally this should not be set to <code>true</code>!)
+ *
+ * @param blocking <code>true</code> if station should be blocking
+ */
+ public void setBlocking(final Boolean blocking) {
+ final Boolean oldValue = this.getBlocking();
+ this.configuration.set(BLOCKING_PROPERTY, blocking);
+ this.firePropertyChange(BLOCKING_PROPERTY, oldValue, this.getBlocking());
+ }
+
+ /**
+ * The ET chunk size which is how many events should be returned at once in the array.
+ *
+ * @param chunkSize the ET chunk size
+ */
+ public void setChunkSize(final Integer chunkSize) {
+ final Integer oldValue = this.getChunkSize();
+ this.configuration.set(CHUNK_SIZE_PROPERTY, chunkSize);
+ this.firePropertyChange(CHUNK_SIZE_PROPERTY, oldValue, this.getChunkSize());
+ }
+
+ /**
+ * Set the conditions system tag.
+ *
+ * @param conditionsTag the conditions system tag
+ */
+ public void setConditionsTag(final String conditionsTag) {
+ final String oldValue = this.getConditionsTag();
+ this.configuration.set(CONDITIONS_TAG_PROPERTY, conditionsTag);
+ this.firePropertyChange(CONDITIONS_TAG_PROPERTY, oldValue, this.getConditionsTag());
+ }
+
+ /**
+ * Set a new configuration for the model which will fire property change events on all properties.
+ *
+ * @param configuration the configuration with properties for the model
+ */
+ public void setConfiguration(final Configuration configuration) {
+ this.configuration = configuration;
+ this.fireModelChanged();
+ }
+
+ /**
+ * Set the data source path which should be a valid EVIO or LCIO file on an accessible disk.
+ *
+ * @param dataSourcePath the data source path
+ */
+ public void setDataSourcePath(final String dataSourcePath) {
+ final String oldValue = this.getDataSourcePath();
+ this.configuration.set(DATA_SOURCE_PATH_PROPERTY, dataSourcePath);
+ this.firePropertyChange(DATA_SOURCE_PATH_PROPERTY, oldValue, this.getDataSourcePath());
+ }
+
+ /**
+ * Set the data source type (EVIO, LCIO or ET).
+ *
+ * @param dataSourceType the data source type
+ */
+ public void setDataSourceType(final DataSourceType dataSourceType) {
+ final DataSourceType oldValue = this.getDataSourceType();
+ this.configuration.set(DATA_SOURCE_TYPE_PROPERTY, dataSourceType);
+ this.firePropertyChange(DATA_SOURCE_TYPE_PROPERTY, oldValue, this.getDataSourceType());
+ }
+
+ /**
+ * Set the detector alias which is an alternate file path to use for the detector model instead of the one from jar.
+ *
+ * @param detectorAlias the detector alias
+ */
+ public void setDetectorAlias(final String detectorAlias) {
String oldValue = null;
- if (configuration.checkKey(RECENT_FILES_PROPERTY)) {
- oldValue = configuration.get(RECENT_FILES_PROPERTY);
+ if (this.hasPropertyKey(DETECTOR_ALIAS_PROPERTY)) {
+ oldValue = this.getDetectorAlias();
}
- configuration.set(RECENT_FILES_PROPERTY, recentFiles);
- firePropertyChange(RECENT_FILES_PROPERTY, oldValue, configuration.get(RECENT_FILES_PROPERTY));
- }
-
- public void remove(String property) {
- if (hasPropertyKey(property)) {
- Object oldValue = configuration.get(property);
- if (oldValue != null) {
- configuration.remove(property);
- firePropertyChange(property, oldValue, null);
- }
+ this.configuration.set(DETECTOR_ALIAS_PROPERTY, detectorAlias);
+ this.firePropertyChange(DETECTOR_ALIAS_PROPERTY, oldValue, this.getDetectorAlias());
+ }
+
+ /**
+ * Set the detector to load from the detector model resources in the jar.
+ * <p>
+ * These are present in the jar according to the LCSim convention:
+ *
+ * <pre>
+ * ${DETECTOR_NAME}/detector.properties
+ * </pre>
+ * <p>
+ * where <code>detector.properties</code> has the name of the detector matching the directory name.
+ *
+ * @param detectorName the name of the detector name
+ */
+ public void setDetectorName(final String detectorName) {
+ final String oldValue = this.getDetectorName();
+ this.configuration.set(DETECTOR_NAME_PROPERTY, detectorName);
+ this.firePropertyChange(DETECTOR_NAME_PROPERTY, oldValue, this.getDetectorName());
+ }
+
+ /**
+ * Set to <code>true</code> to disconnect when an EVIO END event is received.
+ *
+ * @param disconnectOnEndRun <code>true</code> to disconnect when an EVIO END event is received
+ */
+ public void setDisconnectOnEndRun(final Boolean disconnectOnEndRun) {
+ final Boolean oldValue = this.getDisconnectOnEndRun();
+ this.configuration.set(DISCONNECT_ON_END_RUN_PROPERTY, disconnectOnEndRun);
+ this.firePropertyChange(DISCONNECT_ON_END_RUN_PROPERTY, oldValue, this.getDisconnectOnEndRun());
+ }
+
+ /**
+ * Set to <code>true<code> to disconnect if event processing errors occur.
+ *
+ * @param disconnectOnError set to <code>true</code> to disconnect if event processing errors occur
+ */
+ public void setDisconnectOnError(final Boolean disconnectOnError) {
+ final Boolean oldValue = this.getDisconnectOnError();
+ this.configuration.set(DISCONNECT_ON_ERROR_PROPERTY, disconnectOnError);
+ this.firePropertyChange(DISCONNECT_ON_ERROR_PROPERTY, oldValue, this.getDisconnectOnError());
+ }
+
+ /**
+ * Set the name of the ET system which is usually a file.
+ * <p>
+ * Setting this to a valid file on disk being used by the ET server to buffer events will result in event processing
+ * speedup.
+ *
+ * @param etName the name of the ET system (usually a path on disk used as an event buffer by an ET server)
+ */
+ public void setEtName(final String etName) {
+ final String oldValue = this.getEtName();
+ this.configuration.set(ET_NAME_PROPERTY, etName);
+ this.firePropertyChange(ET_NAME_PROPERTY, oldValue, this.getEtName());
+ }
+
+ /**
+ * Set the fully qualified class name of the {@link org.hps.record.LCSimEventBuilder} that should be used to build
+ * LCIO events from EVIO.
+ *
+ * @param eventBuilderClassName the fully qualified class name of the event builder
+ */
+ public void setEventBuilderClassName(final String eventBuilderClassName) {
+ final String oldValue = this.getEventBuilderClassName();
+ this.configuration.set(EVENT_BUILDER_PROPERTY, eventBuilderClassName);
+ this.firePropertyChange(EVENT_BUILDER_PROPERTY, oldValue, this.getEventBuilderClassName());
+ }
+
+ /**
+ * Set to <code>true</code> to freeze the conditions system after initialization if there is also a valid detector
+ * name and run number setting.
+ *
+ * @param freezeConditions <code>true</code> to freeze the conditions
+ */
+ public void setFreezeConditions(final Boolean freezeConditions) {
+ Boolean oldValue = null;
+ if (this.hasPropertyKey(FREEZE_CONDITIONS_PROPERTY)) {
+ oldValue = this.getFreezeConditions();
}
- }
-
- public boolean hasPropertyKey(String key) {
- return configuration.hasKey(key);
- }
-
- public boolean hasValidProperty(String key) {
- return configuration.checkKey(key);
- }
-
- @Override
- public String[] getPropertyNames() {
- return CONFIG_PROPERTIES;
- }
-
- public void fireModelChanged() {
- firePropertiesChanged(configuration.getKeys());
- }
-
- public void merge(Configuration configuration) {
- this.configuration.merge(configuration);
- this.firePropertiesChanged(configuration.getKeys());
+ this.configuration.set(FREEZE_CONDITIONS_PROPERTY, freezeConditions);
+ this.firePropertyChange(FREEZE_CONDITIONS_PROPERTY, oldValue, freezeConditions);
+ }
+
+ /**
+ * Set the ET TCP/IP host name of the server.
+ *
+ * @param host the host name
+ */
+ public void setHost(final String host) {
+ final String oldValue = this.getHost();
+ this.configuration.set(HOST_PROPERTY, host);
+ this.firePropertyChange(HOST_PROPERTY, oldValue, this.getHost());
+ }
+
+ /**
+ * Set the log file name if using file logging.
+ *
+ * @param logFileName the log file name
+ */
+ public void setLogFileName(final String logFileName) {
+ final String oldValue = this.getLogFileName();
+ this.configuration.set(LOG_FILE_NAME_PROPERTY, logFileName);
+ this.firePropertyChange(LOG_FILE_NAME_PROPERTY, oldValue, this.getLogFileName());
+ }
+
+ /**
+ * Set the global log level.
+ *
+ * @param level the global log level
+ */
+ public void setLogLevel(final Level level) {
+ final Level oldValue = this.getLogLevel();
+ this.configuration.set(LOG_LEVEL_PROPERTY, level.getName());
+ this.firePropertyChange(LOG_LEVEL_PROPERTY, oldValue, this.getLogLevel());
+ }
+
+ /**
+ * Set log filter level for the log table.
+ *
+ * @param level the log filter level
+ */
+ public void setLogLevelFilter(final Level level) {
+ final Level oldValue = this.getLogLevelFilter();
+ this.configuration.set(LOG_LEVEL_FILTER_PROPERTY, level.getName());
+ this.firePropertyChange(LOG_LEVEL_FILTER_PROPERTY, oldValue, this.getLogLevelFilter());
+ }
+
+ /**
+ * Set to <code>true</code> to send global messages to a file instead of the console.
+ *
+ * @param logToFile <code>true</code> to log to file
+ */
+ public void setLogToFile(final Boolean logToFile) {
+ final Boolean oldValue = this.getLogToFile();
+ this.configuration.set(LOG_TO_FILE_PROPERTY, logToFile);
+ this.firePropertyChange(LOG_TO_FILE_PROPERTY, oldValue, this.getLogToFile());
+ }
+
+ /**
+ * Set the maximum number of events to process before the session will automatically end.
+ *
+ * @param maxEvents the maximum number of events
+ */
+ public void setMaxEvents(final Long maxEvents) {
+ final Long oldValue = this.getMaxEvents();
+ this.configuration.set(MAX_EVENTS_PROPERTY, maxEvents);
+ this.firePropertyChange(MAX_EVENTS_PROPERTY, oldValue, this.getMaxEvents());
+ }
+
+ /**
+ * Set the TCP/IP port number of the ET server for the client connection.
+ *
+ * @param port the ET port number
+ */
+ public void setPort(final Integer port) {
+ final Integer oldValue = this.getPort();
+ this.configuration.set(PORT_PROPERTY, port);
+ this.firePropertyChange(PORT_PROPERTY, oldValue, this.getPort());
+ }
+
+ /**
+ * Set a prescale value for the ET station which will decrease the event rate.
+ * <p>
+ * A prescale of 2 would mean every 2nd event is processed, etc.
+ *
+ * @param prescale the ET station prescale value
+ */
+ public void setPrescale(final Integer prescale) {
+ final Integer oldValue = this.getPrescale();
+ this.configuration.set(PRESCALE_PROPERTY, prescale);
+ this.firePropertyChange(PRESCALE_PROPERTY, oldValue, this.getPrescale());
+ }
+
+ /**
+ * Set the processing stage which determines which event processing stages are executed.
+ *
+ * @param processingStage the processing stage to execute
+ */
+ public void setProcessingStage(final String processingStage) {
+ final ProcessingStage oldValue = this.getProcessingStage();
+ this.configuration.set(PROCESSING_STAGE_PROPERTY, ProcessingStage.valueOf(processingStage));
+ this.firePropertyChange(PROCESSING_STAGE_PROPERTY, oldValue, this.getProcessingStage());
+ }
+
+ /**
+ * Set the ET queue size.
+ *
+ * @param queueSize the ET queue size
+ */
+ public void setQueueSize(final Integer queueSize) {
+ final Integer oldValue = this.getQueueSize();
+ this.configuration.set(QUEUE_SIZE_PROPERTY, queueSize);
+ this.firePropertyChange(QUEUE_SIZE_PROPERTY, oldValue, this.getQueueSize());
+ }
+
+ /**
+ * Set the recent files list, which is a list of "\n" delimited file paths.
+ *
+ * @param recentFiles the recent files list as a string
+ */
+ public void setRecentFiles(final String recentFiles) {
+ String oldValue = null;
+ if (this.configuration.checkKey(RECENT_FILES_PROPERTY)) {
+ oldValue = this.configuration.get(RECENT_FILES_PROPERTY);
+ }
+ this.configuration.set(RECENT_FILES_PROPERTY, recentFiles);
+ this.firePropertyChange(RECENT_FILES_PROPERTY, oldValue, this.configuration.get(RECENT_FILES_PROPERTY));
+ }
+
+ /**
+ * Set the recent files list.
+ * <p>
+ * This method is not part of the public API and is only used internally.
+ *
+ * @param recentFilesList the recent files list
+ */
+ private void setRecentFilesList(final List<String> recentFilesList) {
+ final StringBuffer sb = new StringBuffer();
+ for (final String recentFile : recentFilesList) {
+ sb.append(recentFile + "\n");
+ }
+ sb.setLength(sb.length() - 2);
+ this.configuration.set(RECENT_FILES_PROPERTY, sb.toString());
+ }
+
+ /**
+ * Set the ET station name.
+ *
+ * @param stationName the ET station name
+ */
+ public void setStationName(final String stationName) {
+ final String oldValue = this.getStationName();
+ this.configuration.set(STATION_NAME_PROPERTY, stationName);
+ this.firePropertyChange(STATION_NAME_PROPERTY, oldValue, this.getStationName());
+ }
+
+ /**
+ * Set the ET station position.
+ *
+ * @param stationPosition the ET station position
+ */
+ public void setStationPosition(final Integer stationPosition) {
+ final Integer oldValue = this.getStationPosition();
+ this.configuration.set(STATION_POSITION_PROPERTY, stationPosition);
+ this.firePropertyChange(STATION_POSITION_PROPERTY, oldValue, this.getStationPosition());
+ }
+
+ /**
+ * Set the steering file path.
+ *
+ * @param steeringFile the steering file path
+ */
+ public void setSteeringFile(final String steeringFile) {
+ final String oldValue = this.getSteeringFile();
+ this.configuration.set(STEERING_FILE_PROPERTY, steeringFile);
+ this.firePropertyChange(STEERING_FILE_PROPERTY, oldValue, this.getSteeringFile());
+ }
+
+ /**
+ * Set the steering file resource.
+ *
+ * @param steeringResource the steering file resource
+ */
+ public void setSteeringResource(final String steeringResource) {
+ final String oldValue = this.getSteeringResource();
+ this.configuration.set(STEERING_RESOURCE_PROPERTY, steeringResource);
+ this.firePropertyChange(STEERING_RESOURCE_PROPERTY, oldValue, steeringResource);
+ }
+
+ /**
+ * Set the steering type (file or resource).
+ *
+ * @param steeringType the steering type
+ * @see SteeringType
+ */
+ public void setSteeringType(final String steeringType) {
+ final SteeringType oldValue = this.getSteeringType();
+ this.configuration.set(STEERING_TYPE_PROPERTY, SteeringType.valueOf(steeringType));
+ this.firePropertyChange(STEERING_TYPE_PROPERTY, oldValue, this.getSteeringType());
+ }
+
+ /**
+ * Set a user run number which will be used to initialize the conditions system.
+ * <p>
+ * This should most likely be used with {@link #setFreezeConditions(Boolean)} or it is likely to be later overridden
+ * by run numbers from the data.
+ *
+ * @param userRunNumber the user run number
+ */
+ public void setUserRunNumber(final Integer userRunNumber) {
+ Integer oldValue = null;
+ if (this.hasPropertyKey(USER_RUN_NUMBER_PROPERTY)) {
+ oldValue = this.getUserRunNumber();
+ }
+ this.configuration.set(USER_RUN_NUMBER_PROPERTY, userRunNumber);
+ this.firePropertyChange(USER_RUN_NUMBER_PROPERTY, oldValue, this.getUserRunNumber());
+ }
+
+ /**
+ * Set verbose mode for the ET system.
+ *
+ * @param verbose the ET verbose flag
+ */
+ public void setVerbose(final Boolean verbose) {
+ final Boolean oldValue = this.getVerbose();
+ this.configuration.set(VERBOSE_PROPERTY, verbose);
+ this.firePropertyChange(VERBOSE_PROPERTY, oldValue, this.getVerbose());
+ }
+
+ /**
+ * Set the ET wait mode (timed, asynchronous or wait).
+ *
+ * @param waitMode the ET wait mode
+ */
+ public void setWaitMode(final String waitMode) {
+ final Mode oldValue = this.getWaitMode();
+ this.configuration.set(WAIT_MODE_PROPERTY, Mode.valueOf(waitMode));
+ this.firePropertyChange(WAIT_MODE_PROPERTY, oldValue, this.getWaitMode());
+ }
+
+ /**
+ * Set the ET wait time, which is ignored if wait mode is not timed.
+ *
+ * @param waitTime the ET wait time
+ */
+ public void setWaitTime(final Integer waitTime) {
+ final Integer oldValue = this.getWaitTime();
+ this.configuration.set(WAIT_TIME_PROPERTY, waitTime);
+ this.firePropertyChange(WAIT_TIME_PROPERTY, oldValue, this.getWaitTime());
}
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java Tue Apr 21 14:48:39 2015
@@ -3,23 +3,46 @@
import java.awt.Color;
/**
- * This is the status of the connection to the ET server from the monitoring client,
- * and it includes a color that should be displayed in the GUI for the associated
- * text.
+ * This is the status of the connection to the ET server from the monitoring client, and it includes a color that should
+ * be displayed in the GUI for the associated text.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
public enum ConnectionStatus {
+ /**
+ * This is the state when the session is connected to event processing.
+ */
+ CONNECTED(Color.GREEN),
+ /**
+ * This is the disconnected state when event processing is not occurring.
+ */
DISCONNECTED(Color.RED),
- DISCONNECTING(Color.YELLOW),
- CONNECTED(Color.GREEN);
-
- Color color;
-
- ConnectionStatus(Color color) {
+ /**
+ * This is the state when the session is being torn down.
+ */
+ DISCONNECTING(Color.YELLOW);
+
+ /**
+ * The color that should be displayed in the GUI component for this state.
+ */
+ private Color color;
+
+ /**
+ * Class constructor.
+ *
+ * @param color the color to display for this state
+ */
+ private ConnectionStatus(final Color color) {
this.color = color;
}
-
+
+ /**
+ * Get the color to display for this state.
+ *
+ * @return the color to display for this state
+ */
public Color getColor() {
- return color;
+ return this.color;
}
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java Tue Apr 21 14:48:39 2015
@@ -4,62 +4,117 @@
import java.beans.PropertyChangeListener;
/**
- * This model updates listeners when the connection status changes from disconnected
- * to connected or vice versa. It will also notify when the event processing is
- * paused.
- *
- * @author Jeremy McCormick <[log in to unmask]>
+ * This model updates listeners when the connection status changes from disconnected to connected or vice versa. It will
+ * also notify listeners when the event processing has been paused.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
public final class ConnectionStatusModel extends AbstractModel {
-
+
+ /**
+ * The connection status property.
+ */
public static final String CONNECTION_STATUS_PROPERTY = "ConnectionStatus";
+
+ /**
+ * The paused property.
+ */
public static final String PAUSED_PROPERTY = "Paused";
-
- static final String[] propertyNames = new String[] {
- CONNECTION_STATUS_PROPERTY,
- PAUSED_PROPERTY
- };
- ConnectionStatus connectionStatus = ConnectionStatus.DISCONNECTED;
- boolean paused = false;
-
+ /**
+ * The property names of this class.
+ */
+ private static final String[] PROPERTY_NAMES = new String[] {CONNECTION_STATUS_PROPERTY, PAUSED_PROPERTY};
+
+ /**
+ * The current connection status.
+ */
+ private ConnectionStatus connectionStatus = ConnectionStatus.DISCONNECTED;
+
+ /**
+ * Flag which is <code>true</code> when event processing is in the paused state.
+ */
+ private boolean paused = false;
+
+ /**
+ * Get the current connection status.
+ *
+ * @return the current connection status
+ */
+ public ConnectionStatus getConnectionStatus() {
+ return this.connectionStatus;
+ }
+
+ /**
+ * Return <code>true</code> if the event processing is currently paused.
+ *
+ * @return <code>true</code> if event processing is currently paused
+ */
+ public boolean getPaused() {
+ return this.paused;
+ }
+
+ /**
+ * Get the property names for this class.
+ *
+ * @return the property names for this class
+ */
+ @Override
public String[] getPropertyNames() {
- return propertyNames;
+ return PROPERTY_NAMES;
}
-
- public ConnectionStatus getConnectionStatus() {
- return connectionStatus;
+
+ /**
+ * Return <code>true</code> if the status is <code>CONNECTED</code>.
+ *
+ * @return <code>true</code> if status is <code>CONNECTED</code>
+ */
+ public boolean isConnected() {
+ return this.connectionStatus == ConnectionStatus.CONNECTED;
}
-
- public void setConnectionStatus(ConnectionStatus connectionStatus) {
- ConnectionStatus oldValue = connectionStatus;
+
+ /**
+ * Return <code>true</code> if the status is <code>DISCONNECTED</code>.
+ *
+ * @return <code>true</code> if the status is <code>DISCONNECTED</code>
+ */
+ public boolean isDisconnected() {
+ return this.connectionStatus == ConnectionStatus.DISCONNECTED;
+ }
+
+ /**
+ * Return <code>true</code> if the status is <code>DISCONNECTING</code>.
+ *
+ * @return <code>true</code> if the status is <code>DISCONNECTING</code>
+ */
+ public boolean isDisconnecting() {
+ return this.connectionStatus == ConnectionStatus.DISCONNECTING;
+ }
+
+ /**
+ * Set the connection status.
+ *
+ * @param connectionStatus the new connection status
+ */
+ public void setConnectionStatus(final ConnectionStatus connectionStatus) {
+ final ConnectionStatus oldValue = connectionStatus;
this.connectionStatus = connectionStatus;
- for (PropertyChangeListener listener : propertyChangeSupport.getPropertyChangeListeners()) {
- listener.propertyChange(new PropertyChangeEvent(this, CONNECTION_STATUS_PROPERTY, oldValue, this.connectionStatus));
+ for (final PropertyChangeListener listener : this.getPropertyChangeSupport().getPropertyChangeListeners()) {
+ listener.propertyChange(new PropertyChangeEvent(this, CONNECTION_STATUS_PROPERTY, oldValue,
+ this.connectionStatus));
}
- }
-
- public boolean getPaused() {
- return paused;
}
-
- public void setPaused(boolean paused) {
- boolean oldValue = this.paused;
+
+ /**
+ * Set to <code>true</code> if status is paused.
+ *
+ * @param paused <code>true</code> if status is paused
+ */
+ public void setPaused(final boolean paused) {
+ final boolean oldValue = this.paused;
this.paused = paused;
- for (PropertyChangeListener listener : propertyChangeSupport.getPropertyChangeListeners()) {
+ for (final PropertyChangeListener listener : this.getPropertyChangeSupport().getPropertyChangeListeners()) {
listener.propertyChange(new PropertyChangeEvent(this, PAUSED_PROPERTY, oldValue, this.paused));
}
}
-
- public boolean isConnected() {
- return this.connectionStatus == ConnectionStatus.CONNECTED;
- }
-
- public boolean isDisconnected() {
- return this.connectionStatus == ConnectionStatus.DISCONNECTED;
- }
-
- public boolean isDisconnecting() {
- return this.connectionStatus == ConnectionStatus.DISCONNECTING;
- }
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/HasConfigurationModel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/HasConfigurationModel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/HasConfigurationModel.java Tue Apr 21 14:48:39 2015
@@ -2,18 +2,22 @@
/**
* Mix-in interface for classes that have an associated {@link ConfigurationModel}.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
public interface HasConfigurationModel {
/**
- * Set the ConfigurationModel of the object.
- * @param configurationModel The ConfigurationModel.
+ * Get the current {@link ConfigurationModel} of the object.
+ *
+ * @return the associated {@link ConfigurationModel}
+ */
+ ConfigurationModel getConfigurationModel();
+
+ /**
+ * Set the {@link ConfigurationModel} of the object.
+ *
+ * @param configurationModel the new {@link ConfigurationModel}
*/
void setConfigurationModel(ConfigurationModel configurationModel);
-
- /**
- * Get the current ConfigurationModel of the object.
- * @return The ConfigurationModel.
- */
- ConfigurationModel getConfigurationModel();
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/RunModel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/RunModel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/RunModel.java Tue Apr 21 14:48:39 2015
@@ -4,117 +4,258 @@
/**
* Backing model for run information that shows in the {@link org.hps.monitoring.application.EventDashboard}.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
public final class RunModel extends AbstractModel {
- public final static String RUN_NUMBER_PROPERTY = "RunNumber";
- public final static String START_DATE_PROPERTY = "StartDate";
- public final static String END_DATE_PROPERTY = "EndDate";
- public final static String RUN_LENGTH_PROPERTY = "RunLength"; // set at end, in seconds
- public final static String TOTAL_EVENTS_PROPERTY = "TotalEvents"; // only set at end
- public final static String EVENTS_RECEIVED_PROPERTY = "EventsReceived"; // events received so far
- public final static String ELAPSED_TIME_PROPERTY = "ElapsedTime"; // updated on the fly, in seconds
- public final static String DATA_RECEIVED_PROPERTY = "DataReceived"; // updated on the fly, in bytes
- public final static String EVENT_NUMBER_PROPERTY = "EventNumber"; // current event number
- public final static String DATA_RATE_PROPERTY = "DataRate"; // data rate in megabytes per second
- public final static String EVENT_RATE_PROPERTY = "EventRate"; // event rate per second
-
- static final String[] RUN_PROPERTIES = AbstractModel.getPropertyNames(RunModel.class);
-
- Integer runNumber;
- Date startDate;
- Date endDate;
- Integer runLength;
- Integer totalEvents;
- Integer eventsReceived;
- Integer elapsedTime;
- Double dataReceived;
- Integer eventNumber;
- Double dataRate;
- Double eventRate;
-
+ /**
+ * The data rate in megabytes per second.
+ */
+ public static final String DATA_RATE_PROPERTY = "DataRate";
+
+ /**
+ * The amount of data received in bytes since the last timer tick.
+ */
+ public static final String DATA_RECEIVED_PROPERTY = "DataReceived";
+
+ /**
+ * The total elapsed time in the session.
+ */
+ public static final String ELAPSED_TIME_PROPERTY = "ElapsedTime";
+
+ /**
+ * The end date of the run which comes from the EVIO END record.
+ */
+ public static final String END_DATE_PROPERTY = "EndDate";
+
+ /**
+ * The event number currently being processed which usually comes from the EVIO or LCIO records.
+ */
+ public static final String EVENT_NUMBER_PROPERTY = "EventNumber";
+
+ /**
+ * The event rate in Hertz.
+ */
+ public static final String EVENT_RATE_PROPERTY = "EventRate";
+
+ /**
+ * The total number of events received in the session.
+ */
+ public static final String EVENTS_RECEIVED_PROPERTY = "EventsReceived";
+
+ /**
+ * The total length of the run which is set from the EVIO END record.
+ */
+ public static final String RUN_LENGTH_PROPERTY = "RunLength";
+
+ /**
+ * The run number which comes from the EVIO control data.
+ */
+ public static final String RUN_NUMBER_PROPERTY = "RunNumber";
+
+ /**
+ * The properties of this model.
+ */
+ private static final String[] RUN_PROPERTIES = AbstractModel.getPropertyNames(RunModel.class);
+
+ /**
+ * The start date of the run which comes from the EVIO PRESTART event.
+ */
+ public static final String START_DATE_PROPERTY = "StartDate";
+
+ /**
+ * The total events in the run which comes from the EVIO END event.
+ */
+ public static final String TOTAL_EVENTS_PROPERTY = "TotalEvents";
+
+ /**
+ * The data rate in MB/s.
+ */
+ private Double dataRate;
+
+ /**
+ * The data received in bytes.
+ */
+ private Double dataReceived;
+
+ /**
+ * The elapsed time in seconds.
+ */
+ private Integer elapsedTime;
+
+ /**
+ * The end date of the run.
+ */
+ private Date endDate;
+
+ /**
+ * The current event number.
+ */
+ private Integer eventNumber;
+
+ /**
+ * The event rate in Hertz.
+ */
+ private Double eventRate;
+
+ /**
+ * The number of events received.
+ */
+ private Integer eventsReceived;
+
+ /**
+ * The length of the run.
+ */
+ private Integer runLength;
+
+ /**
+ * The run number.
+ */
+ private Integer runNumber;
+
+ /**
+ * The run start date.
+ */
+ private Date startDate;
+
+ /**
+ * The total events received in the run.
+ */
+ private Integer totalEvents;
+
+ /**
+ * Add data received in bytes.
+ *
+ * @param addDataReceived the amount of data received in bytes
+ */
+ public void addDataReceived(final double addDataReceived) {
+ this.setDataReceived(this.dataReceived + addDataReceived);
+ }
+
+ /**
+ * Compute the run length from the start and end date and set its value in the GUI.
+ */
+ public void computeRunLength() {
+ if (this.startDate != null && this.endDate != null) {
+ final long elapsedMillis = this.endDate.getTime() - this.startDate.getTime();
+ final int elapsedSeconds = (int) (elapsedMillis / 1000.);
+ this.setRunLength(elapsedSeconds);
+ }
+ }
+
+ /**
+ * Get the data rate in MB/s.
+ *
+ * @return the data rate in MB/s
+ */
+ public double getDataRate() {
+ return this.dataRate;
+ }
+
+ /**
+ * Get the data received in bytes.
+ *
+ * @return the data received in bytes
+ */
+ public double getDataReceived() {
+ return this.dataReceived;
+ }
+
+ /**
+ * Get the elapsed time in seconds.
+ *
+ * @return the elapsed time in seconds
+ */
+ public int getElapsedTime() {
+ return this.elapsedTime;
+ }
+
+ /**
+ * Get the run end date.
+ *
+ * @return the run end date
+ */
+ public Date getEndDate() {
+ return this.endDate;
+ }
+
+ /**
+ * Get the current event number.
+ *
+ * @return the current event number
+ */
+ public int getEventNumber() {
+ return this.eventNumber;
+ }
+
+ /**
+ * Get the event rate in Hertz.
+ *
+ * @return the event rate in Hertz
+ */
+ public double getEventRate() {
+ return this.eventRate;
+ }
+
+ /**
+ * Get the number of events received in the session.
+ *
+ * @return the number of events received
+ */
+ public int getEventsReceived() {
+ return this.eventsReceived;
+ }
+
+ /**
+ * Get the property names for this model.
+ *
+ * @return the property names for this model
+ */
+ @Override
public String[] getPropertyNames() {
return RUN_PROPERTIES;
}
- public void setRunNumber(int runNumber) {
- Integer oldValue = this.runNumber;
- this.runNumber = runNumber;
- this.firePropertyChange(RUN_NUMBER_PROPERTY, oldValue, this.runNumber);
- }
-
- public void setStartDate(Date startDate) {
- Date oldValue = this.startDate;
- this.startDate = startDate;
- this.firePropertyChange(START_DATE_PROPERTY, oldValue, this.startDate);
- }
-
- public void setEndDate(Date endDate) {
- Date oldValue = this.endDate;
- this.endDate = endDate;
- this.firePropertyChange(END_DATE_PROPERTY, oldValue, this.endDate);
- }
-
- public void setRunLength(int runLength) {
- Integer oldValue = this.runLength;
- this.runLength = runLength;
- this.firePropertyChange(RUN_LENGTH_PROPERTY, oldValue, this.runLength);
- }
-
- public void computeRunLength() {
- if (startDate != null && endDate != null) {
- long elapsedMillis = endDate.getTime() - startDate.getTime();
- int elapsedSeconds = (int) ((double) elapsedMillis / 1000.);
- this.setRunLength(elapsedSeconds);
- }
- }
-
- public void setTotalEvents(int totalEvents) {
- Integer oldValue = this.totalEvents;
- this.totalEvents = totalEvents;
- this.firePropertyChange(TOTAL_EVENTS_PROPERTY, oldValue, this.totalEvents);
- }
-
- public void setEventsReceived(int eventsReceived) {
- Integer oldValue = this.eventsReceived;
- this.eventsReceived = eventsReceived;
- this.firePropertyChange(EVENTS_RECEIVED_PROPERTY, oldValue, this.eventsReceived);
- }
-
- public void setElapsedTime(int elapsedTime) {
- Integer oldValue = this.elapsedTime;
- this.elapsedTime = elapsedTime;
- this.firePropertyChange(ELAPSED_TIME_PROPERTY, oldValue, this.elapsedTime);
- }
-
- public void setDataReceived(double dataReceived) {
- Double oldValue = this.dataReceived;
- this.dataReceived = dataReceived;
- this.firePropertyChange(DATA_RECEIVED_PROPERTY, oldValue, this.dataReceived);
- }
-
- public void addDataReceived(double addDataReceived) {
- this.setDataReceived(dataReceived + addDataReceived);
- }
-
- public void setEventNumber(int eventNumber) {
- Integer oldValue = this.eventNumber;
- this.eventNumber = eventNumber;
- this.firePropertyChange(EVENT_NUMBER_PROPERTY, oldValue, this.eventNumber);
- }
-
- public void setDataRate(double dataRate) {
- Double oldValue = this.dataRate;
- this.dataRate = dataRate;
- this.firePropertyChange(DATA_RATE_PROPERTY, oldValue, this.dataRate);
- }
-
- public void setEventRate(double eventRate) {
- Double oldValue = this.eventRate;
- this.eventRate = eventRate;
- this.firePropertyChange(EVENT_RATE_PROPERTY, oldValue, this.eventRate);
- }
-
+ /**
+ * Get the run length in seconds.
+ *
+ * @return the run length in seconds
+ */
+ public int getRunLength() {
+ return this.runLength;
+ }
+
+ /**
+ * Get the run number.
+ *
+ * @return the run number
+ */
+ public int getRunNumber() {
+ return this.runNumber;
+ }
+
+ /**
+ * Get the start date.
+ *
+ * @return the start date
+ */
+ public Date getStartDate() {
+ return this.startDate;
+ }
+
+ /**
+ * Get the total events in the run.
+ *
+ * @return the total events in the run
+ */
+ public int getTotalEvents() {
+ return this.totalEvents;
+ }
+
+ /**
+ * Reset the model for new run.
+ */
public void reset() {
setDataReceived(0);
setElapsedTime(0);
@@ -125,4 +266,125 @@
setStartDate(null);
setTotalEvents(0);
}
-}
+
+ /**
+ * Set the data rate in MB/s.
+ *
+ * @param dataRate the data rate in MB/s
+ */
+ public void setDataRate(final double dataRate) {
+ final Double oldValue = this.dataRate;
+ this.dataRate = dataRate;
+ this.firePropertyChange(DATA_RATE_PROPERTY, oldValue, this.dataRate);
+ }
+
+ /**
+ * Set the data received in bytes.
+ *
+ * @param dataReceived the data received in bytes
+ */
+ public void setDataReceived(final double dataReceived) {
+ final Double oldValue = this.dataReceived;
+ this.dataReceived = dataReceived;
+ this.firePropertyChange(DATA_RECEIVED_PROPERTY, oldValue, this.dataReceived);
+ }
+
+ /**
+ * Set the elapsed time in seconds.
+ *
+ * @param elapsedTime the elapsed time in seconds
+ */
+ public void setElapsedTime(final int elapsedTime) {
+ final Integer oldValue = this.elapsedTime;
+ this.elapsedTime = elapsedTime;
+ this.firePropertyChange(ELAPSED_TIME_PROPERTY, oldValue, this.elapsedTime);
+ }
+
+ /**
+ * Set the run end date.
+ *
+ * @param endDate the run end date
+ */
+ public void setEndDate(final Date endDate) {
+ final Date oldValue = this.endDate;
+ this.endDate = endDate;
+ this.firePropertyChange(END_DATE_PROPERTY, oldValue, this.endDate);
+ }
+
+ /**
+ * Set the current event number.
+ *
+ * @param eventNumber the current event number
+ */
+ public void setEventNumber(final int eventNumber) {
+ final Integer oldValue = this.eventNumber;
+ this.eventNumber = eventNumber;
+ this.firePropertyChange(EVENT_NUMBER_PROPERTY, oldValue, this.eventNumber);
+ }
+
+ /**
+ * Set the event rate in Hertz.
+ *
+ * @param eventRate the event rate in Hertz
+ */
+ public void setEventRate(final double eventRate) {
+ final Double oldValue = this.eventRate;
+ this.eventRate = eventRate;
+ this.firePropertyChange(EVENT_RATE_PROPERTY, oldValue, this.eventRate);
+ }
+
+ /**
+ * Set the number of events received.
+ *
+ * @param eventsReceived the number of events received
+ */
+ public void setEventsReceived(final int eventsReceived) {
+ final Integer oldValue = this.eventsReceived;
+ this.eventsReceived = eventsReceived;
+ this.firePropertyChange(EVENTS_RECEIVED_PROPERTY, oldValue, this.eventsReceived);
+ }
+
+ /**
+ * Set the length of the run in seconds.
+ *
+ * @param runLength the length of the run in seconds
+ */
+ public void setRunLength(final int runLength) {
+ final Integer oldValue = this.runLength;
+ this.runLength = runLength;
+ this.firePropertyChange(RUN_LENGTH_PROPERTY, oldValue, this.runLength);
+ }
+
+ /**
+ * Set the run number.
+ *
+ * @param runNumber the run number
+ */
+ public void setRunNumber(final int runNumber) {
+ final Integer oldValue = this.runNumber;
+ this.runNumber = runNumber;
+ this.firePropertyChange(RUN_NUMBER_PROPERTY, oldValue, this.runNumber);
+ }
+
+ /**
+ * Set the start date.
+ *
+ * @param startDate the start date
+ */
+ public void setStartDate(final Date startDate) {
+ final Date oldValue = this.startDate;
+ this.startDate = startDate;
+ this.firePropertyChange(START_DATE_PROPERTY, oldValue, this.startDate);
+ }
+
+ /**
+ * Set the total number of events in the run.
+ *
+ * @param totalEvents the total number of events in the run
+ */
+ public void setTotalEvents(final int totalEvents) {
+ final Integer oldValue = this.totalEvents;
+ this.totalEvents = totalEvents;
+ this.firePropertyChange(TOTAL_EVENTS_PROPERTY, oldValue, this.totalEvents);
+ }
+}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/SteeringType.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/SteeringType.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/SteeringType.java Tue Apr 21 14:48:39 2015
@@ -2,8 +2,16 @@
/**
* The type of steering to use for event processing.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
public enum SteeringType {
- RESOURCE,
- FILE;
+ /**
+ * Steering from local file on disk.
+ */
+ FILE,
+ /**
+ * Steering from resource in jar file.
+ */
+ RESOURCE;
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/SystemStatusTableModel.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/SystemStatusTableModel.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/model/SystemStatusTableModel.java Tue Apr 21 14:48:39 2015
@@ -2,7 +2,6 @@
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -16,74 +15,164 @@
/**
* A <code>JTableModel</code> that has a list of {@link org.hps.monitoring.subsys.SystemStatus} objects.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
+@SuppressWarnings("serial")
public final class SystemStatusTableModel extends AbstractTableModel implements SystemStatusListener {
- public static final int RESET_COL = 0;
- public static final int ACTIVE_COL = 1;
- public static final int STATUS_COL = 2;
- public static final int SYSTEM_COL = 3;
- public static final int DESCRIPTION_COL = 4;
- public static final int MESSAGE_COL = 5;
- public static final int LAST_CHANGED_COL = 6;
- public static final int CLEARABLE_COL = 7;
-
- static final String[] columnNames = { "Reset", "Active", "Status", "System", "Description", "Message", "Last Changed", "Clearable" };
-
- List<SystemStatus> statuses = new ArrayList<SystemStatus>();
- final SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM-dd-yyyy HH:mm:ss.SSS");
-
- public void addSystemStatus(SystemStatus status) {
- statuses.add(status);
+ /**
+ * Active field column index.
+ */
+ public static final int ACTIVE_COLUMN_INDEX = 1;
+
+ /**
+ * Clearable field column index.
+ */
+ public static final int CLEARABLE_COLUMN_INDEX = 7;
+
+ /**
+ * The names of the columns.
+ */
+ private static final String[] COLUMN_NAMES = {"Reset", "Active", "Status", "System", "Description", "Message",
+ "Last Changed", "Clearable"};
+
+ /**
+ * Description column index.
+ */
+ public static final int DESCRIPTION_COLUMN_INDEX = 4;
+
+ /**
+ * Last changed field column index.
+ */
+ public static final int LAST_CHANGED_COLUMN_INDEX = 6;
+
+ /**
+ * Message field column index.
+ */
+ public static final int MESSAGE_COLUMN_INDEX = 5;
+
+ /**
+ * Reset field column index.
+ */
+ public static final int RESET_COLUMN_INDEX = 0;
+
+ /**
+ * Status field column index.
+ */
+ public static final int STATUS_COLUMN_INDEX = 2;
+
+ /**
+ * System field column index.
+ */
+ public static final int SYSTEM_COLUMN_INDEX = 3;
+
+ /**
+ * The list of system status objects that back the model.
+ */
+ private final List<SystemStatus> statuses = new ArrayList<SystemStatus>();
+
+ /**
+ * Add a system status to the model.
+ *
+ * @param status the system status to add to the model
+ */
+ public void addSystemStatus(final SystemStatus status) {
+ this.statuses.add(status);
status.addListener(this);
fireTableDataChanged();
}
+ /**
+ * Clear all the data in the model.
+ */
+ public void clear() {
+ this.statuses.clear();
+ fireTableDataChanged();
+ }
+
+ /**
+ * Get the class of the column.
+ *
+ * @param columnIndex the index of the column
+ */
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ @Override
+ public Class getColumnClass(final int columnIndex) {
+ switch (columnIndex) {
+ case ACTIVE_COLUMN_INDEX:
+ return Boolean.class;
+ case LAST_CHANGED_COLUMN_INDEX:
+ return Date.class;
+ default:
+ return String.class;
+ }
+ }
+
+ /**
+ * Get the column count.
+ *
+ * @return the column count
+ */
+ @Override
+ public int getColumnCount() {
+ return COLUMN_NAMES.length;
+ }
+
+ /**
+ * Get the column name.
+ *
+ * @param columnIndex the column index
+ */
+ @Override
+ public String getColumnName(final int columnIndex) {
+ return COLUMN_NAMES[columnIndex];
+ }
+
+ /**
+ * Get the row count.
+ *
+ * @return the row count
+ */
@Override
public int getRowCount() {
- return statuses.size();
- }
-
- @Override
- public int getColumnCount() {
- return columnNames.length;
- }
-
- @Override
- public String getColumnName(int col) {
- return columnNames[col];
- }
-
+ return this.statuses.size();
+ }
+
+ /**
+ * Get a table cell value.
+ *
+ * @param rowIndex the row index
+ * @param columnIndex the column index
+ */
@Override
public Object getValueAt(final int rowIndex, final int columnIndex) {
- SystemStatus status = statuses.get(rowIndex);
+ final SystemStatus status = this.statuses.get(rowIndex);
switch (columnIndex) {
- case ACTIVE_COL:
+ case ACTIVE_COLUMN_INDEX:
return status.isActive();
- case STATUS_COL:
+ case STATUS_COLUMN_INDEX:
return status.getStatusCode().name();
- case SYSTEM_COL:
+ case SYSTEM_COLUMN_INDEX:
return status.getSubsystem().name();
- case DESCRIPTION_COL:
+ case DESCRIPTION_COLUMN_INDEX:
return status.getDescription();
- case MESSAGE_COL:
+ case MESSAGE_COLUMN_INDEX:
return status.getMessage();
- case LAST_CHANGED_COL:
+ case LAST_CHANGED_COLUMN_INDEX:
return new Date(status.getLastChangedMillis());
- case RESET_COL:
- // If the status is clearable, then it has a button that can be used to
- // manually set the state to CLEARED. If the status is not clearable,
+ case RESET_COLUMN_INDEX:
+ // If the status is clear-able, then the cell has a button which can be used to
+ // manually set the state to CLEARED. If the status cannot be cleared,
// then nothing is rendered in this cell.
if (status.isClearable()) {
final JButton button = new JButton();
button.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- SystemStatus status = statuses.get(rowIndex);
- // Only clearable statuses can have this state set. Check for this
- // just to be safe, even though no button is available for non-clearable
- // statuses.
+ @Override
+ public void actionPerformed(final ActionEvent e) {
+ final SystemStatus status = SystemStatusTableModel.this.statuses.get(rowIndex);
if (status.isClearable()) {
- StatusCode oldStatusCode = status.getStatusCode();
+ final StatusCode oldStatusCode = status.getStatusCode();
status.setStatus(StatusCode.CLEARED, "Cleared from " + oldStatusCode.name() + " state.");
}
}
@@ -92,48 +181,45 @@
} else {
return null;
}
- case CLEARABLE_COL:
+ case CLEARABLE_COLUMN_INDEX:
return status.isClearable();
default:
return null;
}
}
- @Override
- public Class getColumnClass(int column) {
- switch (column) {
- case ACTIVE_COL:
- return Boolean.class;
- case LAST_CHANGED_COL:
- return Date.class;
- default:
- return String.class;
+ /**
+ * Return <code>true</code> if cell is editable.
+ *
+ * @return <code>true</code> if cell is editable
+ */
+ @Override
+ public boolean isCellEditable(final int rowIndex, final int columnIndex) {
+ return columnIndex == ACTIVE_COLUMN_INDEX;
+ }
+
+ /**
+ * Set the table cell value.
+ *
+ * @param value the new value
+ * @param rowIndex the row index
+ * @param columnIndex the column index
+ */
+ @Override
+ public void setValueAt(final Object value, final int rowIndex, final int columnIndex) {
+ if (columnIndex == ACTIVE_COLUMN_INDEX) {
+ this.statuses.get(rowIndex).setActive((Boolean) value);
}
}
- @Override
- public boolean isCellEditable(int row, int col) {
- if (col == ACTIVE_COL)
- return true;
- else
- return false;
- }
-
- @Override
- public void statusChanged(SystemStatus status) {
- int rowNumber = statuses.indexOf(status);
+ /**
+ * Notify of system status changed.
+ *
+ * @param status the system status that changed
+ */
+ @Override
+ public void statusChanged(final SystemStatus status) {
+ final int rowNumber = this.statuses.indexOf(status);
fireTableRowsUpdated(rowNumber, rowNumber);
}
-
- public void clear() {
- statuses.clear();
- fireTableDataChanged();
- }
-
- @Override
- public void setValueAt(Object value, int row, int col) {
- if (col == ACTIVE_COL) {
- statuses.get(row).setActive((Boolean) value);
- }
- }
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/package-info.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/package-info.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/package-info.java Tue Apr 21 14:48:39 2015
@@ -1,22 +1,20 @@
/**
- * The Monitoring Application is a flexible framework for monitoring the
- * event processing chain of the HPS experiment. It implements the conversion
- * of ET byte buffers to EVIO and then the building of LCIO events from the
- * raw EVIO data.
- * <p>
- * It provides three primary GUI components:
+ * The Monitoring Application is a flexible framework for monitoring the event processing chain of the HPS experiment in
+ * an online environment. It implements the conversion of ET byte buffers to EVIO and then the building of LCIO events
+ * from the raw EVIO data.
+ * <p>
+ * It provides three primary GUI components:
* <ul>
* <li>run dashboard showing basic information about data received</li>
- * <li>system status monitor that can monitor the status of specific subsystems</li>
+ * <li>tab panel showing various information panels</li>
* <li>plotting window that displays any plots generated through the AIDA API</li>
* </ul>
* <p>
- * The FreeHep framework is used extensively for the record processing. Every part
- * of the event processing chain uses the
- * <a href="http://java.freehep.org/freehep-record/">freehep-record</a>
- * module to manage the flow of records and activate any processors that are listening
- * on the record loops.
+ * The FreeHep framework is used extensively for the record processing. Every part of the event processing chain uses
+ * the <a href="http://java.freehep.org/freehep-record/">freehep-record</a> module to manage the flow of records and
+ * activate any processors that are listening on the record loops.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ */
+package org.hps.monitoring.application;
- * @author Jeremy McCormick <[log in to unmask]>
- */
-package org.hps.monitoring.application;
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/AIDAServer.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/AIDAServer.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/AIDAServer.java Tue Apr 21 14:48:39 2015
@@ -11,69 +11,90 @@
/**
* AIDA RMI server wrapper.
- * @author Jeremy McCormick <[log in to unmask]>
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
-public class AIDAServer {
-
- RmiServerImpl server;
- String name;
- boolean connected = false;
-
+public final class AIDAServer {
+
/**
- * Class constructor.
- * @param name The name of the AIDA server.
+ * Connected flag.
*/
- public AIDAServer(String name) {
+ private boolean connected = false;
+
+ /**
+ * The name of the server.
+ */
+ private String name;
+
+ /**
+ * The RMI server object.
+ */
+ private RmiServerImpl server;
+
+ /**
+ * Class constructor.
+ *
+ * @param name the name of the AIDA server
+ */
+ public AIDAServer(final String name) {
this.name = name;
}
-
+
+ /**
+ * Return <code>true</code> if connected.
+ *
+ * @return <code>true</code> if connected to server
+ */
+ public boolean connected() {
+ return this.connected;
+ }
+
+ /**
+ * Close the server down by disconnecting it.
+ */
+ public void disconnect() {
+ this.server.disconnect();
+ this.connected = false;
+ }
+
+ /**
+ * Get the server name as a string.
+ *
+ * @return the server name
+ */
+ public String getName() {
+ try {
+ return InetAddress.getLocalHost().getCanonicalHostName() + this.server.getBindName() + ":"
+ + RmiRemoteUtils.port;
+ } catch (final Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
/**
* Set the name that will be used for the path part of the URL.
+ *
* @param name The server's name.
*/
- public void setName(String name) {
+ public void setName(final String name) {
this.name = name;
}
/**
* Start the remote AIDA server.
- * @return True if server started successfully; false if an error occurred during initialization.
+ *
+ * @return <code>true</code> if server started successfully; false if an error occurred during initialization.
*/
public boolean start() {
- RemoteServer treeServer = new RemoteServer((IDevTree) AIDA.defaultInstance().tree());
+ final RemoteServer treeServer = new RemoteServer((IDevTree) AIDA.defaultInstance().tree());
try {
- server = new RmiServerImpl(treeServer, "/" + name);
- connected = true;
+ this.server = new RmiServerImpl(treeServer, "/" + this.name);
+ this.connected = true;
+ } catch (final Exception e) {
+ e.printStackTrace();
+ this.connected = false;
}
- catch (Exception e) {
- e.printStackTrace();
- connected = false;
- }
- return connected;
- }
-
- /**
- * Close the server down by disconnecting it.
- */
- public void disconnect() {
- server.disconnect();
- connected = false;
- }
-
- /**
- * True if connected.
- * @return True if connected to server.
- */
- public boolean connected() {
- return connected;
- }
-
- public String getName() {
- try {
- return InetAddress.getLocalHost().getCanonicalHostName() + server.getBindName() + ":" + RmiRemoteUtils.port;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
+ return this.connected;
}
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/DialogUtil.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/DialogUtil.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/DialogUtil.java Tue Apr 21 14:48:39 2015
@@ -7,27 +7,102 @@
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
+import javax.swing.WindowConstants;
+/**
+ * This is a set of utility methods for creating Swing dialog windows.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ */
public final class DialogUtil {
/**
- *
- * @param parentComponent
- * @param title
- * @param message
- * @return
+ * Show a confirmation dialog.
+ *
+ * @param parent the parent component
+ * @param message the message
+ * @param title the title of the dialog
+ * @return the result from the user's dialog selection
*/
- public 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);
+ public static int showConfirmationDialog(final Component parent, final String title, final String message) {
+ final Object[] options = { "Yes", "No", "Cancel" };
+ final int result = JOptionPane.showOptionDialog(parent, message, title, JOptionPane.YES_NO_CANCEL_OPTION,
+ JOptionPane.QUESTION_MESSAGE, null, options, options[2]);
+ return result;
+ }
+
+ /**
+ * Show an error dialog.
+ *
+ * @param component the parent component
+ * @param error the error message
+ * @param title the title of the dialog
+ */
+ public static void showErrorDialog(final Component component, final String title, final String message) {
+ final Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ JOptionPane.showMessageDialog(component, message, title, JOptionPane.ERROR_MESSAGE);
+ }
+ };
+ SwingUtilities.invokeLater(runnable);
+ }
+
+ /**
+ * Show an error dialog with an associated thrown object.
+ *
+ * @param component the parent component
+ * @param error the <code>Throwable</code> error
+ * @param title the title of the dialog
+ */
+ public static void showErrorDialog(final Component component, final Throwable error, final String title) {
+ final Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ JOptionPane.showMessageDialog(component, error.getMessage(), title, JOptionPane.ERROR_MESSAGE);
+ }
+ };
+ SwingUtilities.invokeLater(runnable);
+ }
+
+ /**
+ * Show an information dialog.
+ *
+ * @param component the parent component
+ * @param title the title of the dialog
+ * @param message the message
+ */
+ public static void showInfoDialog(final Component component, final String title, final String message) {
+ final Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ JOptionPane.showMessageDialog(component, message, title, JOptionPane.INFORMATION_MESSAGE);
+ }
+ };
+ SwingUtilities.invokeLater(runnable);
+ }
+
+ /**
+ * Show a status dialog which will block GUI interaction.
+ *
+ * @param parentComponent the parent component
+ * @param title the title of the dialog
+ * @param message the message
+ * @return the dialog window component
+ */
+ public static JDialog showStatusDialog(final Component parentComponent, final String title, final 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.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
dialog.pack();
dialog.addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
+ @Override
+ public void windowClosing(final WindowEvent e) {
dialog.setVisible(false);
dialog.dispose();
parentComponent.setEnabled(true);
@@ -40,68 +115,9 @@
}
/**
- *
- * @param component
- * @param error
- * @param title
+ * Do not allow class instantiation.
*/
- public 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);
- }
-
- /**
- *
- * @param component
- * @param error
- * @param title
- */
- public static void showErrorDialog(final Component component, final String title, final String message) {
- final Runnable runnable = new Runnable() {
- public void run() {
- JOptionPane.showMessageDialog(component, message, title, JOptionPane.ERROR_MESSAGE);
- }
- };
- SwingUtilities.invokeLater(runnable);
- }
-
- /**
- *
- * @param component
- * @param title
- * @param message
- */
- public 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);
- }
-
- /**
- *
- * @param parent
- * @param message
- * @param title
- * @return
- */
- public static int showConfirmationDialog(final Component parent, final String title, final String message) {
- Object[] options = { "Yes", "No", "Cancel" };
- int result = JOptionPane.showOptionDialog(
- parent,
- message,
- title,
- JOptionPane.YES_NO_CANCEL_OPTION,
- JOptionPane.QUESTION_MESSAGE,
- null,
- options,
- options[2]);
- return result;
+ private DialogUtil() {
+ throw new UnsupportedOperationException("Do not instantiate this class.");
}
}
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 Apr 21 14:48:39 2015
@@ -8,10 +8,9 @@
import javax.swing.SwingUtilities;
/**
+ * An error handling class which is able to do any of the following, depending on how the users wants to handle the
+ * error.
* <p>
- * An error handling class which is able to do any of the following, depending on how the users
- * wants to handle the error.
- * </p>
* <ul>
* <li>Print a message</li>
* <li>Print the stack trace</li>
@@ -20,97 +19,130 @@
* <li>Raise an exception</li>
* <li>Exit the application</li>
* </ul>
- * </p> It mostly uses the "builder" pattern so that the various handling methods can be easily
- * chained, where appropriate. Some methods are not available for chaining when it doesn't make
- * sense. </p>
+ * <p>
+ * It mostly uses the "builder" pattern so that the various handling methods can be easily chained, where appropriate.
+ * Some methods are not available for chaining when it doesn't make sense.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
public final class ErrorHandler {
- Logger logger;
- Component component;
- Throwable error;
- String message;
+ /**
+ * The component used for showing dialog windows.
+ */
+ private final Component component;
/**
- * Constructor.
+ * The thrown error.
+ */
+ private Throwable error;
+
+ /**
+ * A logger for reporting error messages.
+ */
+ private final Logger logger;
+
+ /**
+ * The error message.
+ */
+ private String message;
+
+ /**
+ * Class constructor.
+ *
* @param component The GUI component to which this object is assigned.
* @param logger The logger to which messages will be written.
*/
- public ErrorHandler(Component component, Logger logger) {
+ public ErrorHandler(final Component component, final Logger logger) {
this.logger = logger;
this.component = component;
}
/**
- * Set the error that occurred. This should always be called first in a method chain.
- * @param error The error which is a <code>Throwable</code>.
+ * Exit the application.
+ * <p>
+ * This is not a chain-able method for obvious reasons.
+ */
+ public void exit() {
+ System.err.println("Fatal error. Application will exit.");
+ System.exit(1);
+ }
+
+ /**
+ * Log the error message to the <code>Logger</code>.
+ *
+ * @return this object
+ */
+ public ErrorHandler log() {
+ this.logger.log(Level.SEVERE, this.message, this.error);
+ return this;
+ }
+
+ /**
+ * Print the error message to System.err.
+ *
* @return This object.
*/
- public ErrorHandler setError(Throwable error) {
+ public ErrorHandler printMessage() {
+ System.err.println(this.message);
+ return this;
+ }
+
+ /**
+ * Print the full stack trace of the error to System.err.
+ *
+ * @return this object
+ */
+ public ErrorHandler printStackTrace() {
+ this.error.printStackTrace();
+ return this;
+ }
+
+ /**
+ * Immediately re-throw the error as a <code>RuntimeException</code>.
+ * <p>
+ * Additional methods cannot be chained to this as they would not be executed.
+ */
+ public void raiseException() {
+ throw new RuntimeException(this.message, this.error);
+ }
+
+ /**
+ * Set the error that occurred.
+ * <p>
+ * This should always be called first when method chaining.
+ *
+ * @param error the error which is any type of <code>Throwable</code>
+ * @return this object
+ */
+ public ErrorHandler setError(final Throwable error) {
this.error = error;
this.message = error.getMessage();
return this;
}
/**
- * Set the error message if it differs from the exception's message.
- * @param message The erro message.
- * @return This object.
+ * Set the error message, if it differs from the exception's message.
+ *
+ * @param message the error message
+ * @return this object
*/
- public ErrorHandler setMessage(String message) {
+ public ErrorHandler setMessage(final String message) {
this.message = message;
return this;
}
/**
- * Print the full stack trace of the error to System.err.
- * @return This object.
- */
- public ErrorHandler printStackTrace() {
- error.printStackTrace();
- return this;
- }
-
- /**
- * Print the error message to System.err.
- * @return This object.
- */
- public ErrorHandler printMessage() {
- System.err.println(message);
- return this;
- }
-
- /**
- * Log the error message to the <code>Logger</code>.
- * @return This object.
- */
- public ErrorHandler log() {
- logger.log(Level.SEVERE, message, error);
- return this;
- }
-
- /**
* Show an error dialog with the message.
- * @return This object.
+ *
+ * @return this object
*/
public ErrorHandler showErrorDialog() {
final Runnable runnable = new Runnable() {
+ @Override
public void run() {
- JOptionPane.showMessageDialog(component, error.getMessage(), "Application Error", JOptionPane.ERROR_MESSAGE);
- }
- };
- SwingUtilities.invokeLater(runnable);
- return this;
- }
-
- /**
- * Show an error dialog with a custom message and title.
- * @return This object.
- */
- public ErrorHandler showErrorDialog(final String message, final String title) {
- final Runnable runnable = new Runnable() {
- public void run() {
- JOptionPane.showMessageDialog(component, message, title, JOptionPane.ERROR_MESSAGE);
+ JOptionPane.showMessageDialog(ErrorHandler.this.component, ErrorHandler.this.error.getMessage(),
+ "Application Error", JOptionPane.ERROR_MESSAGE);
}
};
SwingUtilities.invokeLater(runnable);
@@ -118,18 +150,20 @@
}
/**
- * Rethrow the error as a <code>RuntimeException</code>. Additional methods cannot be chained to
- * this as they would not be executed.
+ * Show an error dialog with a custom message and title.
+ *
+ * @param message the error message
+ * @param title the title of the dialog window
+ * @return this object
*/
- public void raiseException() {
- throw new RuntimeException(message, error);
- }
-
- /**
- * Exit the application. This is not chainable for obvious reasons.
- */
- public void exit() {
- System.err.println("Fatal error. Application will exit.");
- System.exit(1);
+ public ErrorHandler showErrorDialog(final String message, final String title) {
+ final Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ JOptionPane.showMessageDialog(ErrorHandler.this.component, message, title, JOptionPane.ERROR_MESSAGE);
+ }
+ };
+ SwingUtilities.invokeLater(runnable);
+ return this;
}
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/EtSystemUtil.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/EtSystemUtil.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/EtSystemUtil.java Tue Apr 21 14:48:39 2015
@@ -6,28 +6,39 @@
import org.hps.record.et.EtConnection;
import org.jlab.coda.et.EtConstants;
+/**
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ */
public final class EtSystemUtil {
- private EtSystemUtil() {
+ /**
+ * Create an {@link org.hps.record.et.EtConnection} from the settings in a
+ * {@link org.hps.monitoring.application.model.ConfigurationModel}.
+ *
+ * @param config the {@link org.hps.monitoring.application.model.ConfigurationModel} with the connection settings
+ * @return the new {@link org.hps.record.et.EtConnection}
+ */
+ public static EtConnection createEtConnection(final ConfigurationModel config) {
+ return EtConnection.createConnection(config.getEtName(), config.getHost(), config.getPort(),
+ config.getBlocking(), config.getQueueSize(), config.getPrescale(), config.getStationName(),
+ config.getStationPosition(), config.getWaitMode(), config.getWaitTime(), config.getChunkSize());
}
-
- public static EtConnection createEtConnection(ConfigurationModel config) {
- return EtConnection.createConnection(config.getEtName(),
- config.getHost(),
- config.getPort(),
- config.getBlocking(),
- config.getQueueSize(),
- config.getPrescale(),
- config.getStationName(),
- config.getStationPosition(),
- config.getWaitMode(),
- config.getWaitTime(),
- config.getChunkSize());
+
+ /**
+ * Create an event selection array (with size 6).
+ *
+ * @return the event selection array
+ */
+ public static int[] createSelectArray() {
+ final int select[] = new int[EtConstants.stationSelectInts];
+ Arrays.fill(select, -1);
+ return select;
}
-
- public static int[] createSelectArray() {
- int select[] = new int[EtConstants.stationSelectInts];
- Arrays.fill(select, -1);
- return select;
- }
+
+ /**
+ * Do not allow class instantiation.
+ */
+ private EtSystemUtil() {
+ throw new UnsupportedOperationException("Do not instantiate this class.");
+ }
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/EvioFileFilter.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/EvioFileFilter.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/EvioFileFilter.java Tue Apr 21 14:48:39 2015
@@ -5,24 +5,39 @@
import javax.swing.filechooser.FileFilter;
/**
- * This is a simple file filter that will accept files with ".evio" anywhere in their name.
+ * This is a file filter that will accept files with ".evio" anywhere in their name.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
public final class EvioFileFilter extends FileFilter {
- public EvioFileFilter() {
+ /**
+ * Class constructor.
+ */
+ public EvioFileFilter() {
}
-
+
+ /**
+ * Return <code>true</code> if path should be accepted.
+ *
+ * @return <code>true</code> to accept the path
+ */
@Override
- public boolean accept(File pathname) {
- if (pathname.getName().contains(".evio") || pathname.isDirectory()) {
+ public boolean accept(final File path) {
+ if (path.getName().contains(".evio") || path.isDirectory()) {
return true;
} else {
return false;
}
}
-
+
+ /**
+ * Get the description of the file filter.
+ *
+ * @return the description of the file filter
+ */
@Override
public String getDescription() {
return "EVIO files";
- }
+ }
}
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 Apr 21 14:48:39 2015
@@ -19,106 +19,120 @@
import org.reflections.Reflections;
/**
- *
- * @author Jeremy McCormick <[log in to unmask]>
+ * This is a set of utility methods for getting jar resources at runtime.
*
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
public final class ResourceUtil {
- private ResourceUtil() {
- }
-
- /**
- * Get the files with extension 'lcsim' from all loaded jar files.
- * @param packageName The package name for filtering the resources.
- * @return A list of embedded steering file resources.
- */
- public static String[] findSteeringResources(String packageName) {
- List<String> resources = new ArrayList<String>();
- URL url = ResourceUtil.class.getResource("ResourceUtil.class");
- String scheme = url.getProtocol();
- if (!"jar".equals(scheme)) {
- throw new 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(".lcsim") && entry.getName().contains(packageName)) {
- resources.add(entry.getName());
- }
- }
- archive.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- java.util.Collections.sort(resources);
- String[] arr = new String[resources.size()];
- for (int i = 0; i < arr.length; i++) {
- arr[i] = resources.get(i);
- }
- return arr;
- }
-
- /**
- * Find all classes that implement {@link org.hps.record.LCSimEventBuilder} and return
- * a list of their canonical names.
- * @return The list of classes implementing LCSimEventBuilder.
- */
- public static String[] findEventBuilderClassNames() {
- Reflections reflections = new Reflections("org.hps");
- Set<Class<? extends LCSimEventBuilder>> subTypes = reflections.getSubTypesOf(LCSimEventBuilder.class);
- Set<String> classNames = new HashSet<String>();
- for (Class<? extends LCSimEventBuilder> type : subTypes) {
- classNames.add(type.getCanonicalName());
- }
- return classNames.toArray(new String[classNames.size()]);
- }
-
/**
* Find a list of available detector names.
- * Only those detectors that have names starting with "HPS" in their
- * detector.properties files will be returned.
- * @return The list of available detector names.
+ * <p>
+ * Only those detectors that have names starting with "HPS" in their <code>detector.properties</code> files will be
+ * returned.
+ *
+ * @return the list of available HPS detector names
*/
public static String[] findDetectorNames() {
- ClassLoader classLoader = ResourceUtil.class.getClassLoader();
- List<String> detectorNames = new ArrayList<String>();
- URL url = ResourceUtil.class.getResource("ResourceUtil.class");
- String protocol = url.getProtocol();
+ final ClassLoader classLoader = ResourceUtil.class.getClassLoader();
+ final List<String> detectorNames = new ArrayList<String>();
+ final URL url = ResourceUtil.class.getResource("ResourceUtil.class");
+ final 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();
+ final JarURLConnection con = (JarURLConnection) url.openConnection();
+ final JarFile archive = con.getJarFile();
+ final Enumeration<JarEntry> entries = archive.entries();
while (entries.hasMoreElements()) {
- JarEntry entry = entries.nextElement();
+ final JarEntry entry = entries.nextElement();
if (entry.getName().endsWith("detector.properties")) {
- InputStream inputStream = classLoader.getResourceAsStream(entry.getName());
+ final InputStream inputStream = classLoader.getResourceAsStream(entry.getName());
if (inputStream == null) {
throw new RuntimeException("Failed to load jar entry: " + entry.getName());
}
- Properties properties = new Properties();
+ final Properties properties = new Properties();
properties.load(inputStream);
- String detectorName = properties.getProperty("name");
+ final String detectorName = properties.getProperty("name");
if (detectorName.startsWith("HPS")) {
detectorNames.add(detectorName);
}
}
}
archive.close();
- } catch (IOException e) {
+ } catch (final IOException e) {
throw new RuntimeException(e);
}
Collections.sort(detectorNames);
return detectorNames.toArray(new String[detectorNames.size()]);
- }
-
+ }
+
+ /**
+ * Find all classes that implement {@link org.hps.record.LCSimEventBuilder} and return a list of their canonical
+ * names.
+ *
+ * @return the list of fully qualified class names that implement LCSimEventBuilder
+ */
+ public static String[] findEventBuilderClassNames() {
+ final Reflections reflections = new Reflections("org.hps");
+ final Set<Class<? extends LCSimEventBuilder>> subTypes = reflections.getSubTypesOf(LCSimEventBuilder.class);
+ final Set<String> classNames = new HashSet<String>();
+ for (final Class<? extends LCSimEventBuilder> type : subTypes) {
+ classNames.add(type.getCanonicalName());
+ }
+ return classNames.toArray(new String[classNames.size()]);
+ }
+
+ /**
+ * Get all of the files with the extension "lcsim" which are in a certain package.
+ *
+ * @param packageName the package name for filtering the list of resources
+ * @return a list of embedded steering file resources
+ */
+ public static String[] findSteeringResources(final String packageName) {
+ final List<String> resources = new ArrayList<String>();
+ final URL url = ResourceUtil.class.getResource("ResourceUtil.class");
+ final String scheme = url.getProtocol();
+ if (!"jar".equals(scheme)) {
+ throw new RuntimeException("Unsupported URL protocol: " + url.getProtocol());
+ }
+ try {
+ final JarURLConnection con = (JarURLConnection) url.openConnection();
+ final JarFile archive = con.getJarFile();
+ final Enumeration<JarEntry> entries = archive.entries();
+ while (entries.hasMoreElements()) {
+ final JarEntry entry = entries.nextElement();
+ if (entry.getName().endsWith(".lcsim") && entry.getName().contains(packageName)) {
+ resources.add(entry.getName());
+ }
+ }
+ archive.close();
+ } catch (final IOException e) {
+ throw new RuntimeException(e);
+ }
+ java.util.Collections.sort(resources);
+ final String[] arr = new String[resources.size()];
+ for (int i = 0; i < arr.length; i++) {
+ arr[i] = resources.get(i);
+ }
+ return arr;
+ }
+
+ /**
+ * Get the list of available conditions tags from the conditions system.
+ *
+ * @return the list of available conditions tags
+ */
+ // FIXME: This method probably does not belong in this class.
public static String[] getConditionsTags() {
return DatabaseConditionsManager.getInstance().getTags().toArray(new String[] {});
}
+
+ /**
+ * Do not allow class instantiation.
+ */
+ private ResourceUtil() {
+ throw new UnsupportedOperationException("Do not instantiate this class.");
+ }
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/SyncEventProcessor.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/SyncEventProcessor.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/SyncEventProcessor.java Tue Apr 21 14:48:39 2015
@@ -15,20 +15,32 @@
import org.lcsim.event.base.BaseLCSimEvent;
/**
- * This is an ET event processor that will load DAQ configuration into the global manager
- * from EVIO physics SYNC events, which have an event type in which bits 6 and 7 are set to 1.
- *
- * @author Jeremy McCormick <[log in to unmask]>
- *
+ * This is an ET event processor that will load DAQ configuration into the global manager from EVIO physics SYNC events,
+ * which have an event type in which bits 6 and 7 are set to 1.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
* @see org.hps.recon.ecal.daqconfig.ConfigurationManager
* @see org.hps.recon.ecal.daqconfig.EvioDAQParser
*/
-public class SyncEventProcessor extends EtEventProcessor {
+// FIXME: This class is currently unused.
+public final class SyncEventProcessor extends EtEventProcessor {
+ /**
+ * The name of the trigger configuration collection.
+ */
private static final String TRIGGER_CONFIG = "TriggerConfig";
- TriggerConfigEvioReader configReader = new TriggerConfigEvioReader();
- public void process(EtEvent event) {
+ /**
+ * The trigger configuration reader.
+ */
+ private final TriggerConfigEvioReader configReader = new TriggerConfigEvioReader();
+
+ /**
+ * Process an ET event and if there is a trigger configuration present, parse it and update the configuration in the
+ * global manager.
+ */
+ @Override
+ public void process(final EtEvent event) {
EvioEvent evioEvent = null;
try {
evioEvent = new EvioReader(event.getDataBuffer()).parseNextEvent();
@@ -37,20 +49,20 @@
}
try {
// Create a dummy LCIO event to satisfy the configuration reader's interface.
- BaseLCSimEvent dummyLcsimEvent =
- new BaseLCSimEvent(EvioEventUtilities.getRunNumber(evioEvent), evioEvent.getEventNumber(), "DUMMY", 0, false);
-
+ final BaseLCSimEvent dummyLcsimEvent = new BaseLCSimEvent(EvioEventUtilities.getRunNumber(evioEvent),
+ evioEvent.getEventNumber(), "DUMMY", 0, false);
+
// Create the DAQ configuration object in the LCIO event.
- configReader.getDAQConfig(evioEvent, dummyLcsimEvent);
-
+ this.configReader.getDAQConfig(evioEvent, dummyLcsimEvent);
+
// Update the global configuration if a configuration was created.
if (dummyLcsimEvent.hasCollection(EvioDAQParser.class, TRIGGER_CONFIG)) {
- List<EvioDAQParser> configList = dummyLcsimEvent.get(EvioDAQParser.class, TRIGGER_CONFIG);
+ final List<EvioDAQParser> configList = dummyLcsimEvent.get(EvioDAQParser.class, TRIGGER_CONFIG);
if (!configList.isEmpty()) {
ConfigurationManager.updateConfiguration(configList.get(0));
}
}
- } catch (Exception e) {
+ } catch (final Exception e) {
System.err.println("Failed to load DAQ config from sync event ...");
e.printStackTrace();
}
Modified: java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/TableExporter.java
=============================================================================
--- java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/TableExporter.java (original)
+++ java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/TableExporter.java Tue Apr 21 14:48:39 2015
@@ -9,54 +9,60 @@
/**
* This is a utility for exporting a JTable's model data to a text file.
- * Non-numeric fields are all contained in double quotes.
- *
- * @author Jeremy McCormick <[log in to unmask]>
+ * <p>
+ * Non-numeric fields such as strings are delimited by double quotes.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
*/
public final class TableExporter {
-
- private TableExporter() {
- }
-
+
/**
* Export the given table to a text file.
- * @param table The JTable component.
- * @param path The output file path.
- * @param fieldDelimiter The field delimiter to use.
- * @throws IOException if there are errors writing the file.
+ *
+ * @param table the JTable component
+ * @param path the output file path
+ * @param fieldDelimiter the field delimiter to use
+ * @throws IOException if there are errors writing the file
*/
- public static void export(JTable table, String path, char fieldDelimiter) throws IOException {
-
- StringBuffer buffer = new StringBuffer();
- TableModel model = table.getModel();
- int rowCount = model.getRowCount();
- int columnCount = model.getColumnCount();
-
+ public static void export(final JTable table, final String path, final char fieldDelimiter) throws IOException {
+
+ final StringBuffer buffer = new StringBuffer();
+ final TableModel model = table.getModel();
+ final int rowCount = model.getRowCount();
+ final int columnCount = model.getColumnCount();
+
// Column headers.
for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
buffer.append("\"" + model.getColumnName(columnIndex) + "\"" + fieldDelimiter);
- }
+ }
buffer.setLength(buffer.length() - 1);
buffer.append('\n');
-
+
// Row data.
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
- Object value = model.getValueAt(rowIndex, columnIndex);
+ final Object value = model.getValueAt(rowIndex, columnIndex);
if (Number.class.isAssignableFrom(model.getColumnClass(columnIndex))) {
buffer.append(value);
} else {
buffer.append("\"" + value + "\"" + fieldDelimiter);
}
- }
+ }
buffer.setLength(buffer.length() - 1);
buffer.append('\n');
}
-
+
// Write string buffer to file.
- BufferedWriter out = new BufferedWriter(new FileWriter(path));
+ final BufferedWriter out = new BufferedWriter(new FileWriter(path));
out.write(buffer.toString());
out.flush();
out.close();
- }
+ }
+
+ /**
+ * Do not allow class instantiation.
+ */
+ private TableExporter() {
+ throw new UnsupportedOperationException("Do not instantiate this class.");
+ }
}
|