📄 beanconnection.java
字号:
/*
* 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.beans.IntrospectionException;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JComponent;
import javax.swing.JPopupMenu;
import javax.swing.JMenuItem;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
/**
* 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 $
*/
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;
// Should the connection be painted?
private boolean m_hidden = false;
/**
* 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;
}
/**
* A candidate BeanInstance can be an input if it is in the listToCheck
* and it is the source of a connection to a target that is in the
* listToCheck
*/
private static boolean checkForSource(BeanInstance candidate,
Vector listToCheck) {
for (int i = 0; i < CONNECTIONS.size(); i++) {
BeanConnection bc = (BeanConnection)CONNECTIONS.elementAt(i);
if (bc.getSource() != candidate) {
continue;
}
// check to see if target is in list
for (int j = 0; j < listToCheck.size(); j++) {
BeanInstance tempTarget = (BeanInstance)listToCheck.elementAt(j);
if (bc.getTarget() == tempTarget) {
return true;
}
}
}
return false;
}
/**
* A candidate BeanInstance can't be an input if it is the target
* of a connection from a source that is in the listToCheck
*/
private static boolean checkTargetConstraint(BeanInstance candidate,
Vector listToCheck) {
for (int i = 0; i < CONNECTIONS.size(); i++) {
BeanConnection bc = (BeanConnection)CONNECTIONS.elementAt(i);
if (bc.getTarget() == candidate) {
for (int j = 0; j < listToCheck.size(); j++) {
BeanInstance tempSource = (BeanInstance)listToCheck.elementAt(j);
if (bc.getSource() == tempSource) {
return false;
}
}
}
}
return true;
}
/**
* Returns a vector of BeanConnections associated with
* the supplied vector of BeanInstances, i.e. all connections
* that exist between those BeanInstances in the subFlow.
*
* @param subFlow a Vector of BeanInstances
* @return a Vector of BeanConnections
*/
public static Vector associatedConnections(Vector subFlow) {
Vector associatedConnections = new Vector();
for (int i = 0; i < CONNECTIONS.size(); i++) {
BeanConnection bc = (BeanConnection)CONNECTIONS.elementAt(i);
BeanInstance tempSource = bc.getSource();
BeanInstance tempTarget = bc.getTarget();
boolean sourceInSubFlow = false;
boolean targetInSubFlow = false;
for (int j = 0; j < subFlow.size(); j++) {
BeanInstance toCheck = (BeanInstance)subFlow.elementAt(j);
if (toCheck == tempSource) {
sourceInSubFlow = true;
}
if (toCheck == tempTarget) {
targetInSubFlow = true;
}
if (sourceInSubFlow && targetInSubFlow) {
associatedConnections.add(bc);
break;
}
}
}
return associatedConnections;
}
/**
* Returns a vector of BeanInstances that can be considered
* as inputs (or the left-hand side of a sub-flow)
*
* @param subset the sub-flow to examine
* @return a Vector of inputs to the sub-flow
*/
public static Vector inputs(Vector subset) {
Vector result = new Vector();
for (int i = 0; i < subset.size(); i++) {
BeanInstance temp = (BeanInstance)subset.elementAt(i);
// if (checkForSource(temp, subset)) {
// now check target constraint
if (checkTargetConstraint(temp, subset)) {
result.add(temp);
}
// }
}
return result;
}
/**
* A candidate BeanInstance can be an output if it is in the listToCheck
* and it is the target of a connection from a source that is in the
* listToCheck
*/
private static boolean checkForTarget(BeanInstance candidate,
Vector listToCheck) {
for (int i = 0; i < CONNECTIONS.size(); i++) {
BeanConnection bc = (BeanConnection)CONNECTIONS.elementAt(i);
if (bc.getTarget() != candidate) {
continue;
}
// check to see if source is in list
for (int j = 0; j < listToCheck.size(); j++) {
BeanInstance tempSource = (BeanInstance)listToCheck.elementAt(j);
if (bc.getSource() == tempSource) {
return true;
}
}
}
return false;
}
private static boolean isInList(BeanInstance candidate,
Vector listToCheck) {
for (int i = 0; i < listToCheck.size(); i++) {
BeanInstance temp = (BeanInstance)listToCheck.elementAt(i);
if (candidate == temp) {
return true;
}
}
return false;
}
/**
* A candidate BeanInstance can't be an output if it is the source
* of a connection only to target(s) that are in the listToCheck
*/
private static boolean checkSourceConstraint(BeanInstance candidate,
Vector listToCheck) {
boolean result = true;
for (int i = 0; i < CONNECTIONS.size(); i++) {
BeanConnection bc = (BeanConnection)CONNECTIONS.elementAt(i);
if (bc.getSource() == candidate) {
BeanInstance cTarget = bc.getTarget();
// is the target of this connection external to the list to check?
if (!isInList(cTarget, listToCheck)) {
return true;
}
for (int j = 0; j < listToCheck.size(); j++) {
BeanInstance tempTarget = (BeanInstance)listToCheck.elementAt(j);
if (bc.getTarget() == tempTarget) {
result = false;
}
}
}
}
return result;
}
/**
* Returns a vector of BeanInstances that can be considered
* as outputs (or the right-hand side of a sub-flow)
*
* @param subset the sub-flow to examine
* @return a Vector of outputs of the sub-flow
*/
public static Vector outputs(Vector subset) {
Vector result = new Vector();
for (int i = 0; i < subset.size(); i++) {
BeanInstance temp = (BeanInstance)subset.elementAt(i);
if (checkForTarget(temp, subset)) {
// now check source constraint
if (checkSourceConstraint(temp, subset)) {
// now check that this bean can actually produce some events
try {
BeanInfo bi = Introspector.getBeanInfo(temp.getBean().getClass());
EventSetDescriptor [] esd = bi.getEventSetDescriptors();
if (esd != null && esd.length > 0) {
result.add(temp);
}
} catch (IntrospectionException ex) {
// quietly ignore
}
}
}
}
return result;
}
/**
* 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);
if (!bc.isHidden()) {
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());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -