hps-java/src/main/java/org/lcsim/hps/monitoring
diff -u -r1.2 -r1.3
--- DefaultEtEventProcessor.java 29 Apr 2012 23:17:49 -0000 1.2
+++ DefaultEtEventProcessor.java 30 Apr 2012 04:17:58 -0000 1.3
@@ -4,6 +4,9 @@
import java.nio.BufferUnderflowException;
import java.util.ArrayList;
import java.util.List;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.jlab.coda.et.EtEvent;
import org.jlab.coda.et.enums.Modify;
@@ -17,8 +20,9 @@
/**
* This class executes the default event processing chain for HPS Test Run monitoring: ET -> EVIO -> LCIO.
+ * Its method {@link #process()} should be executed on a separate thread which can be joined until it dies.
* @author Jeremy McCormick <[log in to unmask]>
- * @version $Id: DefaultEtEventProcessor.java,v 1.2 2012/04/29 23:17:49 jeremy Exp $
+ * @version $Id: DefaultEtEventProcessor.java,v 1.3 2012/04/30 04:17:58 jeremy Exp $
*/
public class DefaultEtEventProcessor implements EtEventProcessor
{
@@ -32,18 +36,44 @@
int status;
boolean stopProcessing;
boolean stopOnError;
+ Logger logger;
+ /**
+ *
+ * @param et The ET connection.
+ * @param eventBuilder The builder for converting from EVIO to LCIO.
+ * @param jobManager The LCSim job manager.
+ * @param maxEvents Maximum number of events to process in the session.
+ * @param stopOnError True to stop on first error; false to continue processing.
+ * @param logHandler The log handler for redirecting log messages.
+ */
DefaultEtEventProcessor(
EtConnection et,
LCSimEventBuilder eventBuilder,
JobControlManager jobManager,
int maxEvents,
- boolean stopOnError) {
+ boolean stopOnError,
+ Handler logHandler) {
+
+ // Set class parameters.
this.et = et;
this.eventBuilder = eventBuilder;
this.jobManager = jobManager;
this.maxEvents = maxEvents;
this.stopOnError = stopOnError;
+
+ // Setup the logger.
+ logger = Logger.getLogger(this.getClass().getSimpleName());
+ logger.setUseParentHandlers(false);
+ logger.addHandler(logHandler);
+ logger.setLevel(Level.ALL);
+
+ // Log an initialization message.
+ logger.log(Level.INFO, "Event processor initialized successfully.");
+ }
+
+ Logger getLogger() {
+ return logger;
}
public void addListener(EtEventListener callme) {
@@ -52,6 +82,7 @@
public void setMaxEvents(int maxEvents) {
this.maxEvents = maxEvents;
+ logger.log(Level.FINER, "Setting maxEvents to <" + maxEvents + ">.");
}
void begin() {
@@ -87,6 +118,7 @@
public void stop() {
this.stopProcessing = true;
+ logger.log(Level.FINER, "Received stop request.");
}
public int getNumberOfEventsProcessed() {
@@ -103,6 +135,7 @@
public void resetNumberOfEventsProcessed() {
eventsProcessed = 0;
+ errorEvents = 0;
}
public int getStatus() {
@@ -130,8 +163,6 @@
// Check if max events was reached or exceeded.
if (maxEvents != -1 && eventsProcessed >= maxEvents) {
- // TODO: log mesg that max events was reached
- //System.out.println("Reached max events " + eventsProcessed + " of " + maxEvents);
throw new MaxEventsException();
}
@@ -195,6 +226,7 @@
// Check if the ET connection is valid before starting.
if (!et.sys.alive()) {
+ logger.log(Level.SEVERE, "ET system is not alive.");
throw new RuntimeException("ET system is not alive.");
}
@@ -222,17 +254,21 @@
}
// The session timed out.
catch (EtTimeoutException e) {
+ logger.log(Level.WARNING, "ET connection timed out.");
this.status = ConnectionStatus.TIMED_OUT;
}
// Reached max number of events.
catch (MaxEventsException e) {
+ logger.log(Level.INFO, "Reached max events <" + this.maxEvents + ">.");
this.status = ConnectionStatus.DISCONNECTING;
}
- // There was some error processing events.
+ // There was some error processing the EtEvent.
catch (Exception e) {
- e.printStackTrace();
+ e.printStackTrace(); // This should show up in detailed job log in terminal or output file.
+ logger.log(Level.WARNING, "Error processing event <" + this.eventsProcessed + ">.");
if (stopOnError) {
this.status = ConnectionStatus.ERROR;
+ logger.log(Level.INFO, "Exiting on first error.");
}
}
finally {
hps-java/src/main/java/org/lcsim/hps/monitoring
diff -u -r1.30 -r1.31
--- MonitoringApplication.java 29 Apr 2012 23:51:22 -0000 1.30
+++ MonitoringApplication.java 30 Apr 2012 04:17:58 -0000 1.31
@@ -73,7 +73,7 @@
* calling its main() method.
*
* @author Jeremy McCormick <[log in to unmask]>
- * @version $Id: MonitoringApplication.java,v 1.30 2012/04/29 23:51:22 jeremy Exp $
+ * @version $Id: MonitoringApplication.java,v 1.31 2012/04/30 04:17:58 jeremy Exp $
*/
public class MonitoringApplication {
@@ -121,16 +121,21 @@
// Logging objects.
private Logger logger;
+ private Handler logHandler;
private DefaultTableModel logTableModel;
private JTable logTable;
// Some default GUI size parameters.
private final int maxWidth = 800;
- private final int logHeight = 300;
+ private final int logHeight = 320;
// Format for screenshots. Hard-coded to PNG.
private static final String screenshotFormat = "png";
+ /**
+ * Constructor for monitoring application. Users should not
+ * need to use this; call main() method instead.
+ */
private MonitoringApplication() {
// Create the ActionEventListener for event dispatching.
@@ -209,6 +214,7 @@
connectItem.setMnemonic(KeyEvent.VK_C);
connectItem.setActionCommand(connectCmd);
connectItem.addActionListener(actionListener);
+ connectItem.setToolTipText("Connect to ET system using parameters from connection panel.");
connectionMenu.add(connectItem);
disconnectItem = new JMenuItem("Disconnect");
@@ -216,30 +222,35 @@
disconnectItem.setActionCommand(disconnectCmd);
disconnectItem.addActionListener(actionListener);
disconnectItem.setEnabled(false);
+ disconnectItem.setToolTipText("Disconnect from the current ET session.");
connectionMenu.add(disconnectItem);
resetConnectionItem = new JMenuItem("Reset Connection Settings");
resetConnectionItem.setMnemonic(KeyEvent.VK_R);
resetConnectionItem.setActionCommand(resetConnectionSettingsCmd);
resetConnectionItem.addActionListener(actionListener);
+ resetConnectionItem.setToolTipText("Reset connection settings to defaults.");
connectionMenu.add(resetConnectionItem);
connectionLoadItem = new JMenuItem("Load Connection...");
connectionLoadItem.setMnemonic(KeyEvent.VK_L);
connectionLoadItem.setActionCommand(loadConnectionCmd);
connectionLoadItem.addActionListener(actionListener);
+ connectionLoadItem.setToolTipText("Load connection settings from a saved properties file.");
connectionMenu.add(connectionLoadItem);
connectionSaveItem = new JMenuItem("Save Connection...");
connectionSaveItem.setMnemonic(KeyEvent.VK_S);
connectionSaveItem.setActionCommand(saveConnectionCmd);
connectionSaveItem.addActionListener(actionListener);
+ connectionSaveItem.setToolTipText("Save connection settings to a properties file.");
connectionMenu.add(connectionSaveItem);
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.setMnemonic(KeyEvent.VK_X);
exitItem.setActionCommand(exitCmd);
exitItem.addActionListener(actionListener);
+ exitItem.setToolTipText("Exit from the application.");
connectionMenu.add(exitItem);
JMenu eventMenu = new JMenu("Event");
@@ -250,18 +261,21 @@
resetEventsItem.setMnemonic(KeyEvent.VK_E);
resetEventsItem.setActionCommand(resetEventsCmd);
resetEventsItem.addActionListener(actionListener);
+ resetEventsItem.setToolTipText("Reset timer and counters in the event monitor tab.");
eventMenu.add(resetEventsItem);
JMenuItem eventRefreshItem = new JMenuItem("Set Event Refresh...");
eventRefreshItem.setMnemonic(KeyEvent.VK_V);
eventRefreshItem.setActionCommand(eventRefreshCmd);
eventRefreshItem.addActionListener(actionListener);
+ eventRefreshItem.setToolTipText("Set the number of events between GUI updates.");
eventMenu.add(eventRefreshItem);
JMenuItem maxEventsItem = new JMenuItem("Set Max Events...");
maxEventsItem.setMnemonic(KeyEvent.VK_M);
maxEventsItem.setActionCommand(setMaxEventsCmd);
maxEventsItem.addActionListener(actionListener);
+ maxEventsItem.setToolTipText("Set the maximum number of events to process in one session.");
eventMenu.add(maxEventsItem);
JMenu jobMenu = new JMenu("Job");
@@ -272,6 +286,7 @@
steeringItem.setMnemonic(KeyEvent.VK_S);
steeringItem.setActionCommand(setSteeringFileCmd);
steeringItem.addActionListener(actionListener);
+ steeringItem.setToolTipText("Set the job's LCSim steering file.");
jobMenu.add(steeringItem);
savePlotsItem = new JMenuItem("Save Plots to AIDA File...");
@@ -279,6 +294,7 @@
savePlotsItem.setActionCommand(savePlotsCmd);
savePlotsItem.addActionListener(actionListener);
savePlotsItem.setEnabled(false);
+ savePlotsItem.setToolTipText("Save plots from default AIDA tree to an output file.");
jobMenu.add(savePlotsItem);
resetDriversItem = new JMenuItem("Reset LCSim Drivers");
@@ -286,6 +302,7 @@
resetDriversItem.setActionCommand(resetDriversCmd);
resetDriversItem.addActionListener(actionListener);
resetDriversItem.setEnabled(false);
+ resetDriversItem.setToolTipText("Reset Drivers that implement the Resettable interface.");
jobMenu.add(resetDriversItem);
logItem = new JMenuItem("Redirect to File...");
@@ -293,6 +310,7 @@
logItem.setActionCommand(logCmd);
logItem.addActionListener(actionListener);
logItem.setEnabled(true);
+ logItem.setToolTipText("Redirect job's standard out and err to a file.");
jobMenu.add(logItem);
terminalItem = new JMenuItem("Redirect to Terminal");
@@ -300,12 +318,14 @@
terminalItem.setActionCommand(terminalCmd);
terminalItem.addActionListener(actionListener);
terminalItem.setEnabled(false);
+ terminalItem.setToolTipText("Redirect job's standard out and err back to the terminal.");
jobMenu.add(terminalItem);
JMenuItem screenshotItem = new JMenuItem("Take a screenshot...");
screenshotItem.setMnemonic(KeyEvent.VK_N);
screenshotItem.setActionCommand(screenshotCmd);
screenshotItem.addActionListener(actionListener);
+ screenshotItem.setToolTipText("Save a full screenshot to a " + screenshotFormat + " file.");
jobMenu.add(screenshotItem);
JMenu logMenu = new JMenu("Log");
@@ -316,12 +336,14 @@
saveLogItem.setMnemonic(KeyEvent.VK_S);
saveLogItem.setActionCommand(saveLogCmd);
saveLogItem.addActionListener(actionListener);
+ saveLogItem.setToolTipText("Save the log records to a tab delimited text file.");
logMenu.add(saveLogItem);
JMenuItem clearLogItem = new JMenuItem("Clear log");
clearLogItem.setMnemonic(KeyEvent.VK_C);
clearLogItem.setActionCommand(clearLogCmd);
clearLogItem.addActionListener(actionListener);
+ clearLogItem.setToolTipText("Clear the log of all messages.");
logMenu.add(clearLogItem);
}
@@ -330,7 +352,8 @@
*/
private class MonitoringApplicationLogHandler extends Handler {
- final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd,yyyy HH:mm:ss.SSS");
+ // Format of date field.
+ private final SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM-dd-yyyy HH:mm:ss.SSS");
/**
* Puts log messages into the application's log table GUI component.
@@ -357,7 +380,6 @@
*/
private void createLogTable() {
final String[] logTableColumns = {"Source", "Message", "Date", "Level"};
-
String data[][] = new String[0][0];
logTableModel = new DefaultTableModel(data, logTableColumns);
logTable = new JTable(logTableModel);
@@ -373,11 +395,15 @@
mainPanel.add(logPane, c);
}
+ /**
+ * Setup the application's Logger object for writing messages to the log table.
+ */
private void setupLogger() {
- this.logger = Logger.getLogger(this.getClass().getSimpleName());
+ logger = Logger.getLogger(this.getClass().getSimpleName());
logger.setUseParentHandlers(false);
- logger.addHandler(new MonitoringApplicationLogHandler());
- logger.setLevel(Level.FINEST);
+ logHandler = new MonitoringApplicationLogHandler();
+ logger.addHandler(logHandler);
+ logger.setLevel(Level.ALL);
}
/**
@@ -430,18 +456,19 @@
}
/**
- * Runs the application loop.
+ * Runs the application's session loop.
*/
private void run() {
// GUI outer loop.
while (true) {
try {
// Execute a monitoring session.
- startSession();
+ session();
}
// Top-level exception catcher.
catch (Exception e) {
- e.printStackTrace();
+ e.printStackTrace(); // This should show up in terminal or log file.
+ logger.log(Level.SEVERE, e.getMessage());
disconnect(ConnectionStatus.ERROR);
showDialog(e.getMessage());
}
@@ -607,6 +634,7 @@
*/
private void requestConnection() {
setConnectionStatus(ConnectionStatus.CONNECTION_REQUESTED);
+ logger.log(Level.INFO, "Connection requested.");
}
/**
@@ -616,7 +644,7 @@
private void setConnectionStatus(int status) {
connectionStatus = status;
connectionStatusPanel.setStatus(status);
- logger.log(Level.FINE, "Connection status changed to " + ConnectionStatus.toString(status) + ".");
+ logger.log(Level.INFO, "Connection status changed to <" + ConnectionStatus.toString(status) + ">.");
}
/**
@@ -637,19 +665,18 @@
/**
* Pop-up a modal dialog.
- * @param m The message to display.
+ * @param m The message to display in the dialog box.
*/
private void showDialog(String m) {
JOptionPane.showMessageDialog(mainPanel, m);
}
/**
- * Sets up the frame to run the application.
+ * Setup the frame to run the application.
* This should be called using Runnable.run() (see MonitoringExample).
*/
private void createApplicationFrame() {
mainPanel.setOpaque(true);
-
JFrame frame = new JFrame(getApplicationTitle());
frame.setContentPane(mainPanel);
frame.setJMenuBar(menuBar);
@@ -670,6 +697,7 @@
File fileName = fc.getSelectedFile();
try {
AIDA.defaultInstance().saveAs(fileName);
+ logger.log(Level.INFO, "Plots saved to <" + fileName + ">.");
} catch (IOException e) {
e.printStackTrace();
}
@@ -687,9 +715,11 @@
try {
(new JobControlManager()).setup(fileName);
jobPanel.setSteeringFile(fileName.getPath());
+ logger.log(Level.INFO, "Steering file set to <" + fileName.getPath() + ">.");
}
catch (Exception e) {
e.printStackTrace();
+ logger.log(Level.SEVERE, "Failed to read steering file <" + fileName.getPath() + ">.");
showDialog("Failed to read the LCSim XML file.");
}
}
@@ -704,7 +734,7 @@
}
/**
- * Get the hostname.
+ * Get the hostname, which is used in the application title.
* @return The hostname.
*/
private static String getHostname() {
@@ -717,7 +747,7 @@
}
/**
- * Get the user name.
+ * Get the user name, which is used in the application title.
* @return The user name.
*/
private static String getUserName() {
@@ -730,7 +760,7 @@
}
/**
- * Call the reset() method on Drivers which support this.
+ * Call the reset() method on Drivers which implement {@link Resettable}.
* They must implement the {@link Resettable} interface for this to work.
*/
private synchronized void resetDrivers() {
@@ -745,6 +775,7 @@
}
}
}
+ logger.log(Level.INFO, "LCSim drivers were reset.");
}
/**
@@ -771,9 +802,11 @@
jobPanel.logCheckBox.setSelected(true);
terminalItem.setEnabled(true);
logItem.setEnabled(false);
-
+
+ logger.log(Level.INFO, "Redirected print output to file <" + logFile.getPath() + ">.");
} catch (IOException e) {
- JOptionPane.showMessageDialog(this.mainPanel, "Error creating log file.");
+ logger.log(Level.SEVERE, "Error redirecting print output to file <" + logFile.getPath() + ">.");
+ showDialog("Error creating log file.");
}
}
}
@@ -790,6 +823,7 @@
jobPanel.logCheckBox.setSelected(false);
terminalItem.setEnabled(false);
logItem.setEnabled(true);
+ logger.log(Level.INFO, "Redirected print output to terminal.");
}
/**
@@ -803,14 +837,16 @@
throw new RuntimeException("Event Refresh must be > 0.");
}
eventPanel.setEventRefresh(newEventRefresh);
+ logger.log(Level.INFO, "Event refresh set to <" + newEventRefresh + ">.");
}
catch (Exception e) {
+ logger.log(Level.WARNING, "Ignored invalid event refresh setting.");
showDialog("The value " + inputValue + " is not valid for Event Refresh Rate.");
}
}
/**
- * Set the maximum number of events to process before automatic disconnect using a modal dialog.
+ * Using a modal input dialog, set the maximum number of events to process before automatic disconnect.
*/
private void setMaxEvents() {
String inputValue = JOptionPane.showInputDialog("Max Events:", eventPanel.getMaxEvents());
@@ -824,8 +860,10 @@
eventPanel.setMaxEvents(newMaxEvents);
// Set max events in event processor.
eventProcessor.setMaxEvents(newMaxEvents);
+ logger.log(Level.INFO, "Max events set to <" + newMaxEvents + ">.");
}
catch (Exception e) {
+ logger.log(Level.WARNING, "Ignored invalid max events setting <" + inputValue + ">.");
showDialog("The value " + inputValue + " is not valid for Max Events.");
}
}
@@ -900,6 +938,7 @@
fileName = fileName + "." + screenshotFormat;
}
takeScreenshot(fileName);
+ logger.log(Level.INFO, "Screenshot saved to <" + fileName + ">.");
}
}
@@ -957,17 +996,19 @@
/**
* Run a monitoring session, which is everything that happens from waiting for and
- * getting a connect request to disconnecting after the event processing thread is done.
+ * getting a connection request to disconnecting after the event processing thread finishes.
*/
- private void startSession() {
+ private void session() {
+ logger.log(Level.FINER, "Monitoring session started.");
+
// Wait until connection is requested by the GUI.
waitForConnectionRequest();
// Setup LCSim.
setupLCSim();
- // TEST TEST TEST TEST
+ // TEST
//this.setupRemoteAida();
//
@@ -983,13 +1024,17 @@
// Wait for the event processing thread to finish.
try {
+ logger.log(Level.FINER, "Joining event processor thread.");
t.join();
}
catch (InterruptedException e) {}
- logger.log(Level.FINE, "Event processing thread exited with status of " + eventProcessor.getStatus() + ".");
+ logger.log(Level.FINE, "Event processor exited with status <" + ConnectionStatus.toString(eventProcessor.getStatus()) + ">.");
- // Disconnect with the status which was set by the event processor.
- disconnect(eventProcessor.getStatus());
+ // Disconnect with the status which was set by the event processor, if not disconnected already.
+ if (getConnectionStatus() != ConnectionStatus.DISCONNECTED)
+ disconnect(eventProcessor.getStatus());
+
+ logger.log(Level.FINER, "Monitoring session ended.");
}
/**
@@ -1003,7 +1048,8 @@
this.eventBuilder,
this.jobManager,
getMaxEvents(),
- disconnectOnError());
+ disconnectOnError(),
+ logHandler);
eventProcessor.addListener(new MonitoringApplicationEtListener(this));
Runnable run = new Runnable() {
public void run() {
@@ -1018,14 +1064,15 @@
*/
private void connect() {
+ logger.log(Level.FINER, "Connecting to ET system.");
+
// Make sure applicable menu items are enabled or disabled.
setConnectedGuiState();
// Create a connection to the ET server.
createEtConnection();
-
- // Set status to connected.
- connectionStatusPanel.setStatus(ConnectionStatus.CONNECTED);
+
+ logger.log(Level.INFO, "Successfully connected to ET system.");
}
/**
@@ -1082,8 +1129,11 @@
*/
synchronized private void disconnect(int status) {
+ logger.log(Level.FINER, "Disconnecting from ET system.");
+
// Show a warning dialog box before disconnecting, if this option is selected.
if (warnOnDisconnect()) {
+ logger.log(Level.FINER, "Waiting for user to verify disconnect.");
showDialog("You are about to be disconnected.");
}
@@ -1106,6 +1156,8 @@
// Finally, change application state to fully disconnected.
setConnectionStatus(ConnectionStatus.DISCONNECTED);
+
+ logger.log(Level.INFO, "Disconnected from ET system.");
}
/**
@@ -1113,9 +1165,13 @@
*/
private void setupLCSim() {
+ logger.log(Level.FINER, "Setting up LCSim.");
+
// Check if the LCSim steering file looks valid.
- if (!validSteering())
+ if (!validSteering()) {
+ logger.log(Level.SEVERE, "Steering file <" + getSteering() + "> is not valid.");
throw new RuntimeException("Invalid steering file or resource.");
+ }
// Get steering resource or file as a String parameter.
String steering = getSteering();
@@ -1141,7 +1197,7 @@
throw new RuntimeException("Failed to setup LCSim.", e);
}
- logger.log(Level.FINE, "LCSim setup OK with steering file <" + steering + ">.");
+ logger.log(Level.FINE, "LCSim setup with steering <" + steering + ">.");
}
/**
@@ -1150,6 +1206,8 @@
*/
private void createEventBuilder() {
+ logger.log(Level.FINER, "Initializing event builder.");
+
// Setup the EventBuilder class.
String eventBuilderClassName = getEventBuilderClassName();
@@ -1161,13 +1219,18 @@
// Set the detector name on the event builder so it can find conditions data.
eventBuilder.setDetectorName(getDetectorName());
+
+ logger.log(Level.INFO, "Successfully initialized the event builder.");
}
/**
* Create a connection to an ET system using current parameters from GUI.
+ * If successful, the ConnectionStatus is changed to CONNECTED.
*/
private void createEtConnection() {
+ logger.log(Level.FINER, "Creating ET connection.");
+
// Cache connection parameters.
connectionParameters = getConnectionParameters();
@@ -1176,10 +1239,12 @@
if (connection != null) {
// Set status to connected as there is now a live ET connection.
setConnectionStatus(ConnectionStatus.CONNECTED);
+ logger.log(Level.INFO, "Successfully created ET connection.");
}
else {
// An error occurred.
setConnectionStatus(ConnectionStatus.ERROR);
+ logger.log(Level.SEVERE, "Failed to create ET connection.");
throw new RuntimeException("Failed to create ET connection.");
}
}
@@ -1192,6 +1257,7 @@
timer.setActionCommand(updateTimeCmd);
jobStartTime = System.currentTimeMillis();
timer.start();
+ logger.log(Level.FINE, "Job timer started.");
}
/**
@@ -1206,7 +1272,6 @@
* Reset the event panel.
*/
private void resetJob() {
- logger.log(Level.FINE, "Reset the job.");
// Reset GUI.
jobStartTime = System.currentTimeMillis();
eventPanel.reset();
@@ -1215,10 +1280,11 @@
}
// Reset event processor.
eventProcessor.resetNumberOfEventsProcessed();
+ logger.log(Level.FINE, "Job was reset.");
}
/**
- * Save the application log table to an output file.
+ * Save the accumulated log messages to a tab-delimited text file.
*/
private void saveLogToFile() {
JFileChooser fc = new JFileChooser();
@@ -1242,9 +1308,10 @@
BufferedWriter out = new BufferedWriter(new FileWriter(logFile.getPath()));
out.write(buf.toString());
out.close();
- logger.log(Level.FINE, "Saved log records to <" + logFile.getPath() + ">.");
+ logger.log(Level.FINE, "Saved log to file <" + logFile.getPath() + ">.");
}
catch (IOException e) {
+ logger.log(Level.SEVERE, "Failed to save log to <" + logFile.getPath() + ">.");
showDialog("Failed to save log file.");
}
}
@@ -1256,6 +1323,7 @@
*/
private void clearLog() {
logTableModel.setRowCount(0);
+ logger.log(Level.INFO, "Log was cleared.");
}
/**