Author: [log in to unmask]
Date: Sun Mar 15 11:31:15 2015
New Revision: 2459
Log:
Merge changes from monitoring dev branch into trunk.
Added:
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java
- copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConditionsCollectionTableModel.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConditionsPanel.java
- copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/ConditionsPanel.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventDashboard.java
- copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/EventDashboard.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusEventsTable.java
- copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusEventsTable.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusPanel.java
- copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/SystemStatusPanel.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/EtEventFilter.java
- copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/EtEventFilter.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/MonitoringApplicationEventBuilder.java
- copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/MonitoringApplicationEventBuilder.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/PhysicsSyncEventStation.java
- copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/PhysicsSyncEventStation.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/PreStartEtStation.java
- copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/PreStartEtStation.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/util/RunnableEtStation.java
- copied unchanged from r2457, java/branches/monitoring-app-dev/src/main/java/org/hps/monitoring/application/util/RunnableEtStation.java
Removed:
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/RunPanel.java
Modified:
java/trunk/monitoring-app/ (props changed)
java/trunk/monitoring-app/pom.xml
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotPanel.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusTable.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java
java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/RunModel.java
java/trunk/monitoring-app/src/main/resources/org/hps/monitoring/config/default_config.prop
Modified: java/trunk/monitoring-app/pom.xml
=============================================================================
--- java/trunk/monitoring-app/pom.xml (original)
+++ java/trunk/monitoring-app/pom.xml Sun Mar 15 11:31:15 2015
@@ -111,6 +111,10 @@
</dependency>
<dependency>
<groupId>org.hps</groupId>
+ <artifactId>hps-ecal-recon</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hps</groupId>
<artifactId>hps-monitoring-drivers</artifactId>
</dependency>
<dependency>
@@ -134,6 +138,16 @@
<groupId>org.freehep</groupId>
<artifactId>freehep-jaida-remote</artifactId>
<version>3.4.11</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.jdom</groupId>
+ <artifactId>jdom</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-math</groupId>
+ <artifactId>commons-math</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
</dependencies>
-</project>
+</project>
Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java
=============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java (original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/Commands.java Sun Mar 15 11:31:15 2015
@@ -34,9 +34,10 @@
// Save a screenshot
static final String SAVE_SCREENSHOT = "saveScreenshot";
- // Save the plots
+ // 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";
Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java
=============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java (original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/ConnectionStatusPanel.java Sun Mar 15 11:31:15 2015
@@ -45,7 +45,6 @@
setMinimumSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
setLayout(new GridBagLayout());
- // setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
GridBagConstraints c = new GridBagConstraints();
c.weightx = c.weighty = 1.0;
Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java
=============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java (original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventButtonsPanel.java Sun Mar 15 11:31:15 2015
@@ -80,10 +80,19 @@
resumeButton.setEnabled(false);
connectButton.setActionCommand(Commands.CONNECT);
connectButton.setIcon(disconnectedIcon);
- } else {
+ connectButton.setEnabled(true);
+ } else if (status.equals(ConnectionStatus.DISCONNECTING)) {
+ nextButton.setEnabled(false);
+ pauseButton.setEnabled(false);
+ resumeButton.setEnabled(false);
+ 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.setEnabled(true);
}
}
Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java
=============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java (original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/EventProcessing.java Sun Mar 15 11:31:15 2015
@@ -4,6 +4,7 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
@@ -14,6 +15,9 @@
import org.hps.monitoring.application.model.ConnectionStatus;
import org.hps.monitoring.application.model.SteeringType;
import org.hps.monitoring.application.util.EtSystemUtil;
+import org.hps.monitoring.application.util.PhysicsSyncEventStation;
+import org.hps.monitoring.application.util.PreStartEtStation;
+import org.hps.monitoring.application.util.RunnableEtStation;
import org.hps.monitoring.subsys.et.EtSystemMonitor;
import org.hps.monitoring.subsys.et.EtSystemStripCharts;
import org.hps.record.LCSimEventBuilder;
@@ -24,26 +28,30 @@
import org.hps.record.enums.DataSourceType;
import org.hps.record.et.EtConnection;
import org.hps.record.evio.EvioDetectorConditionsProcessor;
+import org.jlab.coda.et.EtSystem;
import org.jlab.coda.et.exception.EtClosedException;
import org.jlab.coda.et.exception.EtException;
+import org.lcsim.conditions.ConditionsListener;
import org.lcsim.conditions.ConditionsManager;
import org.lcsim.conditions.ConditionsReader;
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.
+ * 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]>
*/
class EventProcessing {
-
+
MonitoringApplication application;
Logger logger;
SessionState sessionState;
List<CompositeRecordProcessor> processors;
List<Driver> drivers;
-
+ List<ConditionsListener> conditionsListeners;
+ int stationPosition;
+
/**
* This class is used to organize the objects for an event processing session.
*/
@@ -53,33 +61,54 @@
CompositeLoop loop;
EventProcessingThread processingThread;
Thread sessionWatchdogThread;
+ ThreadGroup stationThreadGroup = new ThreadGroup("Station Threads");
+ List<RunnableEtStation> stations = new ArrayList<RunnableEtStation>();
EtConnection connection;
}
-
- /**
- * Initialize with reference to the current monitoring application
- * and a list of extra processors to add to the loop after
- * configuration.
+
+ /**
+ * 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<CompositeRecordProcessor> processors,
+ List<Driver> drivers,
+ List<ConditionsListener> conditionsListeners) {
this.application = application;
- this.sessionState = new SessionState();
+ this.sessionState = new SessionState();
this.logger = MonitoringApplication.logger;
this.processors = processors;
this.drivers = drivers;
+ this.conditionsListeners = conditionsListeners;
+ this.stationPosition = application.configurationModel.getStationPosition();
}
+ int getNextStationPosition() {
+ this.stationPosition += 1;
+ return this.stationPosition;
+ }
+
/**
* Setup this class from the global configuration.
* @param configurationModel The global configuration.
*/
void setup(ConfigurationModel configurationModel) {
- MonitoringApplication.logger.info("setting up LCSim");
+
+ // Setup LCSim from the configuration.
+ setupLcsim(configurationModel);
+
+ // Now setup the CompositeLoop.
+ setupLoop(configurationModel);
+ }
+
+ /**
+ * @param configurationModel
+ */
+ private void setupLcsim(ConfigurationModel configurationModel) {
+ MonitoringApplication.logger.info("setting up lcsim");
// Get steering resource or file as a String parameter.
String steering = null;
@@ -90,22 +119,31 @@
steering = configurationModel.getSteeringResource();
}
- MonitoringApplication.logger.config("Set steering to " + steering + " with type " + (steeringType == SteeringType.RESOURCE ? "RESOURCE" : "FILE"));
+ MonitoringApplication.logger.config("set steering " + steering + " with type " + (steeringType == SteeringType.RESOURCE ? "RESOURCE" : "FILE"));
try {
- // Create and the job manager. The conditions manager is instantiated from this call but not configured.
+ // Create and the job manager. The conditions manager is instantiated from this call but
+ // not configured.
sessionState.jobManager = new JobManager();
-
+
+ // Add conditions listeners after new database conditions manager is initialized from
+ // job manager.
+ DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
+ for (ConditionsListener conditionsListener : conditionsListeners) {
+ logger.config("adding conditions listener " + conditionsListener.getClass().getName());
+ conditionsManager.addConditionsListener(conditionsListener);
+ }
+
if (configurationModel.hasValidProperty(ConfigurationModel.DETECTOR_ALIAS_PROPERTY)) {
- // Set a detector alias.
+ // Set a detector alias.
ConditionsReader.addAlias(configurationModel.getDetectorName(), "file://" + configurationModel.getDetectorAlias());
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);
-
+
// Configure the job manager for the XML steering.
sessionState.jobManager.setPerformDryRun(true);
if (steeringType == SteeringType.RESOURCE) {
@@ -113,24 +151,23 @@
} 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());
+ logger.config("conditions tag is set to " + configurationModel.getConditionsTag());
} else {
logger.config("conditions NOT using a tag");
}
-
+
// Is there a user specified run number from the JobPanel?
if (configurationModel.hasValidProperty(ConfigurationModel.USER_RUN_NUMBER_PROPERTY)) {
int userRunNumber = configurationModel.getUserRunNumber();
String detectorName = configurationModel.getDetectorName();
- DatabaseConditionsManager conditionsManager = DatabaseConditionsManager.getInstance();
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 from monitoring app");
+ // Freeze the conditions system to ignore run numbers from the events.
+ logger.config("user configured to freeze conditions system");
conditionsManager.freeze();
} else {
// Allow run numbers to be picked up from the events.
@@ -142,18 +179,15 @@
logger.info("lcsim setup was successful");
} catch (Throwable t) {
- // Catch all errors and rethrow them as RuntimeExceptions.
+ // Catch all errors and re-throw them as RuntimeExceptions.
application.errorHandler.setError(t).setMessage("Error setting up LCSim.").printStackTrace().raiseException();
}
-
- // Now setup the CompositeLoop.
- setupLoop(configurationModel);
- }
-
+ }
+
/**
* Create the event builder for converting EVIO events to LCSim.
*/
- void createEventBuilder(ConfigurationModel configurationModel) {
+ private void createEventBuilder(ConfigurationModel configurationModel) {
// Get the class for the event builder.
String eventBuilderClassName = configurationModel.getEventBuilderClassName();
@@ -168,12 +202,12 @@
// 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) {
+ private void setupLoop(ConfigurationModel configurationModel) {
CompositeLoopConfiguration loopConfig = new CompositeLoopConfiguration()
.setStopOnEndRun(configurationModel.getDisconnectOnEndRun())
@@ -187,13 +221,12 @@
if (configurationModel.hasValidProperty(ConfigurationModel.MAX_EVENTS_PROPERTY)) {
long maxEvents = configurationModel.getMaxEvents();
if (maxEvents > 0L) {
- //logger.config("processing will stop after max events: " + maxEvents);
loopConfig.setMaxRecords(maxEvents);
}
}
-
+
// Add all Drivers from the JobManager.
- for (Driver driver : sessionState.jobManager.getDriverExecList()) {
+ for (Driver driver : sessionState.jobManager.getDriverExecList()) {
loopConfig.add(driver);
logger.config("added Driver " + driver.getName() + " to job");
}
@@ -211,30 +244,30 @@
}
// Add extra CompositeRecordProcessors to the loop config.
- for (CompositeRecordProcessor processor : processors) {
- loopConfig.add(processor);
+ for (CompositeRecordProcessor processor : processors) {
+ loopConfig.add(processor);
logger.config("added extra processor " + processor.getClass().getSimpleName() + " to job");
}
-
+
// Add extra Drivers to the loop config.
- for (Driver driver : drivers) {
+ for (Driver driver : drivers) {
loopConfig.add(driver);
logger.config("added extra Driver " + driver.getName() + " to job");
}
-
- // Enable conditions system activation from EVIO event information.
+
+ // Enable conditions system activation from EVIO event data in case the PRESTART is missed.
logger.config("added EvioDetectorConditionsProcessor to job with detector " + configurationModel.getDetectorName());
loopConfig.add(new EvioDetectorConditionsProcessor(configurationModel.getDetectorName()));
// Create the CompositeLoop with the configuration.
- sessionState.loop = new CompositeLoop(loopConfig);
- }
-
+ sessionState.loop = new CompositeLoop(loopConfig);
+ }
+
/**
* Setup a steering file on disk.
* @param steering The steering file.
*/
- void setupSteeringFile(String steering) {
+ private void setupSteeringFile(String steering) {
sessionState.jobManager.setup(new File(steering));
}
@@ -243,83 +276,121 @@
* @param steering The steering resource.
* @throws IOException if there is a problem setting up or accessing the resource.
*/
- void setupSteeringResource(String steering) throws IOException {
+ private void setupSteeringResource(String steering) throws IOException {
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);
is.close();
}
+
+ synchronized void stop() {
+
+ // Kill session watchdog thread.
+ killWatchdogThread();
+
+ // Wake up all ET stations to unblock the system and make sure secondary stations are detached.
+ wakeUpEtStations();
- synchronized void stop() {
-
- // Kill session watchdog thread.
- logger.fine("killing watchdog thread ...");
- killWatchdogThread();
- logger.fine("watchdog thread killed");
-
- // Wake up ET system in case it is blocked in a getEvents() call.
- if (sessionState.connection != null) {
- try {
- logger.fine("waking up ET stations ...");
- sessionState.connection.getEtSystem().wakeUpAll(sessionState.connection.getEtStation());
- logger.fine("ET stations woken up");
- } catch (IOException | EtException | EtClosedException e) {
- e.printStackTrace();
- }
- }
-
- // Stop event processing.
- logger.fine("commanding event processing to stop ...");
+ // Stop the event processing now that ET system is unblocked.
+ logger.fine("sending STOP command to loop ...");
sessionState.loop.execute(Command.STOP);
- logger.fine("event processing commanded to stop");
-
- // Cleanup the event processing thread.
+ logger.fine("loop got command STOP");
+
+ // Cleanup the event processing thread since it was told to stop now.
try {
- logger.fine("joining on event processing thread ...");
+ logger.fine("waiting for event processing thread to end ...");
sessionState.processingThread.join();
- logger.fine("event processing thread joined");
-
- // Invalidate event processing thread.
- sessionState.processingThread = null;
+ logger.fine("event processing thread ended");
} catch (InterruptedException e) {
e.printStackTrace();
}
-
+
// Notify of last error that occurred in event processing.
if (sessionState.loop.getLastError() != null) {
// Log the error.
application.errorHandler.setError(sessionState.loop.getLastError()).log();
}
+
+ // Invalidate the loop.
+ sessionState.loop = null;
+
+ // Disconnect from the ET system.
+ disconnect();
- // Invalidate loop.
- sessionState.loop = null;
-
- // Disconnect from the ET system.
- logger.fine("disconnecting from ET system ...");
- disconnect();
- logger.fine("ET system disconnected");
- }
-
- /**
- * Start event processing on the event processing thread
- * and start the watchdog thread.
+ // Invalidate the event processing object so it is unusable now.
+ invalidate();
+ }
+
+ /**
+ * Wake up all ET stations associated with event processing.
+ */
+ private void wakeUpEtStations() {
+ if (sessionState.connection != null) {
+ logger.fine("waking up ET stations ...");
+
+ // Wake up secondary ET stations.
+ for (RunnableEtStation station : sessionState.stations) {
+ if (station.getEtStation().isUsable()) {
+ // Wake up the station which will automatically trigger a detach.
+ try {
+ logger.finest("waking up " + station.getEtStation().getName() + " ...");
+ sessionState.connection.getEtSystem().wakeUpAll(station.getEtStation());
+ logger.finest(station.getEtStation().getName() + " woken up");
+ } catch (IOException | EtException | EtClosedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ // 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();
+ synchronized (lock) {
+ try {
+ lock.wait(500);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ logger.finest("destroying station thread group");
+ sessionState.stationThreadGroup.destroy();
+ logger.finest("station thread group destroyed");
+
+ // Wake up the primary ET station doing the event processing.
+ logger.finest("waking up event processing station ...");
+ try {
+ sessionState.connection.getEtSystem().wakeUpAll(sessionState.connection.getEtStation());
+ logger.finest("event processing station woken up");
+ } catch (IOException | EtException | EtClosedException e) {
+ e.printStackTrace();
+ }
+
+ logger.finest("ET stations 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 watchdog 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.
*/
@@ -331,7 +402,7 @@
}
logger.finest("paused");
}
-
+
/**
* Get next event if in pause mode.
*/
@@ -344,7 +415,7 @@
}
logger.finest("got next event");
}
-
+
/**
* Resume processing events from pause mode.
*/
@@ -352,19 +423,19 @@
logger.finest("resuming");
if (application.connectionModel.getPaused()) {
// Notify event processor to continue.
- sessionState.loop.resume();
+ sessionState.loop.resume();
application.connectionModel.setPaused(false);
}
logger.finest("resumed");
}
-
+
/**
* Interrupt and join to the processing watchdog thread.
*/
synchronized void killWatchdogThread() {
- logger.fine("killing watchdog thread");
// 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.
@@ -379,10 +450,10 @@
}
// Set the thread object to null.
sessionState.sessionWatchdogThread = null;
- }
- logger.fine("watchdog thread killed");
- }
-
+ logger.finest("watchdog thread killed");
+ }
+ }
+
/**
* Cleanup the ET connection.
*/
@@ -390,15 +461,15 @@
if (sessionState.connection != null) {
logger.fine("closing ET connection");
if (sessionState.connection.getEtSystem().alive()) {
- logger.fine("cleaning up the connection ...");
+ logger.finest("cleaning up the connection ...");
sessionState.connection.cleanup();
- logger.fine("connection cleanup successful");
+ logger.finest("connection cleanup successful");
}
sessionState.connection = null;
logger.fine("ET connection closed");
}
}
-
+
/**
* True if the processing thread is active.
* @return True if processing thread is active.
@@ -406,71 +477,109 @@
boolean isActive() {
return sessionState.processingThread != null && sessionState.processingThread.isAlive();
}
-
+
/**
* Connect to the ET system using the current connection settings.
*/
- synchronized void connect() throws IOException {
- logger.fine("connecting to ET system");
+ 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.
+ createPhysicsSyncStation();
+
+ // 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.
application.connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED);
}
- logger.fine("ET system is connected");
- }
-
+
+ }
+
/**
* True if using an ET server.
* @return True if using an ET server.
*/
boolean usingEtServer() {
return application.configurationModel.getDataSourceType().equals(DataSourceType.ET_SERVER);
- }
-
- /**
- * Create a connection to an ET system using current parameters from the GUI. If successful, the
- * application's ConnectionStatus is changed to CONNECTED.
- */
- void createEtConnection() {
+ }
+
+ /**
+ * 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(application.configurationModel);
if (sessionState.connection != null) {
// Set status to connected as there is now a live ET connection.
application.connectionModel.setConnectionStatus(ConnectionStatus.CONNECTED);
- //logger.info("successfully connected to ET system");
} else {
application.errorHandler.setError(new RuntimeException("Failed to create ET connection.")).log().printStackTrace().raiseException();
}
}
+
+ /**
+ * Create the ET that listens for DAQ configuration change via SYNC events.
+ */
+ private void createPhysicsSyncStation() {
+ logger.fine("creating physics SYNC station ...");
+ PhysicsSyncEventStation configStation = new PhysicsSyncEventStation(
+ this.sessionState.connection.getEtSystem(),
+ this.sessionState.connection.getEtStation().getName() + "_PhysicsSync",
+ getNextStationPosition());
+ sessionState.stations.add(configStation);
+ new Thread(sessionState.stationThreadGroup, configStation).start();
+ logger.fine("physics SYNC station created");
+ }
/**
- * Disconnect from the current ET session with a particular status.
+ * Create the ET station that listens for GO events in order to initialize the conditions system.
+ */
+ private void createPreStartStation() {
+ logger.fine("creating PRESTART station ...");
+ String detectorName = this.application.configurationModel.getDetectorName();
+ EtSystem system = this.sessionState.connection.getEtSystem();
+ String stationName = this.sessionState.connection.getEtStation().getName() + "_PreStart";
+ int order = getNextStationPosition();
+ PreStartEtStation preStartStation = new PreStartEtStation(
+ detectorName,
+ system,
+ stationName,
+ order);
+ sessionState.stations.add(preStartStation);
+ new Thread(sessionState.stationThreadGroup, preStartStation).start();
+ logger.fine("PRESTART station created");
+ }
+
+ /**
+ * Disconnect from the current ET session.
* @param status The connection status.
*/
synchronized void disconnect() {
-
- logger.fine("disconnecting");
// Cleanup the ET connection.
closeEtConnection();
-
+
// Change application state to disconnected.
application.connectionModel.setConnectionStatus(ConnectionStatus.DISCONNECTED);
-
- logger.fine("disconnected");
- }
-
- /**
- * This class notifies the application to disconnect if the event processing thread completes.
+ }
+
+ /**
+ * This class notifies the application to disconnect if the event processing thread completes.
*/
class SessionWatchdogThread extends Thread {
@@ -479,21 +588,39 @@
SessionWatchdogThread(Thread processingThread) {
this.processingThread = processingThread;
}
-
+
public void run() {
try {
- // When the event processing thread finishes, the session should be stopped and a
- // disconnect should occur.
+ // 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.fine("processing thread ended so automatic disconnect is happening");
+ logger.finest("processing thread ended so automatic disconnect is happening");
application.actionPerformed(new ActionEvent(Thread.currentThread(), 0, Commands.DISCONNECT));
-
+
} catch (InterruptedException e) {
- logger.fine("SessionWatchdogThread got interrupted");
+ logger.finest("SessionWatchdogThread got interrupted");
// This happens when the thread is interrupted by the user pressing the disconnect button.
- }
- }
+ }
+ }
+ }
+
+ void invalidate() {
+
+ this.application = null;
+ this.conditionsListeners = null;
+ this.drivers = null;
+ this.logger = null;
+ this.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;
}
}
Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java
=============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java (original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/LogLevelFilterComboBox.java Sun Mar 15 11:31:15 2015
@@ -13,7 +13,7 @@
import org.hps.monitoring.application.model.ConfigurationModel;
/**
- *
+ * This is a combo box used to filter the log table messages by level.
* @author Jeremy McCormick <[log in to unmask]>
*/
class LogLevelFilterComboBox extends JComboBox<Level> implements ActionListener, PropertyChangeListener {
Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java
=============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java (original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplication.java Sun Mar 15 11:31:15 2015
@@ -5,12 +5,10 @@
import hep.aida.jfree.plotter.PlotterRegionListener;
import hep.aida.ref.remote.rmi.client.RmiStoreFactory;
-import java.awt.Dimension;
-import java.awt.Rectangle;
-import java.awt.Robot;
-import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -40,6 +38,7 @@
import org.hps.monitoring.application.LogTable.LogRecordModel;
import org.hps.monitoring.application.model.Configuration;
import org.hps.monitoring.application.model.ConfigurationModel;
+import org.hps.monitoring.application.model.ConnectionStatus;
import org.hps.monitoring.application.model.ConnectionStatusModel;
import org.hps.monitoring.application.model.RunModel;
import org.hps.monitoring.application.util.AIDAServer;
@@ -49,12 +48,11 @@
import org.hps.monitoring.application.util.TableExporter;
import org.hps.monitoring.plotting.MonitoringAnalysisFactory;
import org.hps.monitoring.plotting.MonitoringPlotFactory;
-import org.hps.monitoring.subsys.StatusCode;
import org.hps.monitoring.subsys.SystemStatus;
-import org.hps.monitoring.subsys.SystemStatusListener;
import org.hps.monitoring.subsys.SystemStatusRegistry;
import org.hps.record.composite.CompositeRecordProcessor;
import org.hps.record.enums.DataSourceType;
+import org.lcsim.conditions.ConditionsListener;
import org.lcsim.util.Driver;
import org.lcsim.util.aida.AIDA;
import org.lcsim.util.log.DefaultLogFormatter;
@@ -62,12 +60,11 @@
/**
* 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 or via the supplied script built automatically
- * by Maven.
+ * used from the command line.
*
* @author Jeremy McCormick <[log in to unmask]>
*/
-final class MonitoringApplication implements ActionListener, PropertyChangeListener, SystemStatusListener {
+final class MonitoringApplication implements ActionListener, PropertyChangeListener {
// Statically initialize logging, which will be fully setup later.
static final Logger logger;
@@ -78,14 +75,15 @@
// Default log stream.
MonitoringApplicationStreamHandler streamHandler;
+ LogHandler logHandler;
PrintStream sysOut = System.out;
PrintStream sysErr = System.err;
// Application error handling.
- final ErrorHandler errorHandler;
+ ErrorHandler errorHandler;
// The main GUI components inside a JFrame.
- final MonitoringApplicationFrame frame;
+ MonitoringApplicationFrame frame;
// The primary data models.
final RunModel runModel = new RunModel();
@@ -150,41 +148,86 @@
super.setOutputStream(out);
}
}
-
+
/**
* Instantiate and show the monitoring application with the given configuration.
* @param configuration The Configuration object containing application settings.
*/
MonitoringApplication(Configuration configuration) {
-
- // Setup the main GUI component.
- frame = new MonitoringApplicationFrame(this);
-
- // Setup the error handler.
- errorHandler = new ErrorHandler(frame, logger);
+
+ try {
+
+ // Setup the main GUI component.
+ frame = new MonitoringApplicationFrame(this);
+
+ // Add window listener to perform clean shutdown.
+ frame.addWindowListener(new WindowListener() {
+
+ @Override
+ public void windowOpened(WindowEvent e) {
+ }
+
+ @Override
+ public void windowClosing(WindowEvent e) {
+ }
+
+ @Override
+ public void windowClosed(WindowEvent e) {
+ exit();
+ }
+
+ @Override
+ public void windowIconified(WindowEvent e) {
+ }
+
+ @Override
+ public void windowDeiconified(WindowEvent e) {
+ }
+
+ @Override
+ public void windowActivated(WindowEvent e) {
+ }
+
+ @Override
+ public void windowDeactivated(WindowEvent e) {
+ }
+ });
+
+ // Setup the error handler.
+ errorHandler = new ErrorHandler(frame, logger);
- // Add this class as a listener on the configuration model.
- configurationModel.addPropertyChangeListener(this);
-
- // Setup the logger.
- setupLogger();
+ // Add this class as a listener on the configuration model.
+ configurationModel.addPropertyChangeListener(this);
+
+ // Setup the logger.
+ setupLogger();
- // Setup AIDA plotting and connect it to the GUI.
- setupAida();
-
- // Set the configuration.
- if (configuration != null) {
- // There was a user specified configuration.
- this.configuration = configuration;
- } else {
- // Use the default configuration.
- this.configuration = new Configuration(DEFAULT_CONFIGURATION);
- }
+ // Setup AIDA plotting and connect it to the GUI.
+ setupAida();
+
+ // Set the configuration.
+ if (configuration != null) {
+ // There was a user specified configuration.
+ this.configuration = configuration;
+ } else {
+ // Use the default configuration.
+ this.configuration = new Configuration(DEFAULT_CONFIGURATION);
+ }
- // Load the configuration.
- loadConfiguration(this.configuration);
-
- logger.info("application initialized successfully");
+ // Load the configuration.
+ loadConfiguration(this.configuration);
+
+ frame.setEnabled(true);
+
+ logger.info("application initialized successfully");
+
+ } catch (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.");
+ e.printStackTrace();
+ System.exit(1);
+ }
}
/**
@@ -192,7 +235,8 @@
*/
void setupLogger() {
logger.setUseParentHandlers(false);
- logger.addHandler(new LogHandler());
+ logHandler = new LogHandler();
+ logger.addHandler(logHandler);
streamHandler = new MonitoringApplicationStreamHandler(System.out);
logger.addHandler(streamHandler);
for (Handler handler : logger.getHandlers()) {
@@ -201,7 +245,7 @@
logger.setLevel(DEFAULT_LEVEL);
logger.info("logging initialized");
}
-
+
/**
* Static utility method for creating new instance.
* @param configuration The application settings.
@@ -217,7 +261,9 @@
*/
@Override
public void propertyChange(PropertyChangeEvent evt) {
- // TODO: Handle log level configuration change here.
+ if (evt.getPropertyName().equals(ConfigurationModel.LOG_LEVEL_PROPERTY)) {
+ setLogLevel();
+ }
}
/**
@@ -232,11 +278,12 @@
if (Commands.CONNECT.equals(command)) {
startSession();
} else if (Commands.DISCONNECT.equals(command)) {
- processing.stop();
+ runDisconnectThread();
} else if (Commands.SAVE_PLOTS.equals(command)) {
savePlots();
} else if (Commands.EXIT.equals(command)) {
- exit();
+ // This will trigger the window closing action that cleans everything up.
+ frame.dispose();
} else if (Commands.PAUSE.equals(command)) {
processing.pause();
} else if (Commands.NEXT.equals(command)) {
@@ -265,8 +312,6 @@
closeFile();
} else if (Commands.SAVE_SCREENSHOT.equals(command)) {
saveScreenshot();
- } else if (Commands.LOG_LEVEL_CHANGED.equals(command)) {
- setLogLevel();
} else if (Commands.SAVE_LOG_TABLE.equals(command)) {
saveLogTable();
} else if (Commands.CLEAR_LOG_TABLE.equals(command)) {
@@ -327,11 +372,14 @@
* Reset the plots and clear the tabs in the plot window.
*/
void resetPlots() {
-
+
+ // Clear global list of registered plotters.
+ 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 tabs.
+ // Reset plot panel which removes all its tabs.
frame.plotPanel.reset();
logger.info("plots were cleared");
@@ -341,43 +389,20 @@
* Configure the system status monitor panel for a new job.
*/
void setupSystemStatusMonitor() {
+
// Clear the system status monitor table.
- frame.systemStatusTable.getTableModel().clear();
+ frame.systemStatusPanel.clear();
// Get the global registry of SystemStatus objects.
SystemStatusRegistry registry = SystemStatusRegistry.getSystemStatusRegistery();
// Process the SystemStatus objects.
for (SystemStatus systemStatus : registry.getSystemStatuses()) {
- // Add a row to the table for every SystemStatus.
- frame.systemStatusTable.getTableModel().addSystemStatus(systemStatus);
-
- // Add this class as a listener so all status changes can be logged.
- systemStatus.addListener(this);
+ // This will add the status to the two tables.
+ frame.systemStatusPanel.addSystemStatus(systemStatus);
}
logger.info("system status monitor initialized successfully");
- }
-
- /**
- * Hook for logging all status changes from the system status monitor.
- */
- @Override
- public void statusChanged(SystemStatus status) {
-
- // Choose the appropriate log level.
- Level level = Level.FINE;
- if (status.getStatusCode().equals(Level.WARNING)) {
- level = Level.WARNING;
- } else if (status.getStatusCode().ordinal() >= StatusCode.ERROR.ordinal()) {
- level = Level.SEVERE;
- }
-
- // Log all status changes.
- logger.log(level, "STATUS, " + "subsys: " + status.getSubsystem() + ", "
- + "code: " + status.getStatusCode().name()
- + ", " + "descr: " + status.getDescription()
- + ", " + "mesg: " + status.getMessage());
}
/**
@@ -399,13 +424,18 @@
// List of extra composite record processors including the updater for the RunPanel.
List<CompositeRecordProcessor> processors = new ArrayList<CompositeRecordProcessor>();
- processors.add(frame.runPanel.new RunPanelUpdater());
-
+ 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());
-
- // Initialize event processing with the list of processors and reference to the application.
- processing = new EventProcessing(this, processors, drivers);
+
+ // 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();
@@ -418,7 +448,7 @@
// Setup the system status monitor table.
setupSystemStatusMonitor();
- // Start the event processing thread.
+ // Start the event processing thread.
processing.start();
logger.info("new session successfully initialized");
@@ -437,17 +467,17 @@
}
/**
- * Exit from the application.
+ * Exit from the application from exit menu item or hitting close window button.
*/
void exit() {
- if (processing != null && processing.isActive()) {
+ if (connectionModel.isConnected()) {
processing.stop();
}
- frame.setVisible(false);
+ logHandler.setLevel(Level.OFF);
logger.info("exiting the application");
- logger.getHandlers()[0].flush();
+ streamHandler.flush();
System.exit(0);
- }
+ }
/**
* Save AIDA plots to a file using a file chooser.
@@ -601,6 +631,7 @@
/**
* Save a screenshot to a file using a file chooser.
*/
+ // FIXME: This might need to be on a new thread to allow the GUI to redraw w/o chooser visible.
void saveScreenshot() {
JFileChooser fc = new JFileChooser();
fc.setAcceptAllFileFilterUsed(false);
@@ -615,8 +646,17 @@
if (!fileName.endsWith("." + format)) {
fileName += "." + format;
}
+ frame.repaint();
+ Object lock = new Object();
+ synchronized (lock) {
+ try {
+ lock.wait(500);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
writeScreenshot(fileName, format);
- DialogUtil.showInfoDialog(frame, "Screenshot Saved", "Screenshot was saved to file.");
+ DialogUtil.showInfoDialog(frame, "Screenshot Saved", "Screenshot was saved to file" + '\n' + fileName);
logger.info("saved screenshot to " + fileName);
}
}
@@ -626,15 +666,13 @@
* @param fileName The name of the output file.
*/
void writeScreenshot(String fileName, String format) {
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- Rectangle screenRectangle = new Rectangle(screenSize);
+ BufferedImage image = new BufferedImage(frame.getWidth(), frame.getHeight(), BufferedImage.TYPE_INT_RGB);
+ frame.paint(image.getGraphics());
try {
- Robot robot = new Robot();
- BufferedImage image = robot.createScreenCapture(screenRectangle);
ImageIO.write(image, format, new File(fileName));
- } catch (Exception e) {
- errorHandler.setError(e).setMessage("Failed to take screenshot.").printStackTrace().log().showErrorDialog();
- }
+ } catch (IOException e) {
+ errorHandler.setError(e).setMessage("Failed to save screenshot.").printStackTrace().log().showErrorDialog();
+ }
}
/**
@@ -785,5 +823,19 @@
frame.menu.stopAIDAServer();
logger.info("AIDA server was stopped");
DialogUtil.showInfoDialog(frame, "AIDA Server Stopped", "The AIDA server was stopped.");
- }
+ }
+
+ /**
+ *
+ */
+ 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();
+ }
}
Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java
=============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java (original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/MonitoringApplicationFrame.java Sun Mar 15 11:31:15 2015
@@ -3,14 +3,11 @@
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
-import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
-import javax.swing.BoxLayout;
-import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
-import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
@@ -23,13 +20,14 @@
*/
class MonitoringApplicationFrame extends JFrame {
- RunPanel runPanel;
+ EventDashboard dashboardPanel;
PlotPanel plotPanel;
PlotInfoPanel plotInfoPanel;
LogPanel logPanel;
- SystemStatusTable systemStatusTable;
JPanel buttonsPanel;
TriggerDiagnosticsPanel triggerPanel;
+ ConditionsPanel conditionsPanel;
+ SystemStatusPanel systemStatusPanel;
MenuBar menu;
JSplitPane mainSplitPane;
@@ -39,14 +37,10 @@
DataSourceComboBox dataSourceComboBox;
SettingsDialog settingsDialog;
-
- // Proportional layout parameters relative to the screen size.
- static final double FULL_SIZE = 1.0;
- static final double TOP_PANEL_HEIGHT = 0.05;
- static final double BOTTOM_PANEL_HEIGHT = FULL_SIZE - TOP_PANEL_HEIGHT;
- static final double LEFT_PANEL_WIDTH = 0.3;
- static final double RIGHT_PANEL_WIDTH = FULL_SIZE - LEFT_PANEL_WIDTH;
- static final double PLOT_PANEL_HEIGHT = 0.8;
+
+ 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();
/**
*
@@ -54,20 +48,22 @@
*/
public MonitoringApplicationFrame(
MonitoringApplication application) {
+
+ // Disable interaction until specifically enabled externally after initialization.
+ setEnabled(false);
// Create the content panel.
JPanel contentPanel = new JPanel();
setContentPane(contentPanel);
- contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
+ contentPanel.setLayout(new BorderLayout());
contentPanel.setOpaque(true);
- setProportionalSize(contentPanel, FULL_SIZE, FULL_SIZE);
-
+ contentPanel.setPreferredSize(new Dimension(PIXEL_WIDTH_MAX, PIXEL_HEIGHT_MAX));
+
// Create the top panel.
JPanel topPanel = new JPanel();
topPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 0));
- setProportionalSize(topPanel, FULL_SIZE, TOP_PANEL_HEIGHT);
- contentPanel.add(topPanel);
-
+ contentPanel.add(topPanel, BorderLayout.NORTH);
+
// Create the connection status panel.
JPanel connectionPanel = new ConnectionStatusPanel(application.connectionModel);
topPanel.add(connectionPanel);
@@ -83,7 +79,6 @@
// Add vertical separator.
sep = new JSeparator(SwingConstants.VERTICAL);
- sep.setPreferredSize(new Dimension(5, topPanel.getPreferredSize().height));
topPanel.add(sep);
// Add the data source combo box.
@@ -93,16 +88,14 @@
// Create the bottom panel.
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BorderLayout());
- setProportionalSize(bottomPanel, FULL_SIZE, BOTTOM_PANEL_HEIGHT);
- contentPanel.add(bottomPanel);
-
+ contentPanel.add(bottomPanel, BorderLayout.CENTER);
+
// Create the left panel.
JPanel leftPanel = new JPanel();
leftPanel.setLayout(new BorderLayout());
- setProportionalSize(leftPanel, LEFT_PANEL_WIDTH, FULL_SIZE);
-
+
// Create the run dashboard.
- runPanel = new RunPanel(application.runModel);
+ dashboardPanel = new EventDashboard(application.runModel);
// Create the tabbed pane for content in bottom of left panel such as log table and system monitor.
JTabbedPane tableTabbedPane = new JTabbedPane();
@@ -112,76 +105,58 @@
tableTabbedPane.addTab("Log Messages", logPanel);
// Create the system monitor.
- systemStatusTable = new SystemStatusTable();
- tableTabbedPane.addTab("System Status Monitor", new JScrollPane(systemStatusTable));
+ //systemStatusTable = new SystemStatusTable();
+ systemStatusPanel = new SystemStatusPanel();
+ tableTabbedPane.addTab("System Status Monitor", systemStatusPanel);
// Add the trigger diagnostics tables.
triggerPanel = new TriggerDiagnosticsPanel();
tableTabbedPane.addTab("Trigger Diagnostics", triggerPanel);
+ // Add the conditions panel.
+ conditionsPanel = new ConditionsPanel();
+ tableTabbedPane.addTab("Detector Conditions", conditionsPanel);
+
// Vertical split pane in left panel.
- leftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, runPanel, tableTabbedPane);
- leftSplitPane.setResizeWeight(0.5);
+ leftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, dashboardPanel, tableTabbedPane);
+ leftSplitPane.setDividerLocation(250);
leftPanel.add(leftSplitPane, BorderLayout.CENTER);
// Create the right panel.
JPanel rightPanel = new JPanel();
rightPanel.setLayout(new BorderLayout());
-
+
// Create the plot info panel.
plotInfoPanel = new PlotInfoPanel();
// Create the plot panel.
- plotPanel = new PlotPanel();
- plotPanel.setVisible(true); // DEBUG
- setProportionalSize(plotPanel, RIGHT_PANEL_WIDTH, PLOT_PANEL_HEIGHT);
+ plotPanel = new PlotPanel();
+ plotInfoPanel.saveButton.addActionListener(plotPanel);
// Create the right panel vertical split pane for displaying plots and their information and statistics.
rightSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, plotPanel, plotInfoPanel);
- setProportionalSize(rightSplitPane, RIGHT_PANEL_WIDTH, FULL_SIZE);
- rightSplitPane.setResizeWeight(0.8);
+ rightSplitPane.setResizeWeight(0.7);
rightPanel.add(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.setResizeWeight(0.15);
+ mainSplitPane.setResizeWeight(0.2);
bottomPanel.add(mainSplitPane, BorderLayout.CENTER);
// Create the menu bar.
menu = new MenuBar(application.configurationModel, application.connectionModel, application);
setJMenuBar(menu);
dataSourceComboBox.addActionListener(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);
-
- // Setup the settings dialog box.
- settingsDialog = new SettingsDialog(application.configurationModel, application);
+ setVisible(true);
}
-
- /**
- * Set the size of a Swing component using proportions of the current screen bounds.
- * @param component The component to resize.
- * @param scaleX The X scaling (must be between 0 and 1).
- * @param scaleY The Y scaling (must be between 0 and 1).
- * @param setSize Call the setSize method as well as setPreferredSize (which is the default).
- * @return
- */
- void setProportionalSize(JComponent component, double scaleX, double scaleY) {
- GraphicsConfiguration graphics = this.getGraphicsConfiguration();
- Rectangle bounds = graphics.getBounds();
- if (scaleX < 0 || scaleX > 1) {
- throw new IllegalArgumentException("scaleX must be > 0 and <= 1.");
- }
- if (scaleY < 0 || scaleY > 1) {
- throw new IllegalArgumentException("scaleY must be > 0 and <= 1.");
- }
- Dimension scaledDimension = new Dimension((int)(bounds.getWidth() * scaleX), (int)(bounds.getHeight() * scaleY));
- component.setPreferredSize(scaledDimension);
- }
-
+
/**
* Restore default window settings.
*/
Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java
=============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java (original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotInfoPanel.java Sun Mar 15 11:31:15 2015
@@ -15,10 +15,10 @@
import hep.aida.ref.function.FunctionDispatcher;
import hep.aida.ref.function.FunctionListener;
+import java.awt.Color;
import java.awt.Component;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventObject;
@@ -27,6 +27,8 @@
import java.util.TimerTask;
import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JPanel;
@@ -47,6 +49,8 @@
JComboBox<Object> plotComboBox;
JTable infoTable = new JTable();
DefaultTableModel model;
+ JButton saveButton;
+
PlotterRegion currentRegion;
Object currentObject;
static final int INSET_SIZE = 5;
@@ -63,11 +67,18 @@
*/
@SuppressWarnings("unchecked")
PlotInfoPanel() {
-
- setLayout(new GridBagLayout());
- setBorder(BorderFactory.createEmptyBorder(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE));
-
- GridBagConstraints c;
+
+ setLayout(new FlowLayout(FlowLayout.LEFT));
+
+ JPanel leftPanel = new JPanel();
+ leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS));
+
+ JPanel buttonPanel = new JPanel();
+ saveButton = new JButton("Save Plots ...");
+ saveButton.setActionCommand(Commands.SAVE_SELECTED_PLOTS);
+ buttonPanel.add(saveButton);
+ //c.anchor = GridBagConstraints.NORTHWEST;
+ leftPanel.add(buttonPanel);
plotComboBox = new JComboBox<Object>();
plotComboBox.setActionCommand(PLOT_SELECTED);
@@ -85,26 +96,17 @@
}
});
plotComboBox.addActionListener(this);
- c = new GridBagConstraints();
- c.gridx = 0;
- c.gridy = 0;
- c.fill = GridBagConstraints.HORIZONTAL;
- c.insets = new Insets(0, 0, INSET_SIZE, 0);
- add(plotComboBox, c);
-
+ leftPanel.add(plotComboBox);
+
String data[][] = new String[0][0];
model = new DefaultTableModel(data, COLUMN_NAMES);
infoTable.setModel(model);
-
- // FIXME: Are these adequate column size settings? Could prob be bigger...
infoTable.getColumn("Field").setMinWidth(25);
infoTable.getColumn("Value").setMinWidth(20);
-
- c = new GridBagConstraints();
- c.gridx = 0;
- c.gridy = 1;
- c.fill = GridBagConstraints.BOTH;
- add(infoTable, c);
+ infoTable.setMinimumSize(new Dimension(100, 200));
+ leftPanel.add(infoTable);
+
+ add(leftPanel);
}
/**
Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotPanel.java
=============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotPanel.java (original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/PlotPanel.java Sun Mar 15 11:31:15 2015
@@ -1,15 +1,26 @@
package org.hps.monitoring.application;
+import hep.aida.IPlotter;
+
import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.IOException;
+import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
+
+import org.hps.monitoring.application.util.DialogUtil;
+import org.hps.monitoring.plotting.MonitoringPlotFactory;
/**
* This is the panel containing the tabs with the monitoring plots.
* @author Jeremy McCormick <[log in to unmask]>
*/
-class PlotPanel extends JPanel {
+class PlotPanel extends JPanel implements ActionListener {
private JTabbedPane plotPane;
@@ -23,8 +34,55 @@
JTabbedPane getPlotPane() {
return plotPane;
}
+
+ /**
+ * Get the indices of the current selected tabs.
+ * @return The indices of the current tabs.
+ */
+ 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) {
+ if (event.getActionCommand().equals(Commands.SAVE_SELECTED_PLOTS)) {
+ int[] indices = getSelectedTabs();
+ IPlotter plotter = MonitoringPlotFactory.getPlotterRegistry().find(indices[0], indices[1]);
+ if (plotter != null) {
+ 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();
+ fc.setAcceptAllFileFilterUsed(false);
+ fc.setDialogTitle("Save Plots - " + plotter.title());
+ fc.setCurrentDirectory(new File("."));
+ int r = fc.showSaveDialog(this);
+ if (r == JFileChooser.APPROVE_OPTION) {
+ String path = fc.getSelectedFile().getPath();
+ if (path.lastIndexOf(".") == -1) {
+ path += "." + DEFAULT_FORMAT;
+ }
+ try {
+ plotter.writeToFile(path);
+ } catch (IOException e) {
+ e.printStackTrace();
+ DialogUtil.showErrorDialog(this, "Error Saving Plots", "There was an error saving the plots.");
+ }
+ }
+ }
void reset() {
- plotPane.removeAll();
- }
+ plotPane.removeAll();
+ }
}
Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusTable.java
=============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusTable.java (original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/SystemStatusTable.java Sun Mar 15 11:31:15 2015
@@ -1,6 +1,5 @@
package org.hps.monitoring.application;
-import java.awt.Color;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
@@ -17,8 +16,7 @@
import org.hps.monitoring.subsys.StatusCode;
/**
- * A GUI window for showing changes to {@link org.hps.monitoring.subsys.SystemStatus} objects using
- * a <code>JTable</code>.
+ * This table shows the current state of {@link org.hps.monitoring.subsys.SystemStatus} objects.
*/
class SystemStatusTable extends JTable {
@@ -37,28 +35,7 @@
// Color code the cell by its status.
StatusCode statusCode = StatusCode.valueOf((String) value);
- if (statusCode.ordinal() >= StatusCode.ERROR.ordinal()) {
- // Any type of error is red.
- label.setBackground(Color.RED);
- } else if (statusCode.equals(StatusCode.WARNING)) {
- // Warnings are yellow.
- label.setBackground(Color.YELLOW);
- } else if (statusCode.equals(StatusCode.OKAY)) {
- // Okay is green.
- label.setBackground(Color.GREEN);
- } else if (statusCode.equals(StatusCode.OFFLINE)) {
- // Offline is orange.
- label.setBackground(Color.ORANGE);
- } else if (statusCode.equals(StatusCode.UNKNOWN)) {
- // Unknown is gray.
- label.setBackground(Color.GRAY);
- } else if (statusCode.equals(StatusCode.CLEARED)) {
- // Cleared is light gray.
- label.setBackground(Color.LIGHT_GRAY);
- } else {
- // Default is white, though this shouldn't happen!
- label.setBackground(Color.WHITE);
- }
+ label.setBackground(statusCode.getColor());
return label;
}
});
Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java
=============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java (original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatus.java Sun Mar 15 11:31:15 2015
@@ -10,6 +10,7 @@
public enum ConnectionStatus {
DISCONNECTED(Color.RED),
+ DISCONNECTING(Color.YELLOW),
CONNECTED(Color.GREEN);
Color color;
Modified: java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java
=============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java (original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/ConnectionStatusModel.java Sun Mar 15 11:31:15 2015
@@ -50,4 +50,16 @@
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/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/RunModel.java
=============================================================================
--- java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/RunModel.java (original)
+++ java/trunk/monitoring-app/src/main/java/org/hps/monitoring/application/model/RunModel.java Sun Mar 15 11:31:15 2015
@@ -3,7 +3,7 @@
import java.util.Date;
/**
- * Backing model for run information that shows in the {@link org.hps.monitoring.application.RunPanel}.
+ * Backing model for run information that shows in the {@link org.hps.monitoring.application.EventDashboard}.
*/
public final class RunModel extends AbstractModel {
Modified: java/trunk/monitoring-app/src/main/resources/org/hps/monitoring/config/default_config.prop
=============================================================================
--- java/trunk/monitoring-app/src/main/resources/org/hps/monitoring/config/default_config.prop (original)
+++ java/trunk/monitoring-app/src/main/resources/org/hps/monitoring/config/default_config.prop Sun Mar 15 11:31:15 2015
@@ -29,8 +29,7 @@
Host=localhost
Port=11111
StationPosition=1
-# Prescale was 1
-Prescale=0
+Prescale=1
QueueSize=0
StationName=MY_STATION
Verbose=false
|