weka.gui.MemoryUsagePanel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of weka-stable Show documentation
Show all versions of weka-stable Show documentation
The Waikato Environment for Knowledge Analysis (WEKA), a machine
learning workbench. This is the stable version. Apart from bugfixes, this version
does not receive any other updates.
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* MemoryUsagePanel.java
* Copyright (C) 2008-2012 University of Waikato, Hamilton, New Zealand
*/
package weka.gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import weka.core.Memory;
import weka.core.Utils;
import weka.gui.visualize.VisualizeUtils;
/**
* A panel for displaying the memory usage.
*
* @author fracpete (fracpete at waikato dot ac dot nz)
* @version $Revision: 10216 $
*/
public class MemoryUsagePanel extends JPanel {
/** for serialization. */
private static final long serialVersionUID = -4812319791687471721L;
/**
* Specialized thread for monitoring the memory usage.
*
* @author fracpete (fracpete at waikato dot ac dot nz)
* @version $Revision: 10216 $
*/
protected class MemoryMonitor extends Thread {
/** the refresh interval in msecs. */
protected int m_Interval;
/** whether the thread is still running. */
protected boolean m_Monitoring;
/**
* default constructor.
*/
public MemoryMonitor() {
super();
setInterval(1000); // TODO: via props file
}
/**
* Returns the refresh interval in msecs.
*
* @return returns the refresh interval
*/
public int getInterval() {
return m_Interval;
}
/**
* Sets the refresh interval in msecs.
*
* @param value the refresh interval
*/
public void setInterval(int value) {
m_Interval = value;
}
/**
* Returns whether the thread is still running.
*
* @return true if the thread is still running
*/
public boolean isMonitoring() {
return m_Monitoring;
}
/**
* stops the monitoring thread.
*/
public void stopMonitoring() {
m_Monitoring = false;
}
/**
* The run method.
*/
@Override
public void run() {
m_Monitoring = true;
while (m_Monitoring) {
try {
Thread.sleep(m_Interval);
// update GUI
if (m_Monitoring) {
Runnable doUpdate = new Runnable() {
@Override
public void run() {
update();
}
};
SwingUtilities.invokeLater(doUpdate);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
/**
* Updates the GUI.
*/
protected void update() {
double perc;
Dimension size;
// current usage
perc = (double) m_Memory.getCurrent() / (double) m_Memory.getMax();
perc = Math.round(perc * 1000) / 10;
// tool tip
setToolTipText("" + perc + "% used");
// update history
m_History.insertElementAt(perc, 0);
size = getSize();
while (m_History.size() > size.getWidth()) {
m_History.remove(m_History.size() - 1);
}
// display history
repaint();
}
}
/** The name of the properties file. */
protected static String PROPERTY_FILE = "weka/gui/MemoryUsage.props";
/** Contains the properties. */
protected static Properties PROPERTIES;
/** the memory usage over time. */
protected Vector m_History;
/** for monitoring the memory usage. */
protected Memory m_Memory;
/** the thread for monitoring the memory usage. */
protected MemoryMonitor m_Monitor;
/** the button for running the garbage collector. */
protected JButton m_ButtonGC;
/** the threshold percentages to change color. */
protected Vector m_Percentages;
/** the corresponding colors for the thresholds. */
protected Hashtable m_Colors;
/** the default color. */
protected Color m_DefaultColor;
/** the background color. */
protected Color m_BackgroundColor;
/** the position for the dialog. */
protected Point m_FrameLocation;
/**
* Loads the configuration property file (USE_DYNAMIC is FALSE) or determines
* the classes dynamically (USE_DYNAMIC is TRUE)
*
* @see #USE_DYNAMIC
* @see GenericPropertiesCreator
*/
static {
// Allow a properties file in the current directory to override
try {
PROPERTIES = Utils.readProperties(PROPERTY_FILE);
Enumeration keys = PROPERTIES.propertyNames();
if (!keys.hasMoreElements()) {
throw new Exception("Failed to read a property file for the "
+ "memory usage panel");
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(null,
"Could not read a configuration file for the memory usage\n"
+ "panel. An example file is included with the Weka distribution.\n"
+ "This file should be named \"" + PROPERTY_FILE + "\" and\n"
+ "should be placed either in your user home (which is set\n"
+ "to \"" + System.getProperties().getProperty("user.home") + "\")\n"
+ "or the directory that java was started from\n",
"MemoryUsagePanel", JOptionPane.ERROR_MESSAGE);
}
}
/**
* default constructor.
*/
public MemoryUsagePanel() {
super();
// initializes members
m_Memory = new Memory();
m_History = new Vector();
m_Percentages = new Vector();
m_Colors = new Hashtable();
// colors and percentages
m_BackgroundColor = parseColor("BackgroundColor", Color.WHITE);
m_DefaultColor = parseColor("DefaultColor", Color.GREEN);
String[] percs = PROPERTIES.getProperty("Percentages", "70,80,90").split(
",");
for (String perc2 : percs) {
// do we have a color associated with percentage?
if (PROPERTIES.getProperty(perc2) != null) {
double perc;
Color color;
// try parsing the number
try {
perc = Double.parseDouble(perc2);
} catch (Exception e) {
System.err.println("MemoryUsagePanel: cannot parse percentage '"
+ perc2 + "' - ignored!");
continue;
}
// try parsing the color
color = parseColor(perc2, null);
if (color == null) {
continue;
}
// store color and percentage
m_Percentages.add(perc);
m_Colors.put(perc, color);
} else {
System.err
.println("MemoryUsagePanel: cannot find color for percentage '"
+ perc2 + "' - ignored!");
}
}
Collections.sort(m_Percentages);
// layout
setLayout(new BorderLayout());
JPanel panel = new JPanel(new BorderLayout());
add(panel, BorderLayout.EAST);
m_ButtonGC = new JButton("GC");
m_ButtonGC.setToolTipText("Runs the garbage collector.");
m_ButtonGC.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
System.gc();
}
});
panel.add(m_ButtonGC, BorderLayout.NORTH);
// dimensions
int height;
int width;
try {
height = Integer.parseInt(PROPERTIES.getProperty("Height", ""
+ (int) m_ButtonGC.getPreferredSize().getHeight()));
width = Integer.parseInt(PROPERTIES.getProperty("Width", "400"));
} catch (Exception e) {
System.err.println("MemoryUsagePanel: Problem parsing the dimensions - "
+ e);
height = (int) m_ButtonGC.getPreferredSize().getHeight();
width = 400;
}
setPreferredSize(new Dimension(width, height));
// position
int top;
int left;
try {
top = Integer.parseInt(PROPERTIES.getProperty("Top", "0"));
left = Integer.parseInt(PROPERTIES.getProperty("Left", "0"));
} catch (Exception e) {
System.err.println("MemoryUsagePanel: Problem parsing the position - "
+ e);
top = 0;
left = 0;
}
m_FrameLocation = new Point(left, top);
// monitoring thread
int interval;
try {
interval = Integer.parseInt(PROPERTIES.getProperty("Interval", "1000"));
} catch (Exception e) {
System.err
.println("MemoryUsagePanel: Problem parsing the refresh interval - "
+ e);
interval = 1000;
}
m_Monitor = new MemoryMonitor();
m_Monitor.setInterval(interval);
m_Monitor.setPriority(Thread.MAX_PRIORITY);
m_Monitor.start();
}
/**
* parses the color and returns the corresponding Color object.
*
* @param prop the color property to read and parse
* @param defValue the default color
* @return the parsed color or the default color of the
*/
protected Color parseColor(String prop, Color defValue) {
Color result;
Color color;
String colorStr;
result = defValue;
try {
colorStr = PROPERTIES.getProperty(prop);
color = VisualizeUtils.processColour(colorStr, result);
if (color == null) {
throw new Exception(colorStr);
}
result = color;
} catch (Exception e) {
System.err.println("MemoryUsagePanel: cannot parse color '"
+ e.getMessage() + "' - ignored!");
}
return result;
}
/**
* Returns whether the thread is still running.
*
* @return true if the thread is still running
*/
public boolean isMonitoring() {
return m_Monitor.isMonitoring();
}
/**
* stops the monitoring thread.
*/
public void stopMonitoring() {
m_Monitor.stopMonitoring();
}
/**
* Returns the default position for the dialog.
*
* @return the default position
*/
public Point getFrameLocation() {
return m_FrameLocation;
}
/**
* draws the background image.
*
* @param g the graphics context
*/
@Override
public void paintComponent(Graphics g) {
int i;
int n;
int len;
double scale;
double perc;
Color color;
super.paintComponent(g);
g.setColor(m_BackgroundColor);
g.fillRect(0, 0, getWidth(), getHeight());
scale = getHeight() / 100.0;
for (i = 0; i < m_History.size(); i++) {
perc = m_History.get(i);
// determine color
color = m_DefaultColor;
for (n = m_Percentages.size() - 1; n >= 0; n--) {
if (perc >= m_Percentages.get(n)) {
color = m_Colors.get(m_Percentages.get(n));
break;
}
}
// paint line
g.setColor(color);
len = (int) Math.round(perc * scale);
g.drawLine(i, getHeight() - 1, i, getHeight() - len);
}
}
}