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

weka.gui.beans.BeanInstance 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 .
 */

/*
 *    BeanInstance.java
 *    Copyright (C) 2002-2012 University of Waikato, Hamilton, New Zealand
 *
 */

package weka.gui.beans;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.beans.Beans;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.JComponent;

/**
 * Class that manages a set of beans.
 * 
 * @author Mark Hall
 * @version $Revision: 10221 $
 * @since 1.0
 */
public class BeanInstance implements Serializable {

  /** for serialization */
  private static final long serialVersionUID = -7575653109025406342L;

  private static ArrayList> TABBED_COMPONENTS = new ArrayList>();

  /*
   * static { Vector initial = new Vector(); TABBED_COMPONENTS.add(initial); }
   */

  /**
   * Sets up just a single collection of bean instances in the first element of
   * the list. This is useful for clients that are using XMLBeans to load beans.
   */
  public static void init() {
    TABBED_COMPONENTS.clear();
    TABBED_COMPONENTS.add(new Vector());
  }

  /**
   * class variable holding all the beans
   */
  // private static Vector COMPONENTS = new Vector();

  public static final int IDLE = 0;
  public static final int BEAN_EXECUTING = 1;

  /**
   * Holds the bean encapsulated in this instance
   */
  private Object m_bean;
  private int m_x;
  private int m_y;

  /**
   * Removes all beans from containing component
   * 
   * @param container a JComponent value
   */
  public static void removeAllBeansFromContainer(JComponent container,
    Integer... tab) {

    int index = 0;
    if (tab.length > 0) {
      index = tab[0].intValue();
    }

    Vector components = null;
    if (TABBED_COMPONENTS.size() > 0 && index < TABBED_COMPONENTS.size()) {
      components = TABBED_COMPONENTS.get(index);
    }

    if (container != null) {
      if (components != null) {
        for (int i = 0; i < components.size(); i++) {
          Object tempInstance = components.elementAt(i);
          Object tempBean = ((BeanInstance) tempInstance).getBean();
          if (Beans.isInstanceOf(tempBean, JComponent.class)) {
            container.remove((JComponent) tempBean);
          }
        }
      }
      container.revalidate();
    }
  }

  /**
   * Adds all beans to the supplied component
   * 
   * @param container a JComponent value
   */
  public static void addAllBeansToContainer(JComponent container,
    Integer... tab) {
    int index = 0;
    if (tab.length > 0) {
      index = tab[0].intValue();
    }

    Vector components = null;
    if (TABBED_COMPONENTS.size() > 0 && index < TABBED_COMPONENTS.size()) {
      components = TABBED_COMPONENTS.get(index);
    }

    if (container != null) {
      if (components != null) {
        for (int i = 0; i < components.size(); i++) {
          BeanInstance tempInstance = (BeanInstance) components.elementAt(i);
          Object tempBean = tempInstance.getBean();
          if (Beans.isInstanceOf(tempBean, JComponent.class)) {
            container.add((JComponent) tempBean);
          }
        }
      }
      container.revalidate();
    }
  }

  /**
   * Return the list of displayed beans
   * 
   * @param tab varargs parameter specifying the index of the collection of
   *          beans to return - if omitted then the first (i.e. primary)
   *          collection of beans is returned
   * 
   * @return a vector of beans
   */
  public static Vector getBeanInstances(Integer... tab) {
    Vector returnV = null;
    int index = 0;
    if (tab.length > 0) {
      index = tab[0].intValue();
    }
    if (TABBED_COMPONENTS.size() > 0) {
      returnV = TABBED_COMPONENTS.get(index);
    }

    return returnV;
  }

  /**
   * Adds the supplied collection of beans at the supplied index in the list of
   * collections. If the index is not supplied then the primary collection is
   * set (i.e. index 0). Also adds the beans to the supplied JComponent
   * container (if not null)
   * 
   * @param beanInstances a Vector value
   * @param container a JComponent value
   */
  public static void setBeanInstances(Vector beanInstances,
    JComponent container, Integer... tab) {
    removeAllBeansFromContainer(container, tab);

    if (container != null) {
      for (int i = 0; i < beanInstances.size(); i++) {
        Object bean = ((BeanInstance) beanInstances.elementAt(i)).getBean();
        if (Beans.isInstanceOf(bean, JComponent.class)) {
          container.add((JComponent) bean);
        }
      }
      container.revalidate();
      container.repaint();
    }

    int index = 0;
    if (tab.length > 0) {
      index = tab[0].intValue();
    }

    if (index < TABBED_COMPONENTS.size()) {
      TABBED_COMPONENTS.set(index, beanInstances);
    }

    // COMPONENTS = beanInstances;
  }

  /**
   * Adds the supplied collection of beans to the end of the list of collections
   * and to the JComponent container (if not null)
   * 
   * @param beanInstances the vector of bean instances to add
   * @param container
   */
  public static void addBeanInstances(Vector beanInstances,
    JComponent container) {
    // reset(container);

    if (container != null) {
      for (int i = 0; i < beanInstances.size(); i++) {
        Object bean = ((BeanInstance) beanInstances.elementAt(i)).getBean();
        if (Beans.isInstanceOf(bean, JComponent.class)) {
          container.add((JComponent) bean);
        }
      }
      container.revalidate();
      container.repaint();
    }

    TABBED_COMPONENTS.add(beanInstances);
  }

  /**
   * Remove the vector of bean instances from the supplied index in the list of
   * collections.
   * 
   * @param tab the index of the vector of beans to remove.
   */
  public static void removeBeanInstances(JComponent container, Integer tab) {

    if (tab >= 0 && tab < TABBED_COMPONENTS.size()) {
      System.out.println("Removing vector of beans at index: " + tab);
      removeAllBeansFromContainer(container, tab);
      TABBED_COMPONENTS.remove(tab.intValue());
    }
  }

  /**
   * Renders the textual labels for the beans.
   * 
   * @param gx a Graphics object on which to render the labels
   */
  public static void paintLabels(Graphics gx, Integer... tab) {
    int index = 0;
    if (tab.length > 0) {
      index = tab[0].intValue();
    }

    Vector components = null;
    if (TABBED_COMPONENTS.size() > 0 && index < TABBED_COMPONENTS.size()) {
      components = TABBED_COMPONENTS.get(index);
    }

    if (components != null) {
      gx.setFont(new Font(null, Font.PLAIN, 9));
      FontMetrics fm = gx.getFontMetrics();
      int hf = fm.getAscent();
      for (int i = 0; i < components.size(); i++) {
        BeanInstance bi = (BeanInstance) components.elementAt(i);
        if (!(bi.getBean() instanceof Visible)) {
          continue;
        }
        int cx = bi.getX();
        int cy = bi.getY();
        int width = ((JComponent) bi.getBean()).getWidth();
        int height = ((JComponent) bi.getBean()).getHeight();
        String label = ((Visible) bi.getBean()).getVisual().getText();
        int labelwidth = fm.stringWidth(label);
        if (labelwidth < width) {
          gx.drawString(label, (cx + (width / 2)) - (labelwidth / 2), cy
            + height + hf + 2);
        } else {
          // split label

          // find mid point
          int mid = label.length() / 2;
          // look for split point closest to the mid
          int closest = label.length();
          int closestI = -1;
          for (int z = 0; z < label.length(); z++) {
            if (label.charAt(z) < 'a') {
              if (Math.abs(mid - z) < closest) {
                closest = Math.abs(mid - z);
                closestI = z;
              }
            }
          }
          if (closestI != -1) {
            String left = label.substring(0, closestI);
            String right = label.substring(closestI, label.length());
            if (left.length() > 1 && right.length() > 1) {
              gx.drawString(left, (cx + (width / 2))
                - (fm.stringWidth(left) / 2), cy + height + (hf * 1) + 2);
              gx.drawString(right, (cx + (width / 2))
                - (fm.stringWidth(right) / 2), cy + height + (hf * 2) + 2);
            } else {
              gx.drawString(label, (cx + (width / 2))
                - (fm.stringWidth(label) / 2), cy + height + (hf * 1) + 2);
            }
          } else {
            gx.drawString(label, (cx + (width / 2))
              - (fm.stringWidth(label) / 2), cy + height + (hf * 1) + 2);
          }
        }
      }
    }
  }

  /**
   * Returns a list of start points (if any) in the indexed flow
   * 
   * @param tab varargs integer index of the flow to search for start points.
   *          Defaults to 0 if not supplied.
   * @return a list of BeanInstances who's beans implement Startable
   */
  public static List getStartPoints(Integer... tab) {
    List startPoints = new ArrayList();

    int index = 0;
    if (tab.length > 0) {
      index = tab[0].intValue();
    }

    Vector components = null;
    if (TABBED_COMPONENTS.size() > 0 && index < TABBED_COMPONENTS.size()) {
      components = TABBED_COMPONENTS.get(index);

      for (int i = 0; i < components.size(); i++) {
        BeanInstance t = (BeanInstance) components.elementAt(i);
        if (t.getBean() instanceof Startable) {
          startPoints.add(t);
        }
      }
    }

    return startPoints;
  }

  /**
   * Search for a named bean in the indexed flow
   * 
   * @param beanName the name of the bean to look for
   * @param tab varargs integer index of the flow to search in
   * @return a matching BeanInstance or null if no match was found
   */
  public static BeanInstance findInstance(String beanName, Integer... tab) {
    BeanInstance found = null;

    int index = 0;
    if (tab.length > 0) {
      index = tab[0].intValue();
    }

    Vector components = null;
    if (TABBED_COMPONENTS.size() > 0 && index < TABBED_COMPONENTS.size()) {
      components = TABBED_COMPONENTS.get(index);

      for (int i = 0; i < components.size(); i++) {
        BeanInstance t = (BeanInstance) components.elementAt(i);

        if (t.getBean() instanceof BeanCommon) {
          String bN = ((BeanCommon) t).getCustomName();

          if (bN.equals(beanName)) {
            found = t;
            break;
          }
        }
      }
    }

    return found;
  }

  /**
   * Looks for a bean (if any) whose bounds contain the supplied point
   * 
   * @param p a point
   * @return a bean that contains the supplied point or null if no bean contains
   *         the point
   */
  public static BeanInstance findInstance(Point p, Integer... tab) {
    int index = 0;
    if (tab.length > 0) {
      index = tab[0].intValue();
    }

    Vector components = null;
    if (TABBED_COMPONENTS.size() > 0 && index < TABBED_COMPONENTS.size()) {
      components = TABBED_COMPONENTS.get(index);
    }

    Rectangle tempBounds = new Rectangle();
    for (int i = 0; i < components.size(); i++) {

      BeanInstance t = (BeanInstance) components.elementAt(i);
      JComponent temp = (JComponent) t.getBean();

      tempBounds = temp.getBounds(tempBounds);
      if (tempBounds.contains(p)) {
        return t;
      }
    }
    return null;
  }

  /**
   * Looks for all beans (if any) located within the supplied bounding box. Also
   * adjusts the bounding box to be a tight fit around all contained beans
   * 
   * @param boundingBox the bounding rectangle
   * @return a Vector of BeanInstances
   */
  public static Vector findInstances(Rectangle boundingBox,
    Integer... tab) {
    int index = 0;
    if (tab.length > 0) {
      index = tab[0].intValue();
    }

    Vector components = null;
    if (TABBED_COMPONENTS.size() > 0 && index < TABBED_COMPONENTS.size()) {
      components = TABBED_COMPONENTS.get(index);
    }

    Graphics gx = null;
    FontMetrics fm = null;

    int centerX, centerY;
    int minX = Integer.MAX_VALUE;
    int minY = Integer.MAX_VALUE;
    int maxX = Integer.MIN_VALUE;
    int maxY = Integer.MIN_VALUE;
    Vector result = new Vector();
    for (int i = 0; i < components.size(); i++) {
      BeanInstance t = (BeanInstance) components.elementAt(i);
      centerX = t.getX() + (t.getWidth() / 2);
      centerY = t.getY() + (t.getHeight() / 2);
      if (boundingBox.contains(centerX, centerY)) {
        result.addElement(t);

        // adjust bounding box stuff
        // int hf = 0;
        if (gx == null) {
          gx = ((JComponent) t.getBean()).getGraphics();
          gx.setFont(new Font(null, Font.PLAIN, 9));
          fm = gx.getFontMetrics();
          // hf = fm.getAscent();
        }
        String label = "";
        if (t.getBean() instanceof Visible) {
          label = ((Visible) t.getBean()).getVisual().getText();
        }
        int labelwidth = fm.stringWidth(label);
        /*
         * if (label.length() == 0) { heightMultiplier = 0; }
         */
        int brx = 0;
        int blx = 0;
        if (centerX - (labelwidth / 2) - 2 < t.getX()) {
          blx = (centerX - (labelwidth / 2) - 2);
          brx = centerX + (labelwidth / 2) + 2;
        } else {
          blx = t.getX() - 2;
          brx = t.getX() + t.getWidth() + 2;
        }

        if (blx < minX) {
          minX = blx;
        }
        if (brx > maxX) {
          maxX = brx;
        }
        if (t.getY() - 2 < minY) {
          minY = t.getY() - 2;
        }
        if (t.getY() + t.getHeight() + 2 > maxY) {
          maxY = t.getY() + t.getHeight() + 2;
        }
      }
    }
    boundingBox.setBounds(minX, minY, maxX - minX, maxY - minY);

    return result;
  }

  /**
   * Creates a new BeanInstance instance.
   * 
   * @param container a JComponent to add the bean to
   * @param bean the bean to add
   * @param x the x coordinate of the bean
   * @param y the y coordinate of the bean
   */
  public BeanInstance(JComponent container, Object bean, int x, int y,
    Integer... tab) {
    m_bean = bean;
    m_x = x;
    m_y = y;
    addBean(container, tab);
  }

  /**
   * Creates a new BeanInstance instance given the fully qualified
   * name of the bean
   * 
   * @param container a JComponent to add the bean to
   * @param beanName the fully qualified name of the bean
   * @param x the x coordinate of the bean
   * @param y th y coordinate of the bean
   */
  public BeanInstance(JComponent container, String beanName, int x, int y,
    Integer... tab) {
    m_x = x;
    m_y = y;

    // try and instantiate the named component
    try {
      m_bean = Beans.instantiate(null, beanName);
    } catch (Exception ex) {
      ex.printStackTrace();
      return;
    }

    addBean(container, tab);
  }

  /**
   * Remove this bean from the list of beans and from the containing component
   * 
   * @param container the JComponent that holds the bean
   */
  public void removeBean(JComponent container, Integer... tab) {
    int index = 0;
    if (tab.length > 0) {
      index = tab[0].intValue();
    }

    Vector components = null;
    if (TABBED_COMPONENTS.size() > 0 && index < TABBED_COMPONENTS.size()) {
      components = TABBED_COMPONENTS.get(index);
    }

    for (int i = 0; i < components.size(); i++) {
      if (components.elementAt(i) == this) {
        System.out.println("Removing bean");
        components.removeElementAt(i);
      }
    }
    if (container != null) {
      container.remove((JComponent) m_bean);
      container.revalidate();
      container.repaint();
    }
  }

  public static void appendBeans(JComponent container, Vector beans,
    int tab) {
    if (TABBED_COMPONENTS.size() > 0 && tab < TABBED_COMPONENTS.size()) {
      Vector components = TABBED_COMPONENTS.get(tab);
      //

      for (int i = 0; i < beans.size(); i++) {
        components.add(beans.get(i));
        if (container != null) {
          Object bean = ((BeanInstance) beans.elementAt(i)).getBean();
          if (Beans.isInstanceOf(bean, JComponent.class)) {
            container.add((JComponent) bean);
          }
        }
      }

      if (container != null) {
        container.revalidate();
        container.repaint();
      }
    }
  }

  /**
   * Adds this bean to the global list of beans and to the supplied container.
   * The constructor calls this method, so a client should not need to unless
   * they have called removeBean and then wish to have it added again.
   * 
   * @param container the Component on which this BeanInstance will be displayed
   */
  public void addBean(JComponent container, Integer... tab) {

    int index = 0;
    if (tab.length > 0) {
      index = tab[0].intValue();
    }

    Vector components = null;
    if (TABBED_COMPONENTS.size() > 0 && index < TABBED_COMPONENTS.size()) {
      components = TABBED_COMPONENTS.get(index);
    }

    // do nothing if we are already in the list
    if (components.contains(this)) {
      return;
    }

    // Ignore invisible components
    if (!Beans.isInstanceOf(m_bean, JComponent.class)) {
      System.out.println("Component is invisible!");
      return;
    }

    components.addElement(this);

    // Position and layout the component
    JComponent c = (JComponent) m_bean;
    Dimension d = c.getPreferredSize();
    int dx = (int) (d.getWidth() / 2);
    int dy = (int) (d.getHeight() / 2);
    m_x -= dx;
    m_y -= dy;
    c.setLocation(m_x, m_y);
    // c.doLayout();
    c.validate();
    // bp.addBean(c);
    // c.repaint();
    if (container != null) {
      container.add(c);
      container.revalidate();
    }
  }

  /**
   * Gets the bean encapsulated in this instance
   * 
   * @return an Object value
   */
  public Object getBean() {
    return m_bean;
  }

  /**
   * Gets the x coordinate of this bean
   * 
   * @return an int value
   */
  public int getX() {
    return m_x;
  }

  /**
   * Gets the y coordinate of this bean
   * 
   * @return an int value
   */
  public int getY() {
    return m_y;
  }

  /**
   * Gets the width of this bean
   * 
   * @return an int value
   */
  public int getWidth() {
    return ((JComponent) m_bean).getWidth();
  }

  /**
   * Gets the height of this bean
   * 
   * @return an int value
   */
  public int getHeight() {
    return ((JComponent) m_bean).getHeight();
  }

  /**
   * Set the x and y coordinates of this bean
   * 
   * @param newX the x coordinate
   * @param newY the y coordinate
   */
  public void setXY(int newX, int newY) {
    setX(newX);
    setY(newY);
    if (getBean() instanceof MetaBean) {
      ((MetaBean) getBean()).shiftBeans(this, false);
    }
  }

  /**
   * Sets the x coordinate of this bean
   * 
   * @param newX an int value
   */
  public void setX(int newX) {
    m_x = newX;
    ((JComponent) m_bean).setLocation(m_x, m_y);
    ((JComponent) m_bean).validate();
  }

  /**
   * Sets the y coordinate of this bean
   * 
   * @param newY an int value
   */
  public void setY(int newY) {
    m_y = newY;
    ((JComponent) m_bean).setLocation(m_x, m_y);
    ((JComponent) m_bean).validate();
  }
}