
org.yaoqiang.graph.handler.ConnectionHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of yaoqiang-bpmn-editor Show documentation
Show all versions of yaoqiang-bpmn-editor Show documentation
an Open Source BPMN 2.0 Modeler
package org.yaoqiang.graph.handler;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import org.yaoqiang.bpmn.model.elements.activities.AdHocSubProcess;
import org.yaoqiang.bpmn.model.elements.activities.BusinessRuleTask;
import org.yaoqiang.bpmn.model.elements.activities.CallActivity;
import org.yaoqiang.bpmn.model.elements.activities.ReceiveTask;
import org.yaoqiang.bpmn.model.elements.activities.ScriptTask;
import org.yaoqiang.bpmn.model.elements.activities.SendTask;
import org.yaoqiang.bpmn.model.elements.activities.ServiceTask;
import org.yaoqiang.bpmn.model.elements.activities.SubProcess;
import org.yaoqiang.bpmn.model.elements.activities.Task;
import org.yaoqiang.bpmn.model.elements.activities.Transaction;
import org.yaoqiang.bpmn.model.elements.events.EndEvent;
import org.yaoqiang.bpmn.model.elements.events.IntermediateCatchEvent;
import org.yaoqiang.bpmn.model.elements.events.IntermediateThrowEvent;
import org.yaoqiang.bpmn.model.elements.gateways.ComplexGateway;
import org.yaoqiang.bpmn.model.elements.gateways.EventBasedGateway;
import org.yaoqiang.bpmn.model.elements.gateways.ExclusiveGateway;
import org.yaoqiang.bpmn.model.elements.gateways.InclusiveGateway;
import org.yaoqiang.bpmn.model.elements.gateways.ParallelGateway;
import org.yaoqiang.bpmn.model.elements.humaninteraction.ManualTask;
import org.yaoqiang.bpmn.model.elements.humaninteraction.UserTask;
import org.yaoqiang.graph.model.GraphModel;
import org.yaoqiang.graph.swing.GraphComponent;
import org.yaoqiang.graph.util.GraphUtils;
import org.yaoqiang.graph.view.Graph;
import org.yaoqiang.util.Constants;
import org.yaoqiang.util.Resources;
import com.mxgraph.model.mxCell;
import com.mxgraph.model.mxGeometry;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.swing.handler.mxConnectionHandler;
import com.mxgraph.util.mxEvent;
import com.mxgraph.util.mxEventObject;
import com.mxgraph.util.mxPoint;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.view.mxCellState;
import com.mxgraph.view.mxGraph;
/**
* ConnectionHandler
*
* @author Shi Yaoqiang([email protected])
*/
public class ConnectionHandler extends mxConnectionHandler {
public boolean create = true;
public ConnectionHandler(mxGraphComponent graphComponent) {
super(graphComponent);
}
public GraphComponent getGraphComponent() {
return (GraphComponent) graphComponent;
}
public boolean isCreateTarget() {
Graph graph = getGraphComponent().getGraph();
GraphModel model = graph.getModel();
if (model.isEdge(source.getCell()) || model.isEndEvent(source.getCell()) || graph.isSwimlane(source.getCell())
|| model.isEventSubProcess(source.getCell()) || model.isParticipant(source.getCell()) || model.isChoreographyTask(source.getCell())
|| model.isChoreographySubprocess(source.getCell()) || model.isConversationNode(source.getCell())) {
return false;
}
return true;
}
public void mouseMoved(MouseEvent e) {
mouseDragged(e);
if (isHighlighting() && !marker.hasValidState()) {
source = null;
}
if (!isHighlighting() && source != null) {
int imgWidth = handleSize;
int imgHeight = handleSize;
if (connectIcon != null) {
imgWidth = connectIcon.getIconWidth();
imgHeight = connectIcon.getIconHeight();
}
int x = (int) source.getCenterX() - imgWidth / 2;
int y = (int) source.getCenterY() - imgHeight / 2;
if (graphComponent.getGraph().isSwimlane(source.getCell())) {
mxRectangle size = graphComponent.getGraph().getStartSize(source.getCell());
if (size.getWidth() > 0) {
x = (int) (source.getX() + size.getWidth() / 2 - imgWidth / 2);
} else {
y = (int) (source.getY() + size.getHeight() / 2 - imgHeight / 2);
}
} else if (getGraphComponent().getGraph().getModel().isExpandedSubProcess(source.getCell())) {
x = (int) (source.getX() + source.getWidth() - 12);
}
setBounds(new Rectangle(x, y, imgWidth, imgHeight));
} else {
setBounds(null);
}
if (source != null && (bounds == null || bounds.contains(e.getPoint()))) {
// ==============start==============
graphComponent.getGraphControl().setCursor(GraphUtils.getConnectCursor(graphComponent));
// ==============end================
e.consume();
}
}
public void mouseReleased(MouseEvent e) {
if (isActive()) {
if (error != null) {
if (error.length() > 0) {
// ==============start==============
JOptionPane.showMessageDialog(graphComponent, error, "Validation Error!", JOptionPane.WARNING_MESSAGE);
// ==============end================
}
} else if (first != null) {
mxGraph graph = graphComponent.getGraph();
double dx = first.getX() - e.getX();
double dy = first.getY() - e.getY();
if (connectPreview.isActive() && (marker.hasValidState() || isCreateTarget() || graph.isAllowDanglingEdges())) {
graph.getModel().beginUpdate();
try {
Object dropTarget = null;
Object vertex = source.getCell();
if (!marker.hasValidState() && isCreateTarget()) {
vertex = createTargetVertex(e, source.getCell());
dropTarget = graph.getDropTarget(new Object[] { vertex }, e.getPoint(), graphComponent.getCellAt(e.getX(), e.getY()));
if (vertex != null) {
// Disables edges as drop targets if the target cell was created
if (dropTarget == null || !graph.getModel().isEdge(dropTarget)) {
mxCellState pstate = graph.getView().getState(dropTarget);
if (pstate != null) {
mxGeometry geo = graph.getModel().getGeometry(vertex);
mxPoint origin = pstate.getOrigin();
geo.setX(geo.getX() - origin.getX());
geo.setY(geo.getY() - origin.getY());
}
} else {
dropTarget = graph.getDefaultParent();
}
graph.addCells(new Object[] { vertex }, dropTarget);
// FIXME: Here we pre-create the state for the vertex to be
// inserted in order to invoke update in the connectPreview.
// This means we have a cell state which should be created
// after the model.update, so this should be fixed.
mxCellState targetState = graph.getView().getState(vertex, true);
connectPreview.update(e, targetState, e.getX(), e.getY());
} else {
graphComponent.refresh();
}
}
if (vertex != null) {
Object cell = connectPreview.stop(graphComponent.isSignificant(dx, dy), e);
if (cell != null) {
if (vertex != source.getCell()) {
graph.setSelectionCell(vertex);
graphComponent.startEditing();
} else {
graph.setSelectionCell(cell);
}
eventSource.fireEvent(new mxEventObject(mxEvent.CONNECT, "cell", cell, "event", e, "target", dropTarget));
}
e.consume();
}
} finally {
graph.getModel().endUpdate();
}
}
}
}
reset();
}
public Object createTargetVertex(MouseEvent e, Object source) {
Graph graph = getGraphComponent().getGraph();
GraphModel model = graph.getModel();
graph.refresh();
connectPreview.update(e, null, e.getX(), e.getY());
final mxCell[] target = new mxCell[1];
target[0] = new mxCell();
target[0].setVertex(true);
target[0].setStyle("task");
final int width = Integer.parseInt(Constants.SETTINGS.getProperty("style_task_width", "85"));
final int height = Integer.parseInt(Constants.SETTINGS.getProperty("style_task_height", "55"));
final mxGeometry geo = new mxGeometry(0, 0, width, height);
target[0].setGeometry(geo);
final int gateWaySize = Integer.parseInt(Constants.SETTINGS.getProperty("style_gateway_size", "42"));
final mxGeometry gateWayGeo = new mxGeometry(0, 0, gateWaySize, gateWaySize);
final int subprocessWidth = Integer.parseInt(Constants.SETTINGS.getProperty("style_subprocess_width", "400"));
final int subprocessHeight = Integer.parseInt(Constants.SETTINGS.getProperty("style_subprocess_height", "250"));
final mxGeometry subprocessGeo = new mxGeometry(0, 0, 85, 55);
subprocessGeo.setAlternateBounds(new mxRectangle(0, 0, subprocessWidth, subprocessHeight));
final JDialog dialog = new JDialog() {
private static final long serialVersionUID = 2189389368898372086L;
protected JRootPane createRootPane() {
KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
JRootPane rootPane = new JRootPane();
rootPane.registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
create = false;
dispose();
}
}, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
return rootPane;
}
};
dialog.setModal(true);
dialog.setUndecorated(true);
if (Constants.JAVA_VERSION >= 1.6) {
dialog.setLocation(e.getLocationOnScreen());
} else {
dialog.setLocation(SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), null));
}
JMenuBar menuBar = new JMenuBar();
menuBar.setBorderPainted(false);
JMenu menu = menuBar.add(new JMenu(Resources.get("task")));
menu.add(new AbstractAction(Resources.get("task")) {
private static final long serialVersionUID = -1611245355110855186L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new Task(Resources.get("task")));
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("sendTask")) {
private static final long serialVersionUID = -3844960188265669082L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new SendTask(Resources.get("sendTask")));
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("receiveTask")) {
private static final long serialVersionUID = 1691280172715903327L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new ReceiveTask(Resources.get("receiveTask")));
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("serviceTask")) {
private static final long serialVersionUID = -8211002550564218740L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new ServiceTask(Resources.get("serviceTask")));
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("userTask")) {
private static final long serialVersionUID = 392290782993080476L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new UserTask(Resources.get("userTask")));
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("manualTask")) {
private static final long serialVersionUID = -7275303335441020154L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new ManualTask(Resources.get("manualTask")));
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("scriptTask")) {
private static final long serialVersionUID = -1666035613396497829L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new ScriptTask(Resources.get("scriptTask")));
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("businessRuleTask")) {
private static final long serialVersionUID = -3208987886595389014L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new BusinessRuleTask(Resources.get("businessRuleTask")));
create = true;
dialog.dispose();
}
});
menu = menuBar.add(new JMenu(Resources.get("subprocess")));
menu.add(new AbstractAction(Resources.get("subprocess")) {
private static final long serialVersionUID = -1611245355110855186L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new SubProcess(Resources.get("subprocess")));
target[0].setGeometry(subprocessGeo);
target[0].setStyle("subprocess;verticalAlign=middle");
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("tranSubProcess")) {
private static final long serialVersionUID = 1691280172715903327L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new Transaction(Resources.get("tranSubProcess")));
target[0].setGeometry(subprocessGeo);
target[0].setStyle("subprocess;verticalAlign=middle");
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("adHocSubProcess")) {
private static final long serialVersionUID = -8211002550564218740L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new AdHocSubProcess(Resources.get("adHocSubProcess")));
target[0].setGeometry(subprocessGeo);
target[0].setStyle("subprocess;verticalAlign=middle");
create = true;
dialog.dispose();
}
});
menu = menuBar.add(new JMenu(Resources.get("CallActivity")));
menu.add(new AbstractAction(Resources.get("callActivity")) {
private static final long serialVersionUID = -1611245355110855186L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new CallActivity(Resources.get("CallActivity"), "globalTask"));
target[0].setStyle("callTask");
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("callUser")) {
private static final long serialVersionUID = -3844960188265669082L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new CallActivity(Resources.get("CallActivity"), "globalUserTask"));
target[0].setStyle("callTask");
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("callManual")) {
private static final long serialVersionUID = 1691280172715903327L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new CallActivity(Resources.get("CallActivity"), "globalManualTask"));
target[0].setStyle("callTask");
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("callScript")) {
private static final long serialVersionUID = -8211002550564218740L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new CallActivity(Resources.get("CallActivity"), "globalScriptTask"));
target[0].setStyle("callTask");
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("callBusinessRule")) {
private static final long serialVersionUID = 392290782993080476L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new CallActivity(Resources.get("CallActivity"), "globalBusinessRuleTask"));
target[0].setStyle("callTask");
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("callProcess")) {
private static final long serialVersionUID = -7275303335441020154L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new CallActivity(Resources.get("CallActivity"), "callProcess"));
target[0].setStyle("callProcess");
create = true;
dialog.dispose();
}
});
menu = menuBar.add(new JMenu(Resources.get("gateway")));
menu.add(new AbstractAction(Resources.get("exclusiveGateway")) {
private static final long serialVersionUID = -1611245355110855186L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new ExclusiveGateway(Resources.get("exclusiveGateway")));
target[0].setGeometry(gateWayGeo);
target[0].setStyle("exclusiveGateway");
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("exclusiveGatewayWithIndicator")) {
private static final long serialVersionUID = -3844960188265669082L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new ExclusiveGateway(Resources.get("exclusiveGateway")));
target[0].setGeometry(gateWayGeo);
target[0].setStyle("exclusiveGatewayWithIndicator");
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("parallelGateway")) {
private static final long serialVersionUID = 1691280172715903327L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new ParallelGateway(Resources.get("parallelGateway")));
target[0].setGeometry(gateWayGeo);
target[0].setStyle("gateway");
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("inclusiveGateway")) {
private static final long serialVersionUID = -8211002550564218740L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new InclusiveGateway(Resources.get("inclusiveGateway")));
target[0].setGeometry(gateWayGeo);
target[0].setStyle("gateway");
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("complexGateway")) {
private static final long serialVersionUID = 392290782993080476L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new ComplexGateway(Resources.get("complexGateway")));
target[0].setGeometry(gateWayGeo);
target[0].setStyle("gateway");
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("eventGateway")) {
private static final long serialVersionUID = -7275303335441020154L;
public void actionPerformed(ActionEvent e) {
target[0].setValue(new EventBasedGateway(Resources.get("eventGateway")));
target[0].setGeometry(gateWayGeo);
target[0].setStyle("gateway");
create = true;
dialog.dispose();
}
});
menu = menuBar.add(new JMenu(Resources.get("event")));
menu.add(new AbstractAction(Resources.get("intermediateThrowEvent")) {
private static final long serialVersionUID = 8410063499332903660L;
public void actionPerformed(ActionEvent e) {
String size = Constants.SETTINGS.getProperty("style_intermediateThrowEvent_size", "32");
mxGeometry geo = new mxGeometry(0, 0, Integer.parseInt(size), Integer.parseInt(size));
target[0].setValue(new IntermediateThrowEvent(Resources.get("intermediateThrowEvent")));
target[0].setGeometry(geo);
target[0].setStyle("intermediateEvent");
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("intermediateCatchEvent")) {
private static final long serialVersionUID = 8608648819131423456L;
public void actionPerformed(ActionEvent e) {
String size = Constants.SETTINGS.getProperty("style_intermediateCatchEvent_size", "32");
mxGeometry geo = new mxGeometry(0, 0, Integer.parseInt(size), Integer.parseInt(size));
target[0].setValue(new IntermediateCatchEvent(Resources.get("intermediateCatchEvent")));
target[0].setGeometry(geo);
target[0].setStyle("intermediateEvent");
create = true;
dialog.dispose();
}
});
menu.add(new AbstractAction(Resources.get("endEvent")) {
private static final long serialVersionUID = -581622438562374357L;
public void actionPerformed(ActionEvent e) {
String size = Constants.SETTINGS.getProperty("style_endEvent_size", "32");
mxGeometry geo = new mxGeometry(0, 0, Integer.parseInt(size), Integer.parseInt(size));
target[0].setValue(new EndEvent(Resources.get("endEvent")));
target[0].setGeometry(geo);
target[0].setStyle("endEvent");
create = true;
dialog.dispose();
}
});
menu = menuBar.add(new JMenu(new AbstractAction("", new ImageIcon(ConnectionHandler.class.getResource("/org/yaoqiang/images/close.png"))) {
private static final long serialVersionUID = -1878271033938524199L;
public void actionPerformed(ActionEvent e) {
}
}));
menu.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
create = false;
dialog.dispose();
}
});
dialog.add(menuBar);
dialog.pack();
dialog.setVisible(true);
if (!create) {
return null;
}
if (target.length == 1) {
Object clone = graph.cloneCells(target)[0];
if (Constants.SETTINGS.getProperty("labelWrap", "0").equals("1")) {
model.setStyle(clone, model.getStyle(clone) + ";whiteSpace=wrap;");
GraphUtils.setElementStyles(graph, clone, "whiteSpace");
}
mxGeometry newGeo = model.getGeometry(clone);
if (newGeo != null) {
mxPoint point = graphComponent.getPointForEvent(e);
newGeo.setX(graph.snap(point.getX() - newGeo.getWidth() / 2));
newGeo.setY(graph.snap(point.getY() - newGeo.getHeight() / 2));
}
return clone;
}
return null;
}
public void paint(Graphics g) {
if (bounds != null) {
if (connectIcon != null) {
g.drawImage(connectIcon.getImage(), bounds.x, bounds.y, bounds.width, bounds.height, null);
} else if (handleEnabled) {
// ==============start==============
g.setColor(Color.BLACK);
g.draw3DRect(bounds.x, bounds.y, bounds.width - 1, bounds.height - 1, true);
g.setColor(Color.BLUE);
g.fill3DRect(bounds.x + 1, bounds.y + 1, bounds.width - 2, bounds.height - 2, true);
// ==============end================
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy