weka.gui.beans.BeanVisual 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 .
*/
/*
* BeanVisual.java
* Copyright (C) 2002-2012 University of Waikato, Hamilton, New Zealand
*
*/
package weka.gui.beans;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* BeanVisual encapsulates icons and label for a given bean. Has methods to load
* icons, set label text and toggle between static and animated versions of a
* bean's icon.
*
* @author Mark Hall
* @version $Revision: 12016 $
* @since 1.0
* @see JPanel
* @see Serializable
*/
public class BeanVisual extends JPanel {
/** for serialization */
private static final long serialVersionUID = -6677473561687129614L;
public static final String ICON_PATH = "weka/gui/beans/icons/";
public static final int NORTH_CONNECTOR = 0;
public static final int SOUTH_CONNECTOR = 1;
public static final int EAST_CONNECTOR = 2;
public static final int WEST_CONNECTOR = 3;
/**
* Holds name (including path) of the static icon
*/
protected String m_iconPath;
/**
* Holds name (including path) of the animated icon
*/
protected String m_animatedIconPath;
/**
* ImageIcons for the icons. Is transient because for some reason animated
* gifs cease to be animated after restoring from serialization. Icons are
* re-loaded from source after deserialization
*/
protected transient ImageIcon m_icon;
protected transient ImageIcon m_animatedIcon;
/**
* Name for the bean
*/
protected String m_visualName;
protected JLabel m_visualLabel;
/**
* Container for the icon
*/
// protected IconHolder m_visualHolder;
// protected JLabel m_textLabel;
// private final boolean m_stationary = true;
private final PropertyChangeSupport m_pcs = new PropertyChangeSupport(this);
private boolean m_displayConnectors = false;
private Color m_connectorColor = Color.blue;
/**
* Constructor
*
* @param visualName name for the bean
* @param iconPath path to the icon file
* @param animatedIconPath path to the animated icon file
*/
public BeanVisual(String visualName, String iconPath, String animatedIconPath) {
loadIcons(iconPath, animatedIconPath);
m_visualName = visualName;
// m_textLabel = new JLabel(m_visualName, JLabel.CENTER);
m_visualLabel = new JLabel(m_icon);
setLayout(new BorderLayout());
// m_visualHolder = new IconHolder(m_visualLabel);
add(m_visualLabel, BorderLayout.CENTER);
Dimension d = m_visualLabel.getPreferredSize();
// this.setSize((int)d.getWidth()+50, (int)d.getHeight()+50);
Dimension d2 = new Dimension((int) d.getWidth() + 10,
(int) d.getHeight() + 10);
setMinimumSize(d2);
setPreferredSize(d2);
setMaximumSize(d2);
}
/**
* Reduce this BeanVisual's icon size by the given factor
*
* @param factor the factor by which to reduce the icon size by
*/
public void scale(int factor) {
if (m_icon != null) {
removeAll();
Image pic = m_icon.getImage();
int width = m_icon.getIconWidth();
int height = m_icon.getIconHeight();
int reduction = width / factor;
width -= reduction;
height -= reduction;
pic = pic.getScaledInstance(width, height, Image.SCALE_SMOOTH);
m_icon = new ImageIcon(pic);
m_visualLabel = new JLabel(m_icon);
add(m_visualLabel, BorderLayout.CENTER);
Dimension d = m_visualLabel.getPreferredSize();
// this.setSize((int)d.getWidth()+50, (int)d.getHeight()+50);
Dimension d2 = new Dimension((int) d.getWidth() + 10,
(int) d.getHeight() + 10);
setMinimumSize(d2);
setPreferredSize(d2);
setMaximumSize(d2);
}
}
public Image scale(double percent) {
if (m_icon != null) {
Image pic = m_icon.getImage();
double width = m_icon.getIconWidth();
double height = m_icon.getIconHeight();
width *= percent;
height *= percent;
pic = pic
.getScaledInstance((int) width, (int) height, Image.SCALE_SMOOTH);
return pic;
}
return null;
}
/**
* Loads static and animated versions of a beans icons. These are assumed to
* be defined in the system resource location (i.e. in the CLASSPATH). If the
* named icons do not exist, no changes to the visual appearance is made.
* Since default icons for generic types of beans (eg. DataSource, Classifier
* etc) are assumed to exist, it allows developers to add custom icons for for
* specific instantiations of these beans (eg. J48, DiscretizeFilter etc) at
* their leisure.
*
* @param iconPath path to
* @param animatedIconPath a String
value
*/
public boolean loadIcons(String iconPath, String animatedIconPath) {
boolean success = true;
// java.net.URL imageURL = ClassLoader.getSystemResource(iconPath);
java.net.URL imageURL = this.getClass().getClassLoader()
.getResource(iconPath);
if (imageURL == null) {
// System.err.println("Warning: unable to load "+iconPath);
} else {
Image pic = Toolkit.getDefaultToolkit().getImage(imageURL);
m_icon = new ImageIcon(pic);
if (m_visualLabel != null) {
m_visualLabel.setIcon(m_icon);
}
}
// imageURL = ClassLoader.getSystemResource(animatedIconPath);
imageURL = this.getClass().getClassLoader().getResource(animatedIconPath);
if (imageURL == null) {
// System.err.println("Warning: unable to load "+animatedIconPath);
success = false;
} else {
Image pic2 = Toolkit.getDefaultToolkit().getImage(imageURL);
m_animatedIcon = new ImageIcon(pic2);
}
m_iconPath = iconPath;
m_animatedIconPath = animatedIconPath;
return success;
}
/**
* Set the label for the visual. Informs any property change listeners
*
* @param text the label
*/
public void setText(String text) {
m_visualName = text;
// m_textLabel.setText(m_visualName);
m_pcs.firePropertyChange("label", null, null);
}
/**
* Get the visual's label
*
* @return a String
value
*/
public String getText() {
return m_visualName;
}
/**
* Set the static version of the icon.
*
* This method has been deprecated and now has no affect. A future version of
* the KnowledgeFlow application may orchestrate the display of which
* components are active graphically
*/
@Deprecated
public void setStatic() {
// setDisplayConnectors(false);
// m_visualLabel.setIcon(m_icon);
}
/**
* Set the animated version of the icon
*
* This method has been deprecated and now has no affect. A future version of
* the KnowledgeFlow application may orchestrate the display of which
* components are active graphically
*/
@Deprecated
public void setAnimated() {
// setDisplayConnectors(true);
// m_visualLabel.setIcon(m_animatedIcon);
}
/**
* Returns the coordinates of the closest "connector" point to the supplied
* point. Coordinates are in the parent containers coordinate space.
*
* @param pt the reference point
* @return the closest connector point
*/
public Point getClosestConnectorPoint(Point pt) {
int sourceX = getParent().getX();
int sourceY = getParent().getY();
int sourceWidth = getWidth();
int sourceHeight = getHeight();
int sourceMidX = sourceX + (sourceWidth / 2);
int sourceMidY = sourceY + (sourceHeight / 2);
int x = (int) pt.getX();
int y = (int) pt.getY();
Point closest = new Point();
int cx = (Math.abs(x - sourceMidX) < Math.abs(y - sourceMidY)) ? sourceMidX
: ((x < sourceMidX) ? sourceX : sourceX + sourceWidth);
int cy = (Math.abs(y - sourceMidY) < Math.abs(x - sourceMidX)) ? sourceMidY
: ((y < sourceMidY) ? sourceY : sourceY + sourceHeight);
closest.setLocation(cx, cy);
return closest;
}
/**
* Returns the coordinates of the connector point given a compass point
*
* @param compassPoint a compass point
* @return a Point
value
*/
public Point getConnectorPoint(int compassPoint) {
int sourceX = getParent().getX();
int sourceY = getParent().getY();
int sourceWidth = getWidth();
int sourceHeight = getHeight();
int sourceMidX = sourceX + (sourceWidth / 2);
int sourceMidY = sourceY + (sourceHeight / 2);
switch (compassPoint) {
case NORTH_CONNECTOR:
return new Point(sourceMidX, sourceY);
case SOUTH_CONNECTOR:
return new Point(sourceMidX, sourceY + sourceHeight);
case WEST_CONNECTOR:
return new Point(sourceX, sourceMidY);
case EAST_CONNECTOR:
return new Point(sourceX + sourceWidth, sourceMidY);
default:
System.err.println("Unrecognised connectorPoint (BeanVisual)");
}
return new Point(sourceX, sourceY);
}
/**
* Returns the static icon
*
* @return an ImageIcon
value
*/
public ImageIcon getStaticIcon() {
return m_icon;
}
/**
* Returns the animated icon
*
* @return an ImageIcon
value
*/
public ImageIcon getAnimatedIcon() {
return m_animatedIcon;
}
/**
* returns the path for the icon
*
* @return the path for the icon
*/
public String getIconPath() {
return m_iconPath;
}
/**
* returns the path for the animated icon
*
* @return the path for the animated icon
*/
public String getAnimatedIconPath() {
return m_animatedIconPath;
}
/**
* Turn on/off the connector points
*
* @param dc a boolean
value
*/
public void setDisplayConnectors(boolean dc) {
// m_visualHolder.setDisplayConnectors(dc);
m_displayConnectors = dc;
m_connectorColor = Color.blue;
repaint();
}
/**
* Turn on/off the connector points
*
* @param dc a boolean
value
* @param c the Color to use
*/
public void setDisplayConnectors(boolean dc, Color c) {
setDisplayConnectors(dc);
m_connectorColor = c;
}
/**
* Add a listener for property change events
*
* @param pcl a PropertyChangeListener
value
*/
@Override
public void addPropertyChangeListener(PropertyChangeListener pcl) {
if (m_pcs != null && pcl != null) {
m_pcs.addPropertyChangeListener(pcl);
}
}
/**
* Remove a property change listener
*
* @param pcl a PropertyChangeListener
value
*/
@Override
public void removePropertyChangeListener(PropertyChangeListener pcl) {
if (m_pcs != null && pcl != null) {
m_pcs.removePropertyChangeListener(pcl);
}
}
@Override
public void paintComponent(Graphics gx) {
((Graphics2D) gx).setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
super.paintComponent(gx);
if (m_displayConnectors) {
gx.setColor(m_connectorColor);
int midx = (int) (this.getWidth() / 2.0);
int midy = (int) (this.getHeight() / 2.0);
gx.fillOval(midx - 2, 0, 5, 5);
gx.fillOval(midx - 2, this.getHeight() - 5, 5, 5);
gx.fillOval(0, midy - 2, 5, 5);
gx.fillOval(this.getWidth() - 5, midy - 2, 5, 5);
}
}
/**
* Overides default read object in order to reload icons. This is necessary
* because for some strange reason animated gifs stop being animated after
* being serialized/deserialized.
*
* @param ois an ObjectInputStream
value
* @exception IOException if an error occurs
* @exception ClassNotFoundException if an error occurs
*/
private void readObject(ObjectInputStream ois) throws IOException,
ClassNotFoundException {
try {
ois.defaultReadObject();
remove(m_visualLabel);
m_visualLabel = new JLabel(m_icon);
loadIcons(m_iconPath, m_animatedIconPath);
add(m_visualLabel, BorderLayout.CENTER);
Dimension d = m_visualLabel.getPreferredSize();
Dimension d2 = new Dimension((int) d.getWidth() + 10,
(int) d.getHeight() + 10);
setMinimumSize(d2);
setPreferredSize(d2);
setMaximumSize(d2);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}