All Downloads are FREE. Search and download functionalities are using the official Maven repository.

weka.gui.beans.BeanVisual Maven / Gradle / Ivy

Go to download

The Waikato Environment for Knowledge Analysis (WEKA), a machine learning workbench. This version represents the developer version, the "bleeding edge" of development, you could say. New functionality gets added to this version.

There is a newer version: 3.9.6
Show newest version
/*
 *   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 weka.core.WekaPackageClassLoaderManager;

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: 13476 $
 * @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 = WekaPackageClassLoaderManager.getWekaPackageClassLoaderManager().findResource(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 = WekaPackageClassLoaderManager.getWekaPackageClassLoaderManager().findResource(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();
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy