source: src/main/java/weka/gui/beans/BeanVisual.java @ 9

Last change on this file since 9 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 11.9 KB
Line 
1/*
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.
6 *
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.
11 *
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.
15 */
16
17/*
18 *    BeanVisual.java
19 *    Copyright (C) 2002 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.gui.beans;
24
25import java.awt.BorderLayout;
26import java.awt.Color;
27import java.awt.Dimension;
28import java.awt.Graphics;
29import java.awt.Image;
30import java.awt.Point;
31import java.awt.Toolkit;
32import java.beans.PropertyChangeListener;
33import java.beans.PropertyChangeSupport;
34import java.io.IOException;
35import java.io.ObjectInputStream;
36import java.io.Serializable;
37
38import javax.swing.ImageIcon;
39import javax.swing.JLabel;
40import javax.swing.JPanel;
41
42/**
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.
46 *
47 * @author <a href="mailto:mhall@cs.waikato.ac.nz">Mark Hall</a>
48 * @version $Revision: 1.10 $
49 * @since 1.0
50 * @see JPanel
51 * @see Serializable
52 */
53public class BeanVisual
54  extends JPanel {
55
56  /** for serialization */
57  private static final long serialVersionUID = -6677473561687129614L;
58
59  public static final String ICON_PATH="weka/gui/beans/icons/";
60
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;
65
66  /**
67   * Holds name (including path) of the static icon
68   */
69  protected String m_iconPath;
70
71  /**
72   * Holds name (including path) of the animated icon
73   */
74  protected String m_animatedIconPath;
75
76  /**
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
80   */
81  protected transient ImageIcon m_icon;
82  protected transient ImageIcon m_animatedIcon;
83
84  /**
85   * Name for the bean
86   */
87  protected String m_visualName;
88
89  protected JLabel m_visualLabel;
90 
91  /**
92   * Container for the icon
93   */
94  //  protected IconHolder m_visualHolder;
95
96  //  protected JLabel m_textLabel;
97  private boolean m_stationary = true;
98
99  private PropertyChangeSupport m_pcs = new PropertyChangeSupport(this);
100 
101  private boolean m_displayConnectors = false;
102  private Color m_connectorColor = Color.blue;
103
104  /**
105   * Constructor
106   *
107   * @param visualName name for the bean
108   * @param iconPath path to the icon file
109   * @param animatedIconPath path to the animated icon file
110   */
111  public BeanVisual(String visualName, String iconPath, 
112                    String animatedIconPath) {
113
114    loadIcons(iconPath, animatedIconPath);
115    m_visualName = visualName;
116    //    m_textLabel = new JLabel(m_visualName, JLabel.CENTER);
117    m_visualLabel = new JLabel(m_icon);
118
119    setLayout(new BorderLayout());
120   
121    //    m_visualHolder = new IconHolder(m_visualLabel);
122   
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);
128    setMinimumSize(d2);
129    setPreferredSize(d2);
130    setMaximumSize(d2);
131  }
132
133  /**
134   * Reduce this BeanVisual's icon size by the given factor
135   *
136   * @param factor the factor by which to reduce the icon size by
137   */
138  public void scale(int factor) {
139    if (m_icon != null) {
140      removeAll();
141      Image pic = m_icon.getImage();
142      int width = m_icon.getIconWidth();
143      int height = m_icon.getIconHeight();
144      int reduction = width / factor;
145      width -= reduction;
146      height -= reduction;
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);
155      setMinimumSize(d2);
156      setPreferredSize(d2);
157      setMaximumSize(d2);   
158    }
159  }
160
161  /**
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.
170   *
171   * @param iconPath path to
172   * @param animatedIconPath a <code>String</code> value
173   */
174  public boolean loadIcons(String iconPath, String animatedIconPath) {
175    boolean success = true;
176    //    java.net.URL imageURL = ClassLoader.getSystemResource(iconPath);
177    java.net.URL imageURL = this.getClass().getClassLoader().getResource(iconPath);
178    if (imageURL == null) {
179      //      System.err.println("Warning: unable to load "+iconPath);
180    } else {
181      Image pic = Toolkit.getDefaultToolkit().
182        getImage(imageURL);
183
184      m_icon = new ImageIcon(pic);
185      if (m_visualLabel != null) {
186        m_visualLabel.setIcon(m_icon);
187      }
188    }
189   
190    //    imageURL = ClassLoader.getSystemResource(animatedIconPath);
191    imageURL = this.getClass().getClassLoader().getResource(animatedIconPath);
192    if (imageURL == null) {
193      //      System.err.println("Warning: unable to load "+animatedIconPath);
194      success = false;
195    } else {
196      Image pic2 = Toolkit.getDefaultToolkit().
197        getImage(imageURL);
198      m_animatedIcon = new ImageIcon(pic2);
199    }
200    m_iconPath = iconPath;
201    m_animatedIconPath = animatedIconPath;
202    return success;
203  }
204
205  /**
206   * Set the label for the visual. Informs any property change listeners
207   *
208   * @param text the label
209   */
210  public void setText(String text) {
211    m_visualName = text;
212    //    m_textLabel.setText(m_visualName);
213    m_pcs.firePropertyChange("label",null,null);
214  }
215
216  /**
217   * Get the visual's label
218   *
219   * @return a <code>String</code> value
220   */
221  public String getText() {
222    return m_visualName;
223  }
224
225  /**
226   * Set the static version of the icon
227   *
228   */
229  public void setStatic() {
230    m_visualLabel.setIcon(m_icon);
231  }
232
233  /**
234   * Set the animated version of the icon
235   *
236   */
237  public void setAnimated() {
238    m_visualLabel.setIcon(m_animatedIcon);
239  }
240
241  /**
242   * Returns the coordinates of the closest "connector" point to the
243   * supplied point. Coordinates are in the parent containers coordinate
244   * space.
245   *
246   * @param pt the reference point
247   * @return the closest connector point
248   */
249  public Point getClosestConnectorPoint(Point pt) {
250    int sourceX = getParent().getX();
251    int sourceY = getParent().getY();
252    int sourceWidth = getWidth();
253    int sourceHeight = getHeight();
254    int sourceMidX = sourceX + (sourceWidth / 2);
255    int sourceMidY = sourceY + (sourceHeight / 2);
256    int x = (int)pt.getX();
257    int y = (int)pt.getY();
258   
259    Point closest = new Point();
260    int cx = (Math.abs(x - sourceMidX) < Math.abs(y - sourceMidY)) ? 
261      sourceMidX :
262      ((x < sourceMidX) ? sourceX : sourceX + sourceWidth);
263    int cy = (Math.abs(y - sourceMidY) < Math.abs(x - sourceMidX)) ? 
264      sourceMidY :
265      ((y < sourceMidY) ? sourceY : sourceY + sourceHeight) ;
266    closest.setLocation(cx, cy);
267    return closest;
268  }
269
270  /**
271   * Returns the coordinates of the connector point given a compass point
272   *
273   * @param compassPoint a compass point
274   * @return a <code>Point</code> value
275   */
276  public Point getConnectorPoint(int compassPoint) {
277    int sourceX = getParent().getX();
278    int sourceY = getParent().getY();
279    int sourceWidth = getWidth();
280    int sourceHeight = getHeight();
281    int sourceMidX = sourceX + (sourceWidth / 2);
282    int sourceMidY = sourceY + (sourceHeight / 2);
283
284    switch (compassPoint) {
285    case NORTH_CONNECTOR : return new Point(sourceMidX, sourceY);
286    case SOUTH_CONNECTOR : return new Point(sourceMidX, sourceY+sourceHeight);
287    case WEST_CONNECTOR :  return new Point(sourceX, sourceMidY);
288    case EAST_CONNECTOR :  return new Point(sourceX+sourceWidth, sourceMidY);
289    default : System.err.println("Unrecognised connectorPoint (BeanVisual)");
290    }
291    return new Point(sourceX, sourceY);
292  }
293
294  /**
295   * Returns the static icon
296   *
297   * @return an <code>ImageIcon</code> value
298   */
299  public ImageIcon getStaticIcon() {
300    return m_icon;
301  }
302
303  /**
304   * Returns the animated icon
305   *
306   * @return an <code>ImageIcon</code> value
307   */
308  public ImageIcon getAnimatedIcon() {
309    return m_animatedIcon;
310  }
311
312  /**
313   * returns the path for the icon
314   *
315   * @return the path for the icon
316   */
317  public String getIconPath() {
318    return m_iconPath;
319  }
320
321  /**
322   * returns the path for the animated icon
323   *
324   * @return the path for the animated icon
325   */
326  public String getAnimatedIconPath() {
327    return m_animatedIconPath;
328  }
329
330  /**
331   * Turn on/off the connector points
332   *
333   * @param dc a <code>boolean</code> value
334   */
335  public void setDisplayConnectors(boolean dc) {
336    //    m_visualHolder.setDisplayConnectors(dc);
337    m_displayConnectors = dc;
338    m_connectorColor = Color.blue;
339    repaint();
340  }
341
342  /**
343   * Turn on/off the connector points
344   *
345   * @param dc a <code>boolean</code> value
346   * @param c the Color to use
347   */
348  public void setDisplayConnectors(boolean dc,
349                                   Color c) {
350    setDisplayConnectors(dc);
351    m_connectorColor = c;
352  }
353
354  /**
355   * Add a listener for property change events
356   *
357   * @param pcl a <code>PropertyChangeListener</code> value
358   */
359  public void addPropertyChangeListener(PropertyChangeListener pcl) {
360    m_pcs.addPropertyChangeListener(pcl);
361  }
362
363  /**
364   * Remove a property change listener
365   *
366   * @param pcl a <code>PropertyChangeListener</code> value
367   */
368  public void removePropertyChangeListener(PropertyChangeListener pcl) {
369    m_pcs.removePropertyChangeListener(pcl);
370  }
371
372  public void paintComponent(Graphics gx) {
373    super.paintComponent(gx);
374    if (m_displayConnectors) {
375      gx.setColor(m_connectorColor);
376     
377      int midx = (int)(this.getWidth() / 2.0);
378      int midy = (int)(this.getHeight() / 2.0);
379      gx.fillOval(midx-2, 0, 5, 5);
380      gx.fillOval(midx-2, this.getHeight()-5, 5, 5);
381      gx.fillOval(0, midy-2, 5, 5);
382      gx.fillOval(this.getWidth()-5, midy-2, 5, 5);
383    }
384  }
385
386  /**
387   * Overides default read object in order to reload icons.
388   * This is necessary because for some strange reason animated
389   * gifs stop being animated after being serialized/deserialized.
390   *
391   * @param ois an <code>ObjectInputStream</code> value
392   * @exception IOException if an error occurs
393   * @exception ClassNotFoundException if an error occurs
394   */
395  private void readObject(ObjectInputStream ois) 
396    throws IOException, ClassNotFoundException {
397    try {
398      ois.defaultReadObject();
399      remove(m_visualLabel);
400      m_visualLabel = new JLabel(m_icon);
401      loadIcons(m_iconPath, m_animatedIconPath);
402      add(m_visualLabel, BorderLayout.CENTER);
403      Dimension d = m_visualLabel.getPreferredSize();
404      Dimension d2 = new Dimension((int)d.getWidth() + 10, 
405                                   (int)d.getHeight() + 10);
406      setMinimumSize(d2);
407      setPreferredSize(d2);
408      setMaximumSize(d2);   
409    } catch (Exception ex) {
410      ex.printStackTrace();
411    }
412  }
413}
Note: See TracBrowser for help on using the repository browser.