LISTSERV mailing list manager LISTSERV 16.5

Help for HPS-SVN Archives


HPS-SVN Archives

HPS-SVN Archives


HPS-SVN@LISTSERV.SLAC.STANFORD.EDU


View:

Message:

[

First

|

Previous

|

Next

|

Last

]

By Topic:

[

First

|

Previous

|

Next

|

Last

]

By Author:

[

First

|

Previous

|

Next

|

Last

]

Font:

Proportional Font

LISTSERV Archives

LISTSERV Archives

HPS-SVN Home

HPS-SVN Home

HPS-SVN  March 2015

HPS-SVN March 2015

Subject:

r2273 - /java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/

From:

[log in to unmask]

Reply-To:

Notification of commits to the hps svn repository <[log in to unmask]>

Date:

Thu, 5 Mar 2015 21:46:29 -0000

Content-Type:

text/plain

Parts/Attachments:

Parts/Attachments

text/plain (1192 lines)

Author: [log in to unmask]
Date: Thu Mar  5 13:46:25 2015
New Revision: 2273

Log:
Added monitoring components for the trigger diagnostics to their new home package.

Added:
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTablePanel.java
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTriggerTablePanel.java
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTwoColumnTablePanel.java
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/ClusterTablePanel.java
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/ComponentUtils.java
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/DiagnosticUpdatable.java
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/EfficiencyTablePanel.java
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/PairTablePanel.java
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/SinglesTablePanel.java
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/TableTextModel.java
    java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/TriggerDiagnosticGUIDriver.java

Added: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTablePanel.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTablePanel.java	(added)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTablePanel.java	Thu Mar  5 13:46:25 2015
@@ -0,0 +1,249 @@
+package org.hps.monitoring.trigger;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTable;
+
+import org.hps.analysis.trigger.util.ComponentUtils;
+
+/**
+ * Class <code>AbstractTablePanel</code> displays two <code>JTable</code>
+ * objects side-by-side with headers above them. The left table displays
+ * statistical data for recent events processed with trigger diagnostics
+ * while the right table displays the same, but over the course of the
+ * entire run.<br/>
+ * <br/>
+ * This implements the interface <code>DiagnosticUpdatable</code>.
+ * 
+ * @author Kyle McCarty <[log in to unmask]>
+ * @see JPanel
+ * @see DiagnosticUpdatable
+ */
+public abstract class AbstractTablePanel extends JPanel implements DiagnosticUpdatable {
+	// Static variables.
+	private static final long serialVersionUID = 0L;
+	public static final int ORIENTATION_HORIZONTAL = 0;
+	public static final int ORIENTATION_VERTICAL   = 1;
+	
+	// Components.
+	private JLabel localHeader;
+	private JLabel globalHeader;
+	protected final JTable localTable;
+	protected final JTable globalTable;
+	
+	// Component parameters.
+	private boolean horizontal = true;
+	private Dimension userPrefSize = null;
+	private Dimension defaultPrefSize = new Dimension(0, 0);
+	
+	/**
+	 * Instantiates an <code>AbstractTablePanel</code>.
+	 * @param args Arguments to be usd when generating the panel tables.
+	 */
+	public AbstractTablePanel(Object... args) {
+		// Initialize the tables.
+		JTable[] tables = initializeTables(args);
+		localTable = tables[0];
+		globalTable = tables[1];
+		add(globalTable);
+		add(localTable);
+		
+		// Set the panels to their null starting values.
+		updatePanel(null);
+		
+		// Define the panel layout.
+		setLayout(null);
+		
+		// Create header labels for the tables.
+		localHeader = new JLabel("Local Statistics");
+		localHeader.setHorizontalAlignment(JLabel.CENTER);
+		add(localHeader);
+		
+		globalHeader = new JLabel("Run Statistics");
+		globalHeader.setHorizontalAlignment(JLabel.CENTER);
+		add(globalHeader);
+		
+		// Track when the component changes size and reposition the
+		// components accordingly.
+		addComponentListener(new ComponentAdapter() {
+			@Override
+			public void componentResized(ComponentEvent e) { positionComponents(); }
+		});
+		
+		// Define the component preferred size.
+		defaultPrefSize.width = localTable.getPreferredSize().width +
+				ComponentUtils.hinternal + globalTable.getPreferredSize().width;
+		defaultPrefSize.height = localTable.getPreferredSize().height +
+				ComponentUtils.vinternal + globalTable.getPreferredSize().height;
+	}
+	
+	@Override
+	public Dimension getPreferredSize() {
+		// If there is a user-specified preferred size, return that.
+		if(userPrefSize == null) { return defaultPrefSize; }
+		
+		// Otherwise, return the default calculated preferred size.
+		else { return userPrefSize; }
+	}
+	
+	@Override
+	public void setBackground(Color bg) {
+		// Set the base component background.
+		super.setBackground(bg);
+		
+		// If the components have been initialized, pass the background
+		// color change to them as appropriate. Note that the tables
+		// will always retain the same background color.
+		if(localTable != null) {
+			// Set the header backgrounds.
+			localHeader.setBackground(bg);
+			globalHeader.setBackground(bg);
+		}
+	}
+	
+	@Override
+	public void setFont(Font font) {
+		// Set the base component font.
+		super.setFont(font);
+		
+		// If the components have been initialized, pass the font change
+		// to them as appropriate.
+		if(localTable != null) {
+			// Set the table fonts.
+			localTable.setFont(font);
+			globalTable.setFont(font);
+			
+			// Set the header fonts.
+			Font headerFont = font.deriveFont(Font.BOLD, (float) Math.ceil(font.getSize2D() * 1.3));
+			localHeader.setFont(headerFont);
+			globalHeader.setFont(headerFont);
+		}
+	}
+	
+	@Override
+	public void setForeground(Color fg) {
+		// Set the base component foreground.
+		super.setForeground(fg);
+		
+		// If the components have been initialized, pass the foreground
+		// color change to them as appropriate. Note that the tables
+		// will always retain the same foreground color.
+		if(localTable != null) {
+			// Set the header foregrounds.
+			localHeader.setForeground(fg);
+			globalHeader.setForeground(fg);
+		}
+	}
+	
+	/**
+	 * Sets the orientation of components on the panel.
+	 * @param orientation - The orientation identifier. Identifiers can
+	 * be obtained as static variables from the within the root object
+	 * <code>AbstractTable</code>.
+	 */
+	public void setOrientation(int orientation) {
+		if(orientation == ORIENTATION_HORIZONTAL) {
+			if(!horizontal) {
+				horizontal = true;
+				positionComponents();
+			}
+		} else if(orientation == ORIENTATION_VERTICAL) {
+			if(horizontal) {
+				horizontal = false;
+				positionComponents();
+			}
+		} else {
+			throw new IllegalArgumentException("Invalid orienation identifier.");
+		}
+	}
+	
+	@Override
+	public void setPreferredSize(Dimension preferredSize) {
+		userPrefSize = preferredSize;
+	}
+	
+	/**
+	 * Generates the two tables that are used by the component. This
+	 * must return an array of size two.
+	 * @param args - Any arguments that should be passed to the method
+	 * for generating tables.
+	 * @return Returns an array of size two, where the first index must
+	 * contain the local table and the second index the global table.
+	 */
+	protected abstract JTable[] initializeTables(Object... args);
+	
+	/**
+	 * Repositions the components to the correct places on the parent
+	 * <code>JPanel</code>. This should be run whenever the panel
+	 * changes size.
+	 */
+	private void positionComponents() {
+		// Do not update if the components have not been initialized.
+		if(localHeader == null) { return; }
+		
+		// If the components should be position horizontally...
+		if(horizontal) {
+			// The local components get the left half of the panel and the
+			// global components the right. Find half of the panel width,
+			// accounting for the internal spacing. This is an internal
+			// component, so it does not employ additional spacing between
+			// itself and the parent component's edges.
+			int compWidth = (getWidth() - 10) / 2;
+			
+			// If there is any width remaining, it goes to the spacing.
+			int horizontal = ComponentUtils.hinternal + (getWidth() - 10) % 2;
+			
+			// Place the header labels. These are given their preferred
+			// height. Note that this means a very small panel may cut off
+			// some of the components. First, get the preferred height of
+			// the label with the larger preferred height. These should be
+			// the same thing, but just in case...
+			int labelHeight = localHeader.getPreferredSize().height;
+			if(labelHeight < globalHeader.getPreferredSize().height) {
+				labelHeight = globalHeader.getPreferredSize().height;
+			}
+			
+			// Set the label sizes and positions.
+			localHeader.setBounds(0, 0, compWidth, labelHeight);
+			globalHeader.setLocation(ComponentUtils.getNextX(localHeader, horizontal), 0);
+			globalHeader.setSize(compWidth, labelHeight);
+			
+			// The tables go under their respective labels and should fill
+			// the remainder of the label height.
+			int tableY = ComponentUtils.getNextY(localHeader, ComponentUtils.vinternal);
+			localTable.setBounds(0, tableY, compWidth, localTable.getPreferredSize().height);
+			globalTable.setBounds(globalHeader.getX(), tableY, compWidth, globalTable.getPreferredSize().height);
+		}
+		
+		// Otherwise, position them vertically.
+		else {
+			// Place the header labels. These are given their preferred
+			// height. Note that this means a very small panel may cut off
+			// some of the components. First, get the preferred height of
+			// the label with the larger preferred height. These should be
+			// the same thing, but just in case...
+			int labelHeight = localHeader.getPreferredSize().height;
+			if(labelHeight < globalHeader.getPreferredSize().height) {
+				labelHeight = globalHeader.getPreferredSize().height;
+			}
+			
+			// The local components go first, taking up the entire upper
+			// width of the panel.
+			localHeader.setBounds(0, 0, getWidth(), labelHeight);
+			localTable.setBounds(0, ComponentUtils.getNextY(localHeader, ComponentUtils.vinternal),
+					getWidth(), localTable.getPreferredSize().height);
+			
+			// The global components go immediately below.
+			globalHeader.setBounds(0, ComponentUtils.getNextY(localTable, ComponentUtils.vinternal),
+					getWidth(), labelHeight);
+			globalTable.setBounds(0, ComponentUtils.getNextY(globalHeader, ComponentUtils.vinternal),
+					getWidth(), globalTable.getPreferredSize().height);
+		}
+	}
+}

Added: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTriggerTablePanel.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTriggerTablePanel.java	(added)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTriggerTablePanel.java	Thu Mar  5 13:46:25 2015
@@ -0,0 +1,176 @@
+package org.hps.monitoring.trigger;
+
+import org.hps.analysis.trigger.DiagSnapshot;
+import org.hps.analysis.trigger.event.TriggerStatModule;
+import org.hps.analysis.trigger.util.ComponentUtils;
+
+/**
+ * Abstract class <code>AbstractTriggerTablePanel</code> creates the
+ * basic framework to display trigger statistics. It is also able to
+ * update itself from the diagnostic snapshot given certain information,
+ * which is obtained through the implementation of its abstract methods
+ * by subclasses.
+ * 
+ * @author Kyle McCarty <[log in to unmask]>
+ */
+public abstract class AbstractTriggerTablePanel extends AbstractTwoColumnTablePanel {
+	// Static variables.
+	private static final long serialVersionUID = 0L;
+	
+	// Internal variables.
+	private final int numCuts;
+	
+	// Reference variables to the default table rows.
+	protected static final int ROW_RECON_COUNT        = 0;
+	protected static final int ROW_SSP_SIM_COUNT      = 1;
+	protected static final int ROW_SSP_BANK_COUNT     = 2;
+	protected static final int ROW_SSP_EFFICIENCY     = 3;
+	protected static final int ROW_TRIGGER_EFFICIENCY = 4;
+	protected static final int ROW_EMPTY_SPACE        = 5;
+	protected static final int ROW_CUT_FAILS_TITLE    = 6;
+	protected static final int ROW_FIRST_TRIGGER_CUT  = 7;
+	
+	/**
+	 * Instantiates an <code>AbstractTriggerTablePanel</code> with the
+	 * indicated cut names.
+	 * @param cutNames
+	 */
+	public AbstractTriggerTablePanel(String[] cutNames) {
+		// Instantiate the superclass.
+		super(makeTitle(cutNames));
+		
+		// Store the number of cuts.
+		numCuts = cutNames.length;
+		updatePanel(null);
+	}
+	
+	@Override
+	public void updatePanel(DiagSnapshot snapshot) {
+		// If the snapshot is null, all values should be "N/A."
+		if(snapshot == null) {
+			// Output cluster count data.
+			String scalerNullValue = "---";
+			setLocalRowValue(ROW_RECON_COUNT,     scalerNullValue);
+			setLocalRowValue(ROW_SSP_SIM_COUNT,   scalerNullValue);
+			setLocalRowValue(ROW_SSP_BANK_COUNT,  scalerNullValue);
+			setGlobalRowValue(ROW_RECON_COUNT,    scalerNullValue);
+			setGlobalRowValue(ROW_SSP_SIM_COUNT,  scalerNullValue);
+			setGlobalRowValue(ROW_SSP_BANK_COUNT, scalerNullValue);
+			
+			// Output the tracked statistical data.
+			String percentNullValue = "--- / --- (---%)";
+			setLocalRowValue(ROW_SSP_EFFICIENCY,      percentNullValue);
+			setLocalRowValue(ROW_TRIGGER_EFFICIENCY,  percentNullValue);
+			setGlobalRowValue(ROW_SSP_EFFICIENCY,     percentNullValue);
+			setGlobalRowValue(ROW_TRIGGER_EFFICIENCY, percentNullValue);
+			
+			int ROW_SECOND_TRIGGER_CUT = ROW_FIRST_TRIGGER_CUT + numCuts + 2;
+			for(int cutRow = 0; cutRow < numCuts; cutRow++) {
+				setLocalRowValue(cutRow + ROW_FIRST_TRIGGER_CUT,   percentNullValue);
+				setLocalRowValue(cutRow + ROW_SECOND_TRIGGER_CUT,  percentNullValue);
+				setGlobalRowValue(cutRow + ROW_FIRST_TRIGGER_CUT,  percentNullValue);
+				setGlobalRowValue(cutRow + ROW_SECOND_TRIGGER_CUT, percentNullValue);
+			}
+		} else {
+			// Get the local and run trigger statistics from the snapshot.
+			TriggerStatModule lstat = getLocalModule(snapshot);
+			TriggerStatModule rstat = getRunModule(snapshot);
+			
+			// Determine the most spaces needed to display the values.
+			// Get the largest number of digits in any of the values.
+			int mostDigits = ComponentUtils.max(lstat.getReconTriggerCount(), lstat.getSSPBankTriggerCount(),
+					lstat.getSSPSimTriggerCount(), rstat.getReconTriggerCount(), rstat.getSSPBankTriggerCount(),
+					rstat.getSSPSimTriggerCount());
+			
+			// Update the single-value counters.
+			String countFormat = "%" + mostDigits + "d";
+			setLocalRowValue(ROW_RECON_COUNT,     String.format(countFormat, lstat.getReconTriggerCount()));
+			setLocalRowValue(ROW_SSP_SIM_COUNT,   String.format(countFormat, lstat.getSSPSimTriggerCount()));
+			setLocalRowValue(ROW_SSP_BANK_COUNT,  String.format(countFormat, lstat.getSSPBankTriggerCount()));
+			setGlobalRowValue(ROW_RECON_COUNT,    String.format(countFormat, rstat.getReconTriggerCount()));
+			setGlobalRowValue(ROW_SSP_SIM_COUNT,  String.format(countFormat, rstat.getSSPSimTriggerCount()));
+			setGlobalRowValue(ROW_SSP_BANK_COUNT, String.format(countFormat, rstat.getSSPBankTriggerCount()));
+			
+			// Update the percentage counters.
+			String percentFormat = "%" + mostDigits + "d / %" + mostDigits + "d (%7.3f)";
+			
+			setLocalRowValue(ROW_SSP_EFFICIENCY, String.format(percentFormat, lstat.getMatchedSSPTriggers(),
+					lstat.getSSPSimTriggerCount(), (100.0 * lstat.getMatchedSSPTriggers() / lstat.getSSPSimTriggerCount())));
+			setLocalRowValue(ROW_TRIGGER_EFFICIENCY, String.format(percentFormat, lstat.getMatchedReconTriggers(),
+					lstat.getReconTriggerCount(), (100.0 * lstat.getMatchedReconTriggers() / lstat.getReconTriggerCount())));
+			setGlobalRowValue(ROW_SSP_EFFICIENCY, String.format(percentFormat, rstat.getMatchedSSPTriggers(),
+					rstat.getSSPSimTriggerCount(), (100.0 * rstat.getMatchedSSPTriggers() / rstat.getSSPSimTriggerCount())));
+			setGlobalRowValue(ROW_TRIGGER_EFFICIENCY, String.format(percentFormat, lstat.getMatchedReconTriggers(),
+					rstat.getReconTriggerCount(), (100.0 * rstat.getMatchedReconTriggers() / rstat.getReconTriggerCount())));
+			
+			int ROW_SECOND_TRIGGER_CUT = ROW_FIRST_TRIGGER_CUT + numCuts + 2;
+			int[] total = { lstat.getSSPSimTriggerCount() / 2, rstat.getSSPSimTriggerCount() / 2 };
+			for(int cutRow = 0; cutRow < numCuts; cutRow++) {
+				setLocalRowValue(cutRow + ROW_FIRST_TRIGGER_CUT, String.format(percentFormat, lstat.getCutFailures(0, cutRow),
+						total[0], (100.0 * lstat.getCutFailures(0, cutRow) / total[0])));
+				setLocalRowValue(cutRow + ROW_SECOND_TRIGGER_CUT, String.format(percentFormat, lstat.getCutFailures(1, cutRow),
+						total[0], (100.0 * lstat.getCutFailures(1, cutRow) / total[0])));
+				setGlobalRowValue(cutRow + ROW_FIRST_TRIGGER_CUT, String.format(percentFormat, lstat.getCutFailures(0, cutRow),
+						total[1], (100.0 * lstat.getCutFailures(0, cutRow) / total[1])));
+				setGlobalRowValue(cutRow + ROW_SECOND_TRIGGER_CUT, String.format(percentFormat, lstat.getCutFailures(1, cutRow),
+						total[1], (100.0 * lstat.getCutFailures(1, cutRow) / total[1])));
+			}
+		}
+	}
+	
+	/**
+	 * Gets the statistical module from which local statistics should
+	 * be drawn.
+	 * @param snapshot - The snapshot containing the modules.
+	 * @return Returns the module containing local statistical data.
+	 */
+	protected abstract TriggerStatModule getLocalModule(DiagSnapshot snapshot);
+	
+	/**
+	 * Gets the statistical module from which run statistics should
+	 * be drawn.
+	 * @param snapshot - The snapshot containing the modules.
+	 * @return Returns the module containing run statistical data.
+	 */
+	protected abstract TriggerStatModule getRunModule(DiagSnapshot snapshot);
+	
+	/**
+	 * Creates the table appropriate table rows from the argument cut
+	 * names.
+	 * @param cutNames - An array containing the names of the cuts to
+	 * display.
+	 * @return Returns an array with the default table rows merged in
+	 * with the provided cut names.
+	 */
+	private static final String[] makeTitle(String[] cutNames) {
+		// Make a new array to hold all the text.
+		String[] mergedArray = new String[cutNames.length + cutNames.length + 9];
+		
+		// Define the default trigger headers.
+		mergedArray[0] = "Recon Triggers:";
+		mergedArray[1] = "SSP Sim Triggers:";
+		mergedArray[2] = "SSP Bank Triggers:";
+		mergedArray[3] = "SSP Efficiency:";
+		mergedArray[4] = "Trigger Efficiency:";
+		mergedArray[5] = "";
+		mergedArray[6] = "First Trigger Cut Failures";
+		
+		// Insert the cut names for the first trigger.
+		for(int cutIndex = 0; cutIndex < cutNames.length; cutIndex++) {
+			mergedArray[7 + cutIndex] = cutNames[cutIndex];
+		}
+		
+		// Insert the header for the second trigger cut names.
+		int startIndex = 7 + cutNames.length;
+		mergedArray[startIndex]     = "";
+		mergedArray[startIndex + 1] = "Second Trigger Cut Failures";
+		
+		// Insert the next set of cut names.
+		for(int cutIndex = 0; cutIndex < cutNames.length; cutIndex++) {
+			mergedArray[startIndex + 2 + cutIndex] = cutNames[cutIndex];
+		}
+		
+		// Return the resultant array.
+		return mergedArray;
+	}
+}

Added: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTwoColumnTablePanel.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTwoColumnTablePanel.java	(added)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/AbstractTwoColumnTablePanel.java	Thu Mar  5 13:46:25 2015
@@ -0,0 +1,93 @@
+package org.hps.monitoring.trigger;
+
+import javax.swing.JTable;
+
+/**
+ * Class <code>AbstractTwoColumnTablePanel</code> is an implementation
+ * of <code>AbstractTablePanel</code> that specifically handles tables
+ * with two columns where the first column's cells are row headers and
+ * the second column contains values.
+ * 
+ * @author Kyle McCarty <[log in to unmask]>
+ * @see AbstractTablePanel
+ */
+public abstract class AbstractTwoColumnTablePanel extends AbstractTablePanel {
+	// Static variables.
+	private static final long serialVersionUID = 0L;
+	
+	// Table models.
+	private TableTextModel localModel;
+	private TableTextModel globalModel;
+	
+	// Table model mappings.
+	private static final int COL_TITLE = 0;
+	private static final int COL_VALUE = 1;
+	
+	/**
+	 * Instantiates an <code>AbstractTwoColumnTablePanel</code> object
+	 * with the indicated row names.
+	 * @param rowNames - The names of the rows.
+	 */
+	public AbstractTwoColumnTablePanel(String[] rowNames) {
+		super((Object[]) rowNames);
+	}
+	
+	@Override
+	protected JTable[] initializeTables(Object... args) {
+		// The arguments should be a string array.
+		if(!(args instanceof String[])) {
+			throw new IllegalArgumentException("Row names must be strings!");
+		}
+		String[] rowNames = (String[]) args;
+		
+		// Initialize the table models. They should have two columns
+		// (one for values and one for headers) and a number of rows
+		// equal to the number of row names.
+		localModel = new TableTextModel(rowNames.length, 2);
+		globalModel = new TableTextModel(rowNames.length, 2);
+		
+		// Initialize the titles.
+		for(int i = 0; i < rowNames.length; i++) {
+			localModel.setValueAt(rowNames[i], i, COL_TITLE);
+			globalModel.setValueAt(rowNames[i], i, COL_TITLE);
+		}
+		updatePanel(null);
+		
+		// Create JTable objects to display the data.
+		JTable localTable = new JTable(localModel);
+		localTable.setRowSelectionAllowed(false);
+		localTable.setColumnSelectionAllowed(false);
+		localTable.setCellSelectionEnabled(false);
+		localTable.setShowVerticalLines(false);
+		
+		JTable globalTable = new JTable(globalModel);
+		globalTable.setRowSelectionAllowed(false);
+		globalTable.setColumnSelectionAllowed(false);
+		globalTable.setCellSelectionEnabled(false);
+		globalTable.setShowVerticalLines(false);
+		
+		// Return the two tables.
+		return new JTable[] { localTable, globalTable };
+	}
+	
+	/**
+	 * Sets the value of the indicated row for the global statistical
+	 * table.
+	 * @param rowIndex - The row.
+	 * @param value - The new value.
+	 */
+	protected void setGlobalRowValue(int rowIndex, String value) {
+		globalModel.setValueAt(value, rowIndex, COL_VALUE);
+	}
+	
+	/**
+	 * Sets the value of the indicated row for the local statistical
+	 * table.
+	 * @param rowIndex - The row.
+	 * @param value - The new value.
+	 */
+	protected void setLocalRowValue(int rowIndex, String value) {
+		localModel.setValueAt(value, rowIndex, COL_VALUE);
+	}
+
+}

Added: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/ClusterTablePanel.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/ClusterTablePanel.java	(added)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/ClusterTablePanel.java	Thu Mar  5 13:46:25 2015
@@ -0,0 +1,111 @@
+package org.hps.monitoring.trigger;
+
+import org.hps.analysis.trigger.DiagSnapshot;
+import org.hps.analysis.trigger.event.ClusterStatModule;
+import org.hps.analysis.trigger.util.ComponentUtils;
+
+/**
+ * Class <code>ClusterTablePanel</code> is an implementation of class
+ * <code>AbstractTablePanel</code> for cluster statistical data.<br/>
+ * <br/>
+ * This implements the interface <code>DiagnosticUpdatable</code>.
+ * 
+ * @author Kyle McCarty <[log in to unmask]>
+ * @see AbstractTablePanel
+ */
+public class ClusterTablePanel extends AbstractTwoColumnTablePanel {
+	// Static variables.
+	private static final long serialVersionUID = 0L;
+	private static final String[] TABLE_TITLES = { "Recon Clusters", "SSP Clusters", "Matched Clusters",
+			"Failed (Position)", "Failed (Energy)", "Failed (Hit Count)" };
+	
+	// Table model mappings.
+	private static final int ROW_RECON_COUNT      = 0;
+	private static final int ROW_SSP_COUNT        = 1;
+	private static final int ROW_MATCHED          = 2;
+	private static final int ROW_FAILED_POSITION  = 3;
+	private static final int ROW_FAILED_ENERGY    = 4;
+	private static final int ROW_FAILED_HIT_COUNT = 5;
+	
+	/**
+	 * Instantiate a new <code>ClusterTablePanel</code>.
+	 */
+	public ClusterTablePanel() { super(TABLE_TITLES); }
+	
+	@Override
+	public void updatePanel(DiagSnapshot snapshot) {
+		// If the snapshot is null, all values should be "N/A."
+		if(snapshot == null) {
+			// Output cluster count data.
+			String scalerNullValue = "---";
+			setLocalRowValue(ROW_RECON_COUNT,  scalerNullValue);
+			setLocalRowValue(ROW_SSP_COUNT,    scalerNullValue);
+			setGlobalRowValue(ROW_RECON_COUNT, scalerNullValue);
+			setGlobalRowValue(ROW_SSP_COUNT,   scalerNullValue);
+			
+			// Output the tracked statistical data.
+			String percentNullValue = "--- / --- (---%)";
+			setLocalRowValue(ROW_MATCHED,           percentNullValue);
+			setLocalRowValue(ROW_FAILED_POSITION,   percentNullValue);
+			setLocalRowValue(ROW_FAILED_ENERGY,     percentNullValue);
+			setLocalRowValue(ROW_FAILED_HIT_COUNT,  percentNullValue);
+			setGlobalRowValue(ROW_MATCHED,          percentNullValue);
+			setGlobalRowValue(ROW_FAILED_POSITION,  percentNullValue);
+			setGlobalRowValue(ROW_FAILED_ENERGY,    percentNullValue);
+			setGlobalRowValue(ROW_FAILED_HIT_COUNT, percentNullValue);
+		}
+		
+		// Otherwise, populate the table with the diagnostic data.
+		else {
+			// Get the cluster statistical banks.
+			ClusterStatModule lstat = snapshot.clusterLocalStatistics;
+			ClusterStatModule rstat = snapshot.clusterRunStatistics;
+			
+			// Get the largest number of digits in any of the values.
+			int mostDigits = ComponentUtils.max(lstat.getReconClusterCount(), lstat.getSSPClusterCount(), lstat.getMatches(),
+					lstat.getPositionFailures(), lstat.getEnergyFailures(), lstat.getHitCountFailures(),
+					rstat.getReconClusterCount(), rstat.getSSPClusterCount(), rstat.getMatches(),
+					rstat.getPositionFailures(), rstat.getEnergyFailures(), rstat.getHitCountFailures());
+			
+			// Put the number of reconstructed and SSP clusters into
+			// the tables.
+			int[] clusterValue = {
+					lstat.getReconClusterCount(),
+					lstat.getSSPClusterCount(),
+					rstat.getReconClusterCount(),
+					rstat.getSSPClusterCount()
+			};
+			String countFormat = "%" + mostDigits + "d";
+			setLocalRowValue(ROW_RECON_COUNT,  String.format(countFormat, clusterValue[0]));
+			setLocalRowValue(ROW_SSP_COUNT,    String.format(countFormat, clusterValue[1]));
+			setGlobalRowValue(ROW_RECON_COUNT, String.format(countFormat, clusterValue[2]));
+			setGlobalRowValue(ROW_SSP_COUNT,   String.format(countFormat, clusterValue[3]));
+			
+			// Output the tracked statistical data.
+			int total;
+			String percentFormat = "%" + mostDigits + "d / %" + mostDigits + "d (%7.3f)";
+			int[] statValue = {
+					lstat.getMatches(),
+					lstat.getPositionFailures(),
+					lstat.getEnergyFailures(),
+					lstat.getHitCountFailures(),
+					rstat.getMatches(),
+					rstat.getPositionFailures(),
+					rstat.getEnergyFailures(),
+					rstat.getHitCountFailures()
+			};
+			
+			total = lstat.getReconClusterCount();
+			setLocalRowValue(ROW_MATCHED,          String.format(percentFormat, statValue[0], total, 100.0 * statValue[0] / total));
+			setLocalRowValue(ROW_FAILED_POSITION,  String.format(percentFormat, statValue[1], total, 100.0 * statValue[1] / total));
+			setLocalRowValue(ROW_FAILED_ENERGY,    String.format(percentFormat, statValue[2], total, 100.0 * statValue[2] / total));
+			setLocalRowValue(ROW_FAILED_HIT_COUNT, String.format(percentFormat, statValue[3], total, 100.0 * statValue[3] / total));
+			
+			total = rstat.getReconClusterCount();
+			setGlobalRowValue(ROW_MATCHED,          String.format(percentFormat, statValue[4], total, 100.0 * statValue[4] / total));
+			setGlobalRowValue(ROW_FAILED_POSITION,  String.format(percentFormat, statValue[5], total, 100.0 * statValue[5] / total));
+			setGlobalRowValue(ROW_FAILED_ENERGY,    String.format(percentFormat, statValue[6], total, 100.0 * statValue[6] / total));
+			setGlobalRowValue(ROW_FAILED_HIT_COUNT, String.format(percentFormat, statValue[7], total, 100.0 * statValue[7] / total));
+		}
+	}
+}

Added: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/ComponentUtils.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/ComponentUtils.java	(added)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/ComponentUtils.java	Thu Mar  5 13:46:25 2015
@@ -0,0 +1,126 @@
+package org.hps.monitoring.trigger;
+
+import java.awt.Component;
+
+import org.hps.analysis.trigger.util.TriggerDiagnosticUtil;
+
+/**
+ * Class <code>ComponentUtils</code> is a list of utility methods used
+ * by the trigger diagnostic GUI.
+ * 
+ * @author Kyle McCarty <[log in to unmask]>
+ */
+public class ComponentUtils {
+	/** The default spacing used between a horizontal edge of one
+	 * component and the horizontal edge of another. */
+	static final int hinternal = 10;
+	/** The default spacing used between a vertical edge of one
+	 * component and the vertical edge of another. */
+	static final int vinternal = 10;
+	/** The default spacing used between a horizontal edge of one
+	 * component and the edge of its parent component. */
+	static final int hexternal = 0;
+	/** The default spacing used between a vertical edge of one
+	 * component and the edge of its parent component. */
+	static final int vexternal = 0;
+	
+	/**
+	 * Gets a <code>String</code> composed of a number of instances of
+	 * character <code>c</code> equal to <code>number</code>.
+	 * @param c - The character to repeat.
+	 * @param number - The number of repetitions.
+	 * @return Returns the repeated character as a <code>String</code>.
+	 */
+	public static final String getChars(char c, int number) {
+		// Create a buffer to store the characters in.
+		StringBuffer s = new StringBuffer();
+		
+		// Add the indicated number of instances.
+		for(int i = 0; i < number; i++) {
+			s.append(c);
+		}
+		
+		// Return the string.
+		return s.toString();
+	}
+	
+	/**
+	 * Gets the number of digits in the base-10 String representation
+	 * of an integer primitive. Negative signs are not included in the
+	 * digit count.
+	 * @param value - The value of which to obtain the length.
+	 * @return Returns the number of digits in the String representation
+	 * of the argument value.
+	 */
+	public static final int getDigits(int value) {
+		return TriggerDiagnosticUtil.getDigits(value);
+	}
+	
+	/**
+	 * Gets the maximum value from a list of values.
+	 * @param values - The values to compare.
+	 * @return Returns the largest of the argument values.
+	 * @throws IllegalArgumentException Occurs if no values are given.
+	 */
+	public static final int max(int... values) throws IllegalArgumentException {
+		// Throw an error if no arguments are provided.
+		if(values == null || values.length == 0) {
+			throw new IllegalArgumentException("Can not determine maximum value from a list of 0 values.");
+		}
+		
+		// If there is only one value, return it.
+		if(values.length == 1) { return values[0]; }
+		
+		// Otherwise, get the largest value.
+		int largest = Integer.MIN_VALUE;
+		for(int value : values) {
+			if(value > largest) { largest = value; }
+		}
+		
+		// Return the result.
+		return largest;
+	}
+	
+	/**
+	 * Gets the x-coordinate immediately to the right of the given
+	 * component.
+	 * @param c - The component of which to find the edge.
+	 * @return Returns the x-coordinate as an <code>int</code> value.
+	 */
+	static final int getNextX(Component c) {
+		return getNextX(c, 0);
+	}
+	
+	/**
+	 * Gets the x-coordinate a given distance to the right edge of the
+	 * argument component.
+	 * @param c - The component of which to find the edge.
+	 * @param spacing - The additional spacing past the edge of the
+	 * component to add.
+	 * @return Returns the x-coordinate as an <code>int</code> value.
+	 */
+	static final int getNextX(Component c, int spacing) {
+		return c.getX() + c.getWidth() + spacing;
+	}
+	
+	/**
+	 * Gets the y-coordinate immediately below the given component.
+	 * @param c - The component of which to find the edge.
+	 * @return Returns the y-coordinate as an <code>int</code> value.
+	 */
+	static final int getNextY(Component c) {
+		return getNextY(c, 0);
+	}
+	
+	/**
+	 * Gets the y-coordinate a given distance below the bottom edge
+	 * of the argument component.
+	 * @param c - The component of which to find the edge.
+	 * @param spacing - The additional spacing past the edge of the
+	 * component to add.
+	 * @return Returns the y-coordinate as an <code>int</code> value.
+	 */
+	static final int getNextY(Component c, int spacing) {
+		return c.getY() + c.getHeight() + spacing;
+	}
+}

Added: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/DiagnosticUpdatable.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/DiagnosticUpdatable.java	(added)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/DiagnosticUpdatable.java	Thu Mar  5 13:46:25 2015
@@ -0,0 +1,22 @@
+package org.hps.monitoring.trigger;
+
+import org.hps.analysis.trigger.DiagSnapshot;
+
+/**
+ * Interface <code>DiagnosticUpdatable</code> defines a class of objects
+ * that can be updated with information from a trigger diagnostic driver.
+ * They can take snapshots of the driver results and use this in order to
+ * alter their displayed or constituent values.
+ * 
+ * @author Kyle McCarty <[log in to unmask]>
+ * @see DiagSnapshot
+ */
+public interface DiagnosticUpdatable {
+	/**
+	 * Updates the object with information from the trigger diagnostic
+	 * snapshot in the argument.
+	 * @param snapshot - The snapshot containing information with which
+	 * to update the object.
+	 */
+	public void updatePanel(DiagSnapshot snapshot);
+}

Added: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/EfficiencyTablePanel.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/EfficiencyTablePanel.java	(added)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/EfficiencyTablePanel.java	Thu Mar  5 13:46:25 2015
@@ -0,0 +1,116 @@
+package org.hps.monitoring.trigger;
+
+import javax.swing.JTable;
+
+import org.hps.analysis.trigger.DiagSnapshot;
+import org.hps.analysis.trigger.event.TriggerEfficiencyModule;
+import org.hps.analysis.trigger.util.ComponentUtils;
+import org.hps.analysis.trigger.util.TriggerDiagnosticUtil;
+
+public class EfficiencyTablePanel extends AbstractTablePanel implements DiagnosticUpdatable {
+	// Static variables.
+	private static final long serialVersionUID = 0L;
+	
+	// Table models.
+	private TableTextModel localModel;
+	private TableTextModel globalModel;
+	
+	/**
+	 * Instantiates a new <code>EfficiencyTablePanel</code>.
+	 */
+	public EfficiencyTablePanel() {
+		// Instantiate the superclass.
+		super();
+		
+		// Set the orientation to vertical.
+		setOrientation(ORIENTATION_VERTICAL);
+	}
+	
+	@Override
+	public void updatePanel(DiagSnapshot snapshot) {
+		// If there is no snapshot, the tables should all display an
+		// empty value.
+		if(snapshot == null) {
+			for(int eventTriggerID = 0; eventTriggerID < 6; eventTriggerID++) {
+				for(int seenTriggerID = 0; seenTriggerID < 6; seenTriggerID++) {
+					localModel.setValueAt("--- / ---", eventTriggerID + 1, seenTriggerID + 1);
+					globalModel.setValueAt("--- / ---", eventTriggerID + 1, seenTriggerID + 1);
+				}
+			}
+		}
+		
+		// Otherwise, update the table cells from the snapshot data.
+		else {
+		// Get the efficiency modules.
+			TriggerEfficiencyModule rmod = snapshot.efficiencyRunStatistics;
+			TriggerEfficiencyModule lmod = snapshot.efficiencyLocalStatistics;
+			
+			// Determine the spacing needed to display the largest numerical
+			// cell value.
+			int numWidth = -1;
+			for(int eventTriggerID = 0; eventTriggerID < 6; eventTriggerID++) {
+				for(int seenTriggerID = 0; seenTriggerID < 6; seenTriggerID++) {
+					int rSize = ComponentUtils.getDigits(rmod.getTriggersSeen(eventTriggerID, seenTriggerID));
+					int lSize = ComponentUtils.getDigits(lmod.getTriggersSeen(eventTriggerID, seenTriggerID));
+					numWidth = ComponentUtils.max(numWidth, rSize, lSize);
+				}
+			}
+			
+			// Generate the format string for the cells.
+			String nullText = String.format("%s / %s", ComponentUtils.getChars('-', numWidth),
+					ComponentUtils.getChars('-', numWidth));
+			String format = "%" + numWidth + "d / %" + numWidth + "d";
+			
+			// Update the table.
+			for(int eventTriggerID = 0; eventTriggerID < 6; eventTriggerID++) {
+				for(int seenTriggerID = 0; seenTriggerID < 6; seenTriggerID++) {
+					if(eventTriggerID == seenTriggerID) {
+						localModel.setValueAt(nullText, eventTriggerID + 1, seenTriggerID + 1);
+					} else {
+						localModel.setValueAt(String.format(format, lmod.getTriggersMatched(eventTriggerID, seenTriggerID),
+								lmod.getTriggersSeen(eventTriggerID, seenTriggerID)), eventTriggerID + 1, seenTriggerID + 1);
+						globalModel.setValueAt(String.format(format, rmod.getTriggersMatched(eventTriggerID, seenTriggerID),
+								rmod.getTriggersSeen(eventTriggerID, seenTriggerID)), eventTriggerID + 1, seenTriggerID + 1);
+					}
+				}
+			}
+		}
+	}
+	
+	@Override
+	protected JTable[] initializeTables(Object... args) {
+		// Get a shorter reference to the trigger name list.
+		String[] triggerNames = TriggerDiagnosticUtil.TRIGGER_NAME;
+		
+		// Initialize the table models. There should be one row and
+		// one column for each type of trigger plus an additional one
+		// of each for headers.
+		localModel = new TableTextModel(triggerNames.length + 1, triggerNames.length + 1);
+		globalModel = new TableTextModel(triggerNames.length + 1, triggerNames.length + 1);
+		
+		// Set the column and row headers.
+		for(int triggerType = 0; triggerType < triggerNames.length; triggerType++) {
+			localModel.setValueAt(triggerNames[triggerType], triggerType + 1, 0);
+			localModel.setValueAt(triggerNames[triggerType], 0, triggerType + 1);
+			globalModel.setValueAt(triggerNames[triggerType], triggerType + 1, 0);
+			globalModel.setValueAt(triggerNames[triggerType], 0, triggerType + 1);
+		}
+		
+		// Create JTable objects to display the data.
+		JTable localTable = new JTable(localModel);
+		localTable.setRowSelectionAllowed(false);
+		localTable.setColumnSelectionAllowed(false);
+		localTable.setCellSelectionEnabled(false);
+		localTable.setShowVerticalLines(false);
+		
+		JTable globalTable = new JTable(globalModel);
+		globalTable.setRowSelectionAllowed(false);
+		globalTable.setColumnSelectionAllowed(false);
+		globalTable.setCellSelectionEnabled(false);
+		globalTable.setShowVerticalLines(false);
+		
+		// Return the tables.
+		return new JTable[] { localTable, globalTable };
+	}
+	
+}

Added: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/PairTablePanel.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/PairTablePanel.java	(added)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/PairTablePanel.java	Thu Mar  5 13:46:25 2015
@@ -0,0 +1,33 @@
+package org.hps.monitoring.trigger;
+
+import org.hps.analysis.trigger.DiagSnapshot;
+import org.hps.analysis.trigger.event.TriggerStatModule;
+
+/**
+ * Class <code>PairTablePanel</code> displays statistical information
+ * for trigger pair cuts.
+ * 
+ * @author Kyle McCarty
+ */
+public class PairTablePanel extends AbstractTriggerTablePanel {
+	// Static variables.
+	private static final long serialVersionUID = 0L;
+	private static final String[] CUT_NAMES = { "        Energy Sum:",
+		"        Energy Difference:", "        Energy Slope:", "        Coplanarity:" };
+	
+	/**
+	 * Instantiates a <code>PairTablePanel</code>.
+	 */
+	public PairTablePanel() { super(CUT_NAMES); }
+
+	@Override
+	protected TriggerStatModule getLocalModule(DiagSnapshot snapshot) {
+		return snapshot.pairLocalStatistics;
+	}
+
+	@Override
+	protected TriggerStatModule getRunModule(DiagSnapshot snapshot) {
+		return snapshot.pairRunStatistics;
+	}
+	
+}

Added: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/SinglesTablePanel.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/SinglesTablePanel.java	(added)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/SinglesTablePanel.java	Thu Mar  5 13:46:25 2015
@@ -0,0 +1,33 @@
+package org.hps.monitoring.trigger;
+
+import org.hps.analysis.trigger.DiagSnapshot;
+import org.hps.analysis.trigger.event.TriggerStatModule;
+
+/**
+ * Class <code>SinglesTablePanel</code> displays statistical information
+ * for trigger singles cuts.
+ * 
+ * @author Kyle McCarty
+ */
+public class SinglesTablePanel extends AbstractTriggerTablePanel {
+	// Static variables.
+	private static final long serialVersionUID = 0L;
+	private static final String[] CUT_NAMES = { "        Cluster Energy (Low):",
+		"        Cluster Energy (High):", "        Hit Count:"  };
+	
+	/**
+	 * Instantiates a <code>SinglesTablePanel</code>.
+	 */
+	public SinglesTablePanel() { super(CUT_NAMES); }
+	
+	@Override
+	protected TriggerStatModule getLocalModule(DiagSnapshot snapshot) {
+		return snapshot.singlesLocalStatistics;
+	}
+	
+	@Override
+	protected TriggerStatModule getRunModule(DiagSnapshot snapshot) {
+		return snapshot.singlesRunStatistics;
+	}
+	
+}

Added: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/TableTextModel.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/TableTextModel.java	(added)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/TableTextModel.java	Thu Mar  5 13:46:25 2015
@@ -0,0 +1,103 @@
+package org.hps.monitoring.trigger;
+
+import javax.swing.table.AbstractTableModel;
+
+/**
+ * Class <code>TableTextModel</code> is a simple implementation of
+ * <code>AbstractTableModel</code> that supports a definable number
+ * of rows and columns which must be populated with <code>String</code>
+ * data.
+ * 
+ * @author Kyle McCarty <[log in to unmask]>
+ */
+public class TableTextModel extends AbstractTableModel {
+	// Serial UID.
+	private static final long serialVersionUID = 0L;
+	
+	// Stored values.
+	private final int rows, columns;
+	private final String[][] values;
+	
+	/**
+	 * Instantiates a new <code>TableTextModel</code> with the indicated
+	 * number of rows and columns.
+	 * @param rows - The number of rows.
+	 * @param columns - The number of columns.
+	 */
+	public TableTextModel(int rows, int columns) {
+		// Make sure that the arguments for rows and columns are valid.
+		if(rows < 1) {
+			throw new IllegalArgumentException("TableTextModel must have at least one row.");
+		} else 	if(columns < 1) {
+			throw new IllegalArgumentException("TableTextModel must have at least one column.");
+		}
+		
+		// Define the number of rows and columns.
+		this.rows = rows;
+		this.columns = columns;
+		
+		// Instantiate the data storage array.
+		values = new String[rows][columns];
+	}
+	
+	@Override
+	public int getRowCount() { return rows; }
+	
+	@Override
+	public int getColumnCount() { return columns; }
+	
+	@Override
+	public Object getValueAt(int rowIndex, int columnIndex) {
+		// Ensure that the value is within the allowed range.
+		validateIndex(rowIndex, columnIndex);
+		
+		// Return the value.
+		return values[rowIndex][columnIndex];
+	}
+	
+	@Override
+	public void setValueAt(Object value, int rowIndex, int columnIndex) {
+		// If the object is a string, pass it to the preferred handler.
+		// This can also be performed if the value is null.
+		if(value == null || value instanceof String) {
+			setValueAt((String) value, rowIndex, columnIndex);
+		}
+		
+		// Otherwise, cast the object to a string and use that instead.
+		else { setValueAt(value.toString(), rowIndex, columnIndex); }
+	}
+	
+	/**
+	 * Sets the text for the indicated column and row of the table.
+	 * @param value - The new text.
+	 * @param rowIndex - The row.
+	 * @param columnIndex - The column.
+	 * @throws IndexOutOfBoundsException Occurs if the row and column
+	 * are not a valid member of table model.
+	 */
+	public void setValueAt(String value, int rowIndex, int columnIndex) throws IndexOutOfBoundsException {
+		// Ensure that the value is within the allowed range.
+		validateIndex(rowIndex, columnIndex);
+		
+		// Set the value.
+		values[rowIndex][columnIndex] = value;
+	}
+	
+	/**
+	 * Checks to make sure that a given row/column pointer refers to
+	 * an extant position in the data array. In the event that the row
+	 * and column values are not valid, an <code>IndexOutOfBounds</code>
+	 * exception is thrown.
+	 * @param rowIndex - The row index.
+	 * @param columnIndex - The column index.
+	 * @throws IndexOutOfBoundsException Occurs if the row and column
+	 * are not a valid member of the data array.
+	 */
+	private void validateIndex(int rowIndex, int columnIndex) throws IndexOutOfBoundsException {
+		if(rowIndex < 0 || rowIndex >= getRowCount()) {
+			throw new IndexOutOfBoundsException(String.format("Row index %d is out of bounds.", rowIndex));
+		} else if(columnIndex < 0 || columnIndex >= getColumnCount()) {
+			throw new IndexOutOfBoundsException(String.format("Column index %d is out of bounds.", columnIndex));
+		}
+	}
+}

Added: java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/TriggerDiagnosticGUIDriver.java
 =============================================================================
--- java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/TriggerDiagnosticGUIDriver.java	(added)
+++ java/trunk/monitoring-util/src/main/java/org/hps/monitoring/trigger/TriggerDiagnosticGUIDriver.java	Thu Mar  5 13:46:25 2015
@@ -0,0 +1,43 @@
+package org.hps.monitoring.trigger;
+
+import java.util.List;
+
+import javax.swing.JFrame;
+
+import org.hps.analysis.trigger.DiagSnapshot;
+import org.lcsim.event.EventHeader;
+import org.lcsim.util.Driver;
+
+public class TriggerDiagnosticGUIDriver extends Driver {
+	private JFrame window = new JFrame();
+	private ClusterTablePanel clusterTable = new ClusterTablePanel();
+	private String diagnosticCollectionName = "DiagnosticSnapshot";
+	
+	@Override
+	public void startOfData() {
+		window.add(clusterTable);
+		window.setVisible(true);
+		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		window.setSize(500, 400);
+	}
+	
+	@Override
+	public void process(EventHeader event) {
+		// Updates are only performed if a diagnostic snapshot object
+		// exists. Otherwise, do nothing.
+		if(event.hasCollection(DiagSnapshot.class, 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);
+			
+			// Feed it to the table.
+			clusterTable.updatePanel(snapshot);
+		}
+	}
+	
+	public void setDiagnosticCollectionName(String name) {
+		diagnosticCollectionName = name;
+	}
+}

Top of Message | Previous Page | Permalink

Advanced Options


Options

Log In

Log In

Get Password

Get Password


Search Archives

Search Archives


Subscribe or Unsubscribe

Subscribe or Unsubscribe


Archives

November 2017
August 2017
July 2017
January 2017
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
December 2013
November 2013

ATOM RSS1 RSS2



LISTSERV.SLAC.STANFORD.EDU

Secured by F-Secure Anti-Virus CataList Email List Search Powered by the LISTSERV Email List Manager

Privacy Notice, Security Notice and Terms of Use