BeanConnection.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 13k
Category:

Windows Develop

Development Platform:

Java

  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.  *    BeanConnection.java
  18.  *    Copyright (C) 2002 Mark Hall
  19.  *
  20.  */
  21. package weka.gui.beans;
  22. import java.io.Serializable;
  23. import java.lang.reflect.Method;
  24. import java.util.Vector;
  25. import java.beans.Beans;
  26. import java.beans.EventSetDescriptor;
  27. import java.beans.BeanInfo;
  28. import java.beans.Introspector;
  29. import java.awt.Component;
  30. import java.awt.Graphics;
  31. import java.awt.Point;
  32. import java.awt.Color;
  33. import javax.swing.JComponent;
  34. import java.beans.EventSetDescriptor;
  35. /**
  36.  * Class for encapsulating a connection between two beans. Also
  37.  * maintains a list of all connections
  38.  *
  39.  * @author <a href="mailto:mhall@cs.waikato.ac.nz">Mark Hall</a>
  40.  * @version $Revision: 1.1 $
  41.  */
  42. public class BeanConnection implements Serializable {
  43.   /**
  44.    * The list of connections
  45.    */
  46.   public static Vector CONNECTIONS = new Vector();
  47.   // details for this connection
  48.   private BeanInstance m_source;
  49.   private BeanInstance m_target;
  50.   /**
  51.    * The name of the event for this connection
  52.    */
  53.   private String m_eventName;
  54.   /**
  55.    * Reset the list of connections
  56.    */
  57.   public static void reset() {
  58.     CONNECTIONS = new Vector();
  59.   }
  60.   /**
  61.    * Returns the list of connections
  62.    *
  63.    * @return the list of connections
  64.    */
  65.   public static Vector getConnections() {
  66.     return CONNECTIONS;
  67.   }
  68.   /**
  69.    * Describe <code>setConnections</code> method here.
  70.    *
  71.    * @param connections a <code>Vector</code> value
  72.    */
  73.   public static void setConnections(Vector connections) {
  74.     CONNECTIONS = connections;
  75.   }
  76.   /**
  77.    * Returns true if there is a link between the supplied source and
  78.    * target BeanInstances at an earlier index than the supplied index
  79.    *
  80.    * @param source the source BeanInstance
  81.    * @param target the target BeanInstance
  82.    * @param index the index to compare to
  83.    * @return true if there is already a link at an earlier index
  84.    */
  85.   private static boolean previousLink(BeanInstance source, BeanInstance target,
  86.       int index) {
  87.     for (int i = 0; i < CONNECTIONS.size(); i++) {
  88.       BeanConnection bc = (BeanConnection)CONNECTIONS.elementAt(i);
  89.       BeanInstance compSource = bc.getSource();
  90.       BeanInstance compTarget = bc.getTarget();
  91.       if (compSource == source && compTarget == target && index < i) {
  92. return true;
  93.       }
  94.     }
  95.     return false;
  96.   }
  97.   /**
  98.    * Renders the connections and their names on the supplied graphics
  99.    * context
  100.    *
  101.    * @param gx a <code>Graphics</code> value
  102.    */
  103.   public static void paintConnections(Graphics gx) {
  104.     for (int i = 0; i < CONNECTIONS.size(); i++) {
  105.       BeanConnection bc = (BeanConnection)CONNECTIONS.elementAt(i);
  106.       BeanInstance source = bc.getSource();
  107.       BeanInstance target = bc.getTarget();
  108.       EventSetDescriptor srcEsd = bc.getSourceEventSetDescriptor();
  109.       BeanVisual sourceVisual = (source.getBean() instanceof Visible) ?
  110. ((Visible)source.getBean()).getVisual() :
  111. null;
  112.       BeanVisual targetVisual = (target.getBean() instanceof Visible) ?
  113. ((Visible)target.getBean()).getVisual() :
  114. null;
  115.       if (sourceVisual != null && targetVisual != null) {
  116. Point bestSourcePt = 
  117.   sourceVisual.getClosestConnectorPoint(
  118.        new Point((target.getX()+(target.getWidth()/2)), 
  119.  (target.getY() + (target.getHeight() / 2))));
  120. Point bestTargetPt = 
  121.   targetVisual.getClosestConnectorPoint(
  122.        new Point((source.getX()+(source.getWidth()/2)), 
  123.  (source.getY() + (source.getHeight() / 2))));
  124. gx.setColor(Color.red);
  125. boolean active = true;
  126. if (source.getBean() instanceof EventConstraints) {
  127.   if (!((EventConstraints) source.getBean()).
  128.       eventGeneratable(srcEsd.getName())) {
  129.     gx.setColor(Color.gray); // link not active at this time
  130.     active = false;
  131.   }
  132. }
  133. gx.drawLine((int)bestSourcePt.getX(), (int)bestSourcePt.getY(),
  134.     (int)bestTargetPt.getX(), (int)bestTargetPt.getY());
  135. // paint the connection name
  136. int midx = (int)bestSourcePt.getX();
  137. midx += (int)((bestTargetPt.getX() - bestSourcePt.getX()) / 2);
  138. int midy = (int)bestSourcePt.getY();
  139. midy += (int)((bestTargetPt.getY() - bestSourcePt.getY()) / 2) - 2 ;
  140. gx.setColor((active) ? Color.blue : Color.gray);
  141. if (previousLink(source, target, i)) {
  142.   midy -= 15;
  143. }
  144. gx.drawString(srcEsd.getName(), midx, midy);
  145.       }
  146.     }
  147.   }
  148.   /**
  149.    * Return a list of connections within some delta of a point
  150.    *
  151.    * @param pt the point at which to look for connections
  152.    * @param delta connections have to be within this delta of the point
  153.    * @return a list of connections
  154.    */
  155.   public static Vector getClosestConnections(Point pt, int delta) {
  156.     Vector closestConnections = new Vector();
  157.     
  158.     for (int i = 0; i < CONNECTIONS.size(); i++) {
  159.       BeanConnection bc = (BeanConnection)CONNECTIONS.elementAt(i);
  160.       BeanInstance source = bc.getSource();
  161.       BeanInstance target = bc.getTarget();
  162.       EventSetDescriptor srcEsd = bc.getSourceEventSetDescriptor();
  163.       BeanVisual sourceVisual = (source.getBean() instanceof Visible) ?
  164. ((Visible)source.getBean()).getVisual() :
  165. null;
  166.       BeanVisual targetVisual = (target.getBean() instanceof Visible) ?
  167. ((Visible)target.getBean()).getVisual() :
  168. null;
  169.       if (sourceVisual != null && targetVisual != null) {
  170. Point bestSourcePt = 
  171.   sourceVisual.getClosestConnectorPoint(
  172.        new Point((target.getX()+(target.getWidth()/2)), 
  173.  (target.getY() + (target.getHeight() / 2))));
  174. Point bestTargetPt = 
  175.   targetVisual.getClosestConnectorPoint(
  176.        new Point((source.getX()+(source.getWidth()/2)), 
  177.  (source.getY() + (source.getHeight() / 2))));
  178. int minx = (int) Math.min(bestSourcePt.getX(), bestTargetPt.getX());
  179. int maxx = (int) Math.max(bestSourcePt.getX(), bestTargetPt.getX());
  180. int miny = (int) Math.min(bestSourcePt.getY(), bestTargetPt.getY());
  181. int maxy = (int) Math.max(bestSourcePt.getY(), bestTargetPt.getY());
  182. // check to see if supplied pt is inside bounding box
  183. if (pt.getX() >= minx-delta && pt.getX() <= maxx+delta && 
  184.     pt.getY() >= miny-delta && pt.getY() <= maxy+delta) {
  185.   // now see if the point is within delta of the line
  186.   // formulate ax + by + c = 0
  187.   double a = bestSourcePt.getY() - bestTargetPt.getY();
  188.   double b = bestTargetPt.getX() - bestSourcePt.getX();
  189.   double c = (bestSourcePt.getX() * bestTargetPt.getY()) -
  190.     (bestTargetPt.getX() * bestSourcePt.getY());
  191.   
  192.   double distance = Math.abs((a * pt.getX()) + (b * pt.getY()) + c);
  193.   distance /= Math.abs(Math.sqrt((a*a) + (b*b)));
  194.   if (distance <= delta) {
  195.     closestConnections.addElement(bc);
  196.   }
  197. }
  198.       }
  199.     }
  200.     return closestConnections;
  201.   }
  202.   /**
  203.    * Remove all connections for a bean. If the bean is a target for
  204.    * receiving events then it gets deregistered from the corresonding
  205.    * source bean. If the bean is a source of events then all targets 
  206.    * implementing BeanCommon are notified via their
  207.    * disconnectionNotification methods that the source (and hence the
  208.    * connection) is going away.
  209.    *
  210.    * @param instance the bean to remove connections to/from
  211.    */
  212.   public static void removeConnections(BeanInstance instance) {
  213.     
  214.     Vector removeVector = new Vector();
  215.     for (int i = 0; i < CONNECTIONS.size(); i++) {
  216.       // In cases where this instance is the target, deregister it
  217.       // as a listener for the source
  218.       BeanConnection bc = (BeanConnection)CONNECTIONS.elementAt(i);
  219.       BeanInstance tempTarget = bc.getTarget();
  220.       BeanInstance tempSource = bc.getSource();
  221.       EventSetDescriptor tempEsd = bc.getSourceEventSetDescriptor();
  222.       if (instance == tempTarget) {
  223. // try to deregister the target as a listener for the source
  224. try {
  225.   Method deregisterMethod = tempEsd.getRemoveListenerMethod();
  226.   Object targetBean = tempTarget.getBean();
  227.   Object [] args = new Object[1];
  228.   args[0] = targetBean;
  229.   deregisterMethod.invoke(tempSource.getBean(), args);
  230.   System.err.println("Deregistering listener");
  231.   removeVector.addElement(bc);
  232. } catch (Exception ex) {
  233.   ex.printStackTrace();
  234. }
  235.       } else if (instance == tempSource) {
  236. removeVector.addElement(bc);
  237. if (tempTarget.getBean() instanceof BeanCommon) {
  238.   // tell the target that the source is going away, therefore
  239.   // this type of connection is as well
  240.   ((BeanCommon)tempTarget.getBean()).
  241.     disconnectionNotification(tempEsd.getName(),
  242.       tempSource.getBean());
  243. }
  244.       }
  245.     }
  246.     for (int i = 0; i < removeVector.size(); i++) {
  247.       System.err.println("removing connection");
  248.       CONNECTIONS.removeElement((BeanConnection)removeVector.elementAt(i));
  249.     }
  250.   }
  251.   /**
  252.    * Creates a new <code>BeanConnection</code> instance.
  253.    *
  254.    * @param source the source bean
  255.    * @param target the target bean
  256.    * @param esd the EventSetDescriptor for the connection
  257.    */
  258.   public BeanConnection(BeanInstance source, BeanInstance target,
  259. EventSetDescriptor esd) {
  260.     m_source = source;
  261.     m_target = target;
  262.     //    m_sourceEsd = sourceEsd;
  263.     m_eventName = esd.getName();
  264.     System.err.println(m_eventName);
  265.     // attempt to connect source and target beans
  266.     Method registrationMethod = 
  267.       //      m_sourceEsd.getAddListenerMethod();
  268.       //      getSourceEventSetDescriptor().getAddListenerMethod();
  269.       esd.getAddListenerMethod();
  270.     Object targetBean = m_target.getBean();
  271.     Object [] args = new Object[1];
  272.     args[0] = targetBean;
  273.     Class listenerClass = esd.getListenerType();
  274.     if (listenerClass.isInstance(targetBean)) {
  275.       try {
  276. registrationMethod.invoke(m_source.getBean(), args);
  277. // if the target implements BeanCommon, then inform
  278. // it that it has been registered as a listener with a source via
  279. // the named listener interface
  280. if (targetBean instanceof BeanCommon) {
  281.   ((BeanCommon)targetBean).
  282.     connectionNotification(esd.getName(), m_source.getBean());
  283. }
  284. CONNECTIONS.addElement(this);
  285.       } catch (Exception ex) {
  286. System.err.println("Unable to connect beans (BeanConnection)");
  287. ex.printStackTrace();
  288.       }
  289.     } else {
  290.       System.err.println("Unable to connect beans (BeanConnection)");
  291.     }
  292.   }
  293.   
  294.   /**
  295.    * Remove this connection
  296.    */
  297.   public void remove() {
  298.     EventSetDescriptor tempEsd = getSourceEventSetDescriptor();
  299.     // try to deregister the target as a listener for the source
  300.     try {
  301.       Method deregisterMethod = tempEsd.getRemoveListenerMethod();
  302.       Object targetBean = getTarget().getBean();
  303.       Object [] args = new Object[1];
  304.       args[0] = targetBean;
  305.       deregisterMethod.invoke(getSource().getBean(), args);
  306.       System.err.println("Deregistering listener");
  307.     } catch (Exception ex) {
  308.       ex.printStackTrace();
  309.     }
  310.     if (getTarget().getBean() instanceof BeanCommon) {
  311.       // tell the target that this connection is going away
  312.       ((BeanCommon)getTarget().getBean()).
  313. disconnectionNotification(tempEsd.getName(),
  314.   getSource().getBean());
  315.     }
  316.     CONNECTIONS.remove(this);
  317.   }
  318.   /**
  319.    * returns the source BeanInstance for this connection
  320.    *
  321.    * @return a <code>BeanInstance</code> value
  322.    */
  323.   protected BeanInstance getSource() {
  324.     return m_source;
  325.   }
  326.   /**
  327.    * Returns the target BeanInstance for this connection
  328.    *
  329.    * @return a <code>BeanInstance</code> value
  330.    */
  331.   protected BeanInstance getTarget() {
  332.     return m_target;
  333.   }
  334.   /**
  335.    * Returns the event set descriptor for the event generated by the source
  336.    * for this connection
  337.    *
  338.    * @return an <code>EventSetDescriptor</code> value
  339.    */
  340.   protected EventSetDescriptor getSourceEventSetDescriptor() {
  341.     JComponent bc = (JComponent)m_source.getBean();
  342.      try {
  343.        BeanInfo sourceInfo = Introspector.getBeanInfo(bc.getClass());
  344.        if (sourceInfo == null) {
  345.        System.err.println("Error");
  346.        } else {
  347.  EventSetDescriptor [] esds = sourceInfo.getEventSetDescriptors();
  348.  for (int i = 0; i < esds.length; i++) {
  349.    if (esds[i].getName().compareTo(m_eventName) == 0) {
  350.      return esds[i];
  351.    }
  352.  }
  353.        }
  354.      } catch (Exception ex) {
  355.        System.err.println("Problem retrieving event set descriptor (BeanConnection)");
  356.      }
  357.      return null;
  358.      
  359.      //    return m_sourceEsd;
  360.   }
  361. }