2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* GNU General Public License for more details.
12
* You should have received a copy of the GNU General Public License
13
* along with this program; if not, write to the Free Software
14
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
* Copyright (C) 2002 University of Waikato, Hamilton, New Zealand
23
package weka.gui.beans;
25
import java.awt.BorderLayout;
26
import java.awt.Color;
27
import java.awt.Dimension;
28
import java.awt.Graphics;
29
import java.awt.Image;
30
import java.awt.Point;
31
import java.awt.Toolkit;
32
import java.beans.PropertyChangeListener;
33
import java.beans.PropertyChangeSupport;
34
import java.io.IOException;
35
import java.io.ObjectInputStream;
36
import java.io.Serializable;
38
import javax.swing.ImageIcon;
39
import javax.swing.JLabel;
40
import javax.swing.JPanel;
43
* BeanVisual encapsulates icons and label for a given bean. Has methods
44
* to load icons, set label text and toggle between static and animated
45
* versions of a bean's icon.
47
* @author <a href="mailto:mhall@cs.waikato.ac.nz">Mark Hall</a>
48
* @version $Revision: 1.9 $
53
public class BeanVisual
56
/** for serialization */
57
private static final long serialVersionUID = -6677473561687129614L;
59
public static final String ICON_PATH="weka/gui/beans/icons/";
61
public static final int NORTH_CONNECTOR = 0;
62
public static final int SOUTH_CONNECTOR = 1;
63
public static final int EAST_CONNECTOR = 2;
64
public static final int WEST_CONNECTOR = 3;
67
* Holds name (including path) of the static icon
69
protected String m_iconPath;
72
* Holds name (including path) of the animated icon
74
protected String m_animatedIconPath;
77
* ImageIcons for the icons. Is transient because for some reason
78
* animated gifs cease to be animated after restoring from serialization.
79
* Icons are re-loaded from source after deserialization
81
protected transient ImageIcon m_icon;
82
protected transient ImageIcon m_animatedIcon;
87
protected String m_visualName;
89
protected JLabel m_visualLabel;
92
* Container for the icon
94
// protected IconHolder m_visualHolder;
96
// protected JLabel m_textLabel;
97
private boolean m_stationary = true;
99
private PropertyChangeSupport m_pcs = new PropertyChangeSupport(this);
101
private boolean m_displayConnectors = false;
102
private Color m_connectorColor = Color.blue;
107
* @param visualName name for the bean
108
* @param iconPath path to the icon file
109
* @param animatedIconPath path to the animated icon file
111
public BeanVisual(String visualName, String iconPath,
112
String animatedIconPath) {
114
loadIcons(iconPath, animatedIconPath);
115
m_visualName = visualName;
116
// m_textLabel = new JLabel(m_visualName, JLabel.CENTER);
117
m_visualLabel = new JLabel(m_icon);
119
setLayout(new BorderLayout());
121
// m_visualHolder = new IconHolder(m_visualLabel);
123
add(m_visualLabel, BorderLayout.CENTER);
124
Dimension d = m_visualLabel.getPreferredSize();
125
// this.setSize((int)d.getWidth()+50, (int)d.getHeight()+50);
126
Dimension d2 = new Dimension((int)d.getWidth() + 10,
127
(int)d.getHeight() + 10);
129
setPreferredSize(d2);
134
* Reduce this BeanVisual's icon size by the given factor
136
* @param factor the factor by which to reduce the icon size by
138
public void scale(int factor) {
139
if (m_icon != null) {
141
Image pic = m_icon.getImage();
142
int width = m_icon.getIconWidth();
143
int height = m_icon.getIconHeight();
144
int reduction = width / factor;
147
pic = pic.getScaledInstance(width, height, Image.SCALE_SMOOTH);
148
m_icon = new ImageIcon(pic);
149
m_visualLabel = new JLabel(m_icon);
150
add(m_visualLabel, BorderLayout.CENTER);
151
Dimension d = m_visualLabel.getPreferredSize();
152
// this.setSize((int)d.getWidth()+50, (int)d.getHeight()+50);
153
Dimension d2 = new Dimension((int)d.getWidth() + 10,
154
(int)d.getHeight() + 10);
156
setPreferredSize(d2);
162
* Loads static and animated versions of a beans icons. These are
163
* assumed to be defined in the system resource location (i.e. in the
164
* CLASSPATH). If the named icons do not exist, no changes to the
165
* visual appearance is made. Since default icons for generic
166
* types of beans (eg. DataSource, Classifier etc)
167
* are assumed to exist, it allows developers to add custom icons for
168
* for specific instantiations of these beans
169
* (eg. J48, DiscretizeFilter etc) at their leisure.
171
* @param iconPath path to
172
* @param animatedIconPath a <code>String</code> value
174
public boolean loadIcons(String iconPath, String animatedIconPath) {
175
boolean success = true;
176
java.net.URL imageURL = ClassLoader.getSystemResource(iconPath);
177
if (imageURL == null) {
178
// System.err.println("Warning: unable to load "+iconPath);
180
Image pic = Toolkit.getDefaultToolkit().
183
m_icon = new ImageIcon(pic);
184
if (m_visualLabel != null) {
185
m_visualLabel.setIcon(m_icon);
189
imageURL = ClassLoader.getSystemResource(animatedIconPath);
190
if (imageURL == null) {
191
// System.err.println("Warning: unable to load "+animatedIconPath);
194
Image pic2 = Toolkit.getDefaultToolkit().
196
m_animatedIcon = new ImageIcon(pic2);
198
m_iconPath = iconPath;
199
m_animatedIconPath = animatedIconPath;
204
* Set the label for the visual. Informs any property change listeners
206
* @param text the label
208
public void setText(String text) {
210
// m_textLabel.setText(m_visualName);
211
m_pcs.firePropertyChange("label",null,null);
215
* Get the visual's label
217
* @return a <code>String</code> value
219
public String getText() {
224
* Set the static version of the icon
227
public void setStatic() {
228
m_visualLabel.setIcon(m_icon);
232
* Set the animated version of the icon
235
public void setAnimated() {
236
m_visualLabel.setIcon(m_animatedIcon);
240
* Returns the coordinates of the closest "connector" point to the
241
* supplied point. Coordinates are in the parent containers coordinate
244
* @param pt the reference point
245
* @return the closest connector point
247
public Point getClosestConnectorPoint(Point pt) {
248
int sourceX = getParent().getX();
249
int sourceY = getParent().getY();
250
int sourceWidth = getWidth();
251
int sourceHeight = getHeight();
252
int sourceMidX = sourceX + (sourceWidth / 2);
253
int sourceMidY = sourceY + (sourceHeight / 2);
254
int x = (int)pt.getX();
255
int y = (int)pt.getY();
257
Point closest = new Point();
258
int cx = (Math.abs(x - sourceMidX) < Math.abs(y - sourceMidY)) ?
260
((x < sourceMidX) ? sourceX : sourceX + sourceWidth);
261
int cy = (Math.abs(y - sourceMidY) < Math.abs(x - sourceMidX)) ?
263
((y < sourceMidY) ? sourceY : sourceY + sourceHeight) ;
264
closest.setLocation(cx, cy);
269
* Returns the coordinates of the connector point given a compass point
271
* @param compassPoint a compass point
272
* @return a <code>Point</code> value
274
public Point getConnectorPoint(int compassPoint) {
275
int sourceX = getParent().getX();
276
int sourceY = getParent().getY();
277
int sourceWidth = getWidth();
278
int sourceHeight = getHeight();
279
int sourceMidX = sourceX + (sourceWidth / 2);
280
int sourceMidY = sourceY + (sourceHeight / 2);
282
switch (compassPoint) {
283
case NORTH_CONNECTOR : return new Point(sourceMidX, sourceY);
284
case SOUTH_CONNECTOR : return new Point(sourceMidX, sourceY+sourceHeight);
285
case WEST_CONNECTOR : return new Point(sourceX, sourceMidY);
286
case EAST_CONNECTOR : return new Point(sourceX+sourceWidth, sourceMidY);
287
default : System.err.println("Unrecognised connectorPoint (BeanVisual)");
289
return new Point(sourceX, sourceY);
293
* Returns the static icon
295
* @return an <code>ImageIcon</code> value
297
public ImageIcon getStaticIcon() {
302
* Returns the animated icon
304
* @return an <code>ImageIcon</code> value
306
public ImageIcon getAnimatedIcon() {
307
return m_animatedIcon;
311
* returns the path for the icon
313
* @return the path for the icon
315
public String getIconPath() {
320
* returns the path for the animated icon
322
* @return the path for the animated icon
324
public String getAnimatedIconPath() {
325
return m_animatedIconPath;
329
* Turn on/off the connector points
331
* @param dc a <code>boolean</code> value
333
public void setDisplayConnectors(boolean dc) {
334
// m_visualHolder.setDisplayConnectors(dc);
335
m_displayConnectors = dc;
336
m_connectorColor = Color.blue;
341
* Turn on/off the connector points
343
* @param dc a <code>boolean</code> value
344
* @param c the Color to use
346
public void setDisplayConnectors(boolean dc,
348
setDisplayConnectors(dc);
349
m_connectorColor = c;
353
* Add a listener for property change events
355
* @param pcl a <code>PropertyChangeListener</code> value
357
public void addPropertyChangeListener(PropertyChangeListener pcl) {
358
m_pcs.addPropertyChangeListener(pcl);
362
* Remove a property change listener
364
* @param pcl a <code>PropertyChangeListener</code> value
366
public void removePropertyChangeListener(PropertyChangeListener pcl) {
367
m_pcs.removePropertyChangeListener(pcl);
370
public void paintComponent(Graphics gx) {
371
super.paintComponent(gx);
372
if (m_displayConnectors) {
373
gx.setColor(m_connectorColor);
375
int midx = (int)(this.getWidth() / 2.0);
376
int midy = (int)(this.getHeight() / 2.0);
377
gx.fillOval(midx-2, 0, 5, 5);
378
gx.fillOval(midx-2, this.getHeight()-5, 5, 5);
379
gx.fillOval(0, midy-2, 5, 5);
380
gx.fillOval(this.getWidth()-5, midy-2, 5, 5);
385
* Overides default read object in order to reload icons.
386
* This is necessary because for some strange reason animated
387
* gifs stop being animated after being serialized/deserialized.
389
* @param ois an <code>ObjectInputStream</code> value
390
* @exception IOException if an error occurs
391
* @exception ClassNotFoundException if an error occurs
393
private void readObject(ObjectInputStream ois)
394
throws IOException, ClassNotFoundException {
396
ois.defaultReadObject();
397
remove(m_visualLabel);
398
m_visualLabel = new JLabel(m_icon);
399
loadIcons(m_iconPath, m_animatedIconPath);
400
add(m_visualLabel, BorderLayout.CENTER);
401
Dimension d = m_visualLabel.getPreferredSize();
402
Dimension d2 = new Dimension((int)d.getWidth() + 10,
403
(int)d.getHeight() + 10);
405
setPreferredSize(d2);
407
} catch (Exception ex) {
408
ex.printStackTrace();