beanconnection.java

来自「wekaUT是 university texas austin 开发的基于wek」· Java 代码 · 共 422 行

JAVA
422
字号
/* *    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 2 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, write to the Free Software *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* *    BeanConnection.java *    Copyright (C) 2002 Mark Hall * */package weka.gui.beans;import java.io.Serializable;import java.lang.reflect.Method;import java.util.Vector;import java.beans.Beans;import java.beans.EventSetDescriptor;import java.beans.BeanInfo;import java.beans.Introspector;import java.awt.Component;import java.awt.Graphics;import java.awt.Point;import java.awt.Color;import javax.swing.JComponent;import java.beans.EventSetDescriptor;/** * Class for encapsulating a connection between two beans. Also * maintains a list of all connections * * @author <a href="mailto:mhall@cs.waikato.ac.nz">Mark Hall</a> * @version $Revision: 1.1.1.1 $ */public class BeanConnection implements Serializable {  /**   * The list of connections   */  public static Vector CONNECTIONS = new Vector();  // details for this connection  private BeanInstance m_source;  private BeanInstance m_target;  /**   * The name of the event for this connection   */  private String m_eventName;  /**   * Reset the list of connections   */  public static void reset() {    CONNECTIONS = new Vector();  }  /**   * Returns the list of connections   *   * @return the list of connections   */  public static Vector getConnections() {    return CONNECTIONS;  }  /**   * Describe <code>setConnections</code> method here.   *   * @param connections a <code>Vector</code> value   */  public static void setConnections(Vector connections) {    CONNECTIONS = connections;  }  /**   * Returns true if there is a link between the supplied source and   * target BeanInstances at an earlier index than the supplied index   *   * @param source the source BeanInstance   * @param target the target BeanInstance   * @param index the index to compare to   * @return true if there is already a link at an earlier index   */  private static boolean previousLink(BeanInstance source, BeanInstance target,				      int index) {    for (int i = 0; i < CONNECTIONS.size(); i++) {      BeanConnection bc = (BeanConnection)CONNECTIONS.elementAt(i);      BeanInstance compSource = bc.getSource();      BeanInstance compTarget = bc.getTarget();      if (compSource == source && compTarget == target && index < i) {	return true;      }    }    return false;  }  /**   * Renders the connections and their names on the supplied graphics   * context   *   * @param gx a <code>Graphics</code> value   */  public static void paintConnections(Graphics gx) {    for (int i = 0; i < CONNECTIONS.size(); i++) {      BeanConnection bc = (BeanConnection)CONNECTIONS.elementAt(i);      BeanInstance source = bc.getSource();      BeanInstance target = bc.getTarget();      EventSetDescriptor srcEsd = bc.getSourceEventSetDescriptor();      BeanVisual sourceVisual = (source.getBean() instanceof Visible) ?	((Visible)source.getBean()).getVisual() :	null;      BeanVisual targetVisual = (target.getBean() instanceof Visible) ?	((Visible)target.getBean()).getVisual() :	null;      if (sourceVisual != null && targetVisual != null) {	Point bestSourcePt = 	  sourceVisual.getClosestConnectorPoint(		       new Point((target.getX()+(target.getWidth()/2)), 				 (target.getY() + (target.getHeight() / 2))));	Point bestTargetPt = 	  targetVisual.getClosestConnectorPoint(		       new Point((source.getX()+(source.getWidth()/2)), 				 (source.getY() + (source.getHeight() / 2))));	gx.setColor(Color.red);	boolean active = true;	if (source.getBean() instanceof EventConstraints) {	  if (!((EventConstraints) source.getBean()).	      eventGeneratable(srcEsd.getName())) {	    gx.setColor(Color.gray); // link not active at this time	    active = false;	  }	}	gx.drawLine((int)bestSourcePt.getX(), (int)bestSourcePt.getY(),		    (int)bestTargetPt.getX(), (int)bestTargetPt.getY());	// paint an arrow head	double angle;	try {	  double a = 	    (double)(bestSourcePt.getY() - 		     bestTargetPt.getY()) / 	    (double)(bestSourcePt.getX() - bestTargetPt.getX());	  angle = Math.atan(a);	} catch(Exception ex) {	  angle = Math.PI / 2;	}	//	Point arrowstart = new Point((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);	Point arrowstart = new Point(bestTargetPt.x,				     bestTargetPt.y);	Point arrowoffset = new Point((int)(7 * Math.cos(angle)), 				      (int)(7 * Math.sin(angle)));	Point arrowend;	if (bestSourcePt.getX() >= bestTargetPt.getX()) {	  	  arrowend = new Point(arrowstart.x + arrowoffset.x, 			       arrowstart.y + arrowoffset.y);	} else {	  arrowend = new Point(arrowstart.x - arrowoffset.x, 			       arrowstart.y - arrowoffset.y);	}	int xs[] = { arrowstart.x,		     arrowend.x + (int)(7 * Math.cos(angle + (Math.PI / 2))),		     arrowend.x + (int)(7 * Math.cos(angle - (Math.PI / 2)))};	int ys[] = { arrowstart.y,		     arrowend.y + (int)(7 * Math.sin(angle + (Math.PI / 2))),		     arrowend.y + (int)(7 * Math.sin(angle - (Math.PI / 2)))};	gx.fillPolygon(xs, ys, 3);	// ----	// paint the connection name	int midx = (int)bestSourcePt.getX();	midx += (int)((bestTargetPt.getX() - bestSourcePt.getX()) / 2);	int midy = (int)bestSourcePt.getY();	midy += (int)((bestTargetPt.getY() - bestSourcePt.getY()) / 2) - 2 ;	gx.setColor((active) ? Color.blue : Color.gray);	if (previousLink(source, target, i)) {	  midy -= 15;	}	gx.drawString(srcEsd.getName(), midx, midy);      }    }  }  /**   * Return a list of connections within some delta of a point   *   * @param pt the point at which to look for connections   * @param delta connections have to be within this delta of the point   * @return a list of connections   */  public static Vector getClosestConnections(Point pt, int delta) {    Vector closestConnections = new Vector();        for (int i = 0; i < CONNECTIONS.size(); i++) {      BeanConnection bc = (BeanConnection)CONNECTIONS.elementAt(i);      BeanInstance source = bc.getSource();      BeanInstance target = bc.getTarget();      EventSetDescriptor srcEsd = bc.getSourceEventSetDescriptor();      BeanVisual sourceVisual = (source.getBean() instanceof Visible) ?	((Visible)source.getBean()).getVisual() :	null;      BeanVisual targetVisual = (target.getBean() instanceof Visible) ?	((Visible)target.getBean()).getVisual() :	null;      if (sourceVisual != null && targetVisual != null) {	Point bestSourcePt = 	  sourceVisual.getClosestConnectorPoint(		       new Point((target.getX()+(target.getWidth()/2)), 				 (target.getY() + (target.getHeight() / 2))));	Point bestTargetPt = 	  targetVisual.getClosestConnectorPoint(		       new Point((source.getX()+(source.getWidth()/2)), 				 (source.getY() + (source.getHeight() / 2))));	int minx = (int) Math.min(bestSourcePt.getX(), bestTargetPt.getX());	int maxx = (int) Math.max(bestSourcePt.getX(), bestTargetPt.getX());	int miny = (int) Math.min(bestSourcePt.getY(), bestTargetPt.getY());	int maxy = (int) Math.max(bestSourcePt.getY(), bestTargetPt.getY());	// check to see if supplied pt is inside bounding box	if (pt.getX() >= minx-delta && pt.getX() <= maxx+delta && 	    pt.getY() >= miny-delta && pt.getY() <= maxy+delta) {	  // now see if the point is within delta of the line	  // formulate ax + by + c = 0	  double a = bestSourcePt.getY() - bestTargetPt.getY();	  double b = bestTargetPt.getX() - bestSourcePt.getX();	  double c = (bestSourcePt.getX() * bestTargetPt.getY()) -	    (bestTargetPt.getX() * bestSourcePt.getY());	  	  double distance = Math.abs((a * pt.getX()) + (b * pt.getY()) + c);	  distance /= Math.abs(Math.sqrt((a*a) + (b*b)));	  if (distance <= delta) {	    closestConnections.addElement(bc);	  }	}      }    }    return closestConnections;  }  /**   * Remove all connections for a bean. If the bean is a target for   * receiving events then it gets deregistered from the corresonding   * source bean. If the bean is a source of events then all targets    * implementing BeanCommon are notified via their   * disconnectionNotification methods that the source (and hence the   * connection) is going away.   *   * @param instance the bean to remove connections to/from   */  public static void removeConnections(BeanInstance instance) {        Vector removeVector = new Vector();    for (int i = 0; i < CONNECTIONS.size(); i++) {      // In cases where this instance is the target, deregister it      // as a listener for the source      BeanConnection bc = (BeanConnection)CONNECTIONS.elementAt(i);      BeanInstance tempTarget = bc.getTarget();      BeanInstance tempSource = bc.getSource();      EventSetDescriptor tempEsd = bc.getSourceEventSetDescriptor();      if (instance == tempTarget) {	// try to deregister the target as a listener for the source	try {	  Method deregisterMethod = tempEsd.getRemoveListenerMethod();	  Object targetBean = tempTarget.getBean();	  Object [] args = new Object[1];	  args[0] = targetBean;	  deregisterMethod.invoke(tempSource.getBean(), args);	  System.err.println("Deregistering listener");	  removeVector.addElement(bc);	} catch (Exception ex) {	  ex.printStackTrace();	}      } else if (instance == tempSource) {	removeVector.addElement(bc);	if (tempTarget.getBean() instanceof BeanCommon) {	  // tell the target that the source is going away, therefore	  // this type of connection is as well	  ((BeanCommon)tempTarget.getBean()).	    disconnectionNotification(tempEsd.getName(),				      tempSource.getBean());	}      }    }    for (int i = 0; i < removeVector.size(); i++) {      System.err.println("removing connection");      CONNECTIONS.removeElement((BeanConnection)removeVector.elementAt(i));    }  }  /**   * Creates a new <code>BeanConnection</code> instance.   *   * @param source the source bean   * @param target the target bean   * @param esd the EventSetDescriptor for the connection   */  public BeanConnection(BeanInstance source, BeanInstance target,			EventSetDescriptor esd) {    m_source = source;    m_target = target;    //    m_sourceEsd = sourceEsd;    m_eventName = esd.getName();    System.err.println(m_eventName);    // attempt to connect source and target beans    Method registrationMethod =       //      m_sourceEsd.getAddListenerMethod();      //      getSourceEventSetDescriptor().getAddListenerMethod();      esd.getAddListenerMethod();    Object targetBean = m_target.getBean();    Object [] args = new Object[1];    args[0] = targetBean;    Class listenerClass = esd.getListenerType();    if (listenerClass.isInstance(targetBean)) {      try {	registrationMethod.invoke(m_source.getBean(), args);	// if the target implements BeanCommon, then inform	// it that it has been registered as a listener with a source via	// the named listener interface	if (targetBean instanceof BeanCommon) {	  ((BeanCommon)targetBean).	    connectionNotification(esd.getName(), m_source.getBean());	}	CONNECTIONS.addElement(this);      } catch (Exception ex) {	System.err.println("Unable to connect beans (BeanConnection)");	ex.printStackTrace();      }    } else {      System.err.println("Unable to connect beans (BeanConnection)");    }  }    /**   * Remove this connection   */  public void remove() {    EventSetDescriptor tempEsd = getSourceEventSetDescriptor();    // try to deregister the target as a listener for the source    try {      Method deregisterMethod = tempEsd.getRemoveListenerMethod();      Object targetBean = getTarget().getBean();      Object [] args = new Object[1];      args[0] = targetBean;      deregisterMethod.invoke(getSource().getBean(), args);      System.err.println("Deregistering listener");    } catch (Exception ex) {      ex.printStackTrace();    }    if (getTarget().getBean() instanceof BeanCommon) {      // tell the target that this connection is going away      ((BeanCommon)getTarget().getBean()).	disconnectionNotification(tempEsd.getName(),				  getSource().getBean());    }    CONNECTIONS.remove(this);  }  /**   * returns the source BeanInstance for this connection   *   * @return a <code>BeanInstance</code> value   */  protected BeanInstance getSource() {    return m_source;  }  /**   * Returns the target BeanInstance for this connection   *   * @return a <code>BeanInstance</code> value   */  protected BeanInstance getTarget() {    return m_target;  }  /**   * Returns the event set descriptor for the event generated by the source   * for this connection   *   * @return an <code>EventSetDescriptor</code> value   */  protected EventSetDescriptor getSourceEventSetDescriptor() {    JComponent bc = (JComponent)m_source.getBean();     try {       BeanInfo sourceInfo = Introspector.getBeanInfo(bc.getClass());       if (sourceInfo == null) {       System.err.println("Error");       } else {	 EventSetDescriptor [] esds = sourceInfo.getEventSetDescriptors();	 for (int i = 0; i < esds.length; i++) {	   if (esds[i].getName().compareTo(m_eventName) == 0) {	     return esds[i];	   }	 }       }     } catch (Exception ex) {       System.err.println("Problem retrieving event set descriptor (BeanConnection)");     }     return null;          //    return m_sourceEsd;  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?