
org.yaoqiang.graph.swing.GraphComponent 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.swing;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.print.PageFormat;
import java.util.EventObject;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.ToolTipManager;
import org.w3c.dom.Document;
import org.yaoqiang.bpmn.model.elements.activities.Activity;
import org.yaoqiang.bpmn.model.elements.activities.AdHocSubProcess;
import org.yaoqiang.bpmn.model.elements.choreographyactivities.ChoreographyActivity;
import org.yaoqiang.bpmn.model.elements.core.common.FlowNode;
import org.yaoqiang.bpmn.model.elements.core.foundation.BaseElement;
import org.yaoqiang.bpmn.model.elements.events.BoundaryEvent;
import org.yaoqiang.graph.handler.ConnectionHandler;
import org.yaoqiang.graph.handler.GraphHandler;
import org.yaoqiang.graph.model.GraphModel;
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.io.mxCodec;
import com.mxgraph.model.mxICell;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.swing.view.mxICellEditor;
import com.mxgraph.util.mxConstants;
import com.mxgraph.util.mxUtils;
import com.mxgraph.view.mxCellState;
/**
* GraphComponent
*
* @author Shi Yaoqiang([email protected])
*/
public class GraphComponent extends mxGraphComponent {
private static final long serialVersionUID = 5582918475032396064L;
protected Point popupPoint;
protected Point pasteToPoint;
protected Object lastViewRoot;
public GraphComponent(Graph graph) {
super(graph);
// Sets switches typically used in an editor
setPageVisible(true);
setVerticalPageCount(getGraph().getModel().getPageCount());
setHorizontalPageCount(getGraph().getModel().getHorizontalPageCount());
setGridVisible(Constants.SETTINGS.getProperty("showGrid", "1").equals("1"));
setGridStyle(Integer.parseInt(Constants.SETTINGS.getProperty("gridstyle", "3")));
setGridColor(mxUtils.parseColor(Constants.SETTINGS.getProperty("gridColor", "#c0c0c0")));
setToolTips(true);
setZoomFactor(1.05);
setTolerance(2);
setZoomPolicy(mxGraphComponent.ZOOM_POLICY_PAGE);
setKeepSelectionVisibleOnZoom(true);
setDragEnabled(false);
setPreferPageSize(true);
setEnterStopsCellEditing(true);
ToolTipManager.sharedInstance().setDismissDelay(Integer.MAX_VALUE);
getConnectionHandler().setHandleEnabled(true);
getConnectionHandler().setCreateTarget(true);
// setTripleBuffered(true);
// getGraphHandler().setRemoveCellsFromParent(false);
if (Constants.SETTINGS.getProperty("showRulers", "1").equals("1")) {
setColumnHeaderView(new Ruler(this, Ruler.ORIENTATION_HORIZONTAL));
setRowHeaderView(new Ruler(this, Ruler.ORIENTATION_VERTICAL));
}
// Loads the defalt stylesheet from an external file
mxCodec codec = new mxCodec();
Document doc = mxUtils.loadDocument(GraphComponent.class.getResource(Constants.DEFAULT_STYLE_XML).toString());
codec.decode(doc.getDocumentElement(), graph.getStylesheet());
// Sets PageFormat
Constants.PAGE_WIDTH = Double.parseDouble(Constants.SETTINGS.getProperty("pageWidth", String.valueOf(11.7 * 72)));
Constants.PAGE_HEIGHT = Double.parseDouble(Constants.SETTINGS.getProperty("pageHeight", String.valueOf(8.3 * 72)));
PageFormat pageFormat = getGraph().getModel().setDefaultPageFormat();
setPageFormat(pageFormat);
mxConstants.DEFAULT_STARTSIZE = Integer.parseInt(Constants.SETTINGS.getProperty("style_swimlane_title_size", "25"));
Constants.SWIMLANE_WIDTH = (int) (pageFormat.getWidth() * 1.25 + (getGraph().getModel().getHorizontalPageCount() - 1)
* (Constants.SWIMLANE_START_POINT + pageFormat.getWidth() * 1.25));
Constants.SWIMLANE_HEIGHT = (int) (pageFormat.getHeight() * 1.2 + (getGraph().getModel().getPageCount() - 1)
* (Constants.SWIMLANE_START_POINT + pageFormat.getHeight() * 1.2));
// Sets the background to white
getViewport().setOpaque(true);
getViewport().setBackground(Color.WHITE);
setFocusTraversalKeysEnabled(false);
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
startEditing();
} else if (e.getKeyCode() == KeyEvent.VK_TAB) {
if ((e.getModifiers() & KeyEvent.SHIFT_MASK) != 0) {
getGraph().selectPreviousCell();
} else {
getGraph().selectNextCell();
}
}
}
});
}
public Graph getGraph() {
return (Graph) graph;
}
public Point getPopupPoint() {
return popupPoint;
}
public void setPopupPoint(Point popupPoint) {
this.popupPoint = popupPoint;
}
public Point getPasteToPoint() {
return pasteToPoint;
}
public void setPasteToPoint(Point pasteToPoint) {
this.pasteToPoint = pasteToPoint;
}
public Object getLastViewRoot() {
return lastViewRoot;
}
public void setLastViewRoot(Object lastViewRoot) {
this.lastViewRoot = lastViewRoot;
}
protected ConnectionHandler createConnectionHandler() {
return new ConnectionHandler(this);
}
protected GraphHandler createGraphHandler() {
return new GraphHandler(this);
}
protected mxICellEditor createCellEditor() {
return new CellEditor(this);
}
public Object[] importCells(Object[] cells, double dx, double dy, Object target, Point location) {
if (cells[0] instanceof mxICell) {
mxICell dropCell = (mxICell) cells[0];
Graph graph = getGraph();
GraphModel model = graph.getModel();
if ("org".equals(getName()) && !graph.isOrganizationElement(dropCell) || !"org".equals(getName()) && !"GraphEditor".equals(getName())
&& graph.isOrganizationElement(dropCell)) {
return null;
}
if (target == null) {
target = graph.getCurrentRoot();
}
if (graph.isSwimlane(dropCell)) {
if (target == null) {
if (model.isLane(dropCell) || GraphUtils.hasSwimlane(graph, !graph.isVerticalSwimlane(dropCell))) {
return null;
}
} else {
if (graph.isSwimlane(target)) {
if (model.isPool(dropCell) || (graph.isVerticalSwimlane(dropCell) && !graph.isVerticalSwimlane(target))
|| (!graph.isVerticalSwimlane(dropCell) && graph.isVerticalSwimlane(target))) {
return null;
}
} else {
JOptionPane.showMessageDialog(null, Resources.get("WarningSubProcessCannotContainPool"), "Not Supported",
JOptionPane.WARNING_MESSAGE);
return null;
}
}
} else {
if (target == null && dropCell.getParent() == null && dropCell.getId() != null && dropCell.isVertex()) {
if (graph.isChoreography(dropCell) || graph.isSubChoreography(dropCell)) {
JOptionPane.showMessageDialog(null, Resources.get("WarningCopyPasteNotApplicableForChoreography"), "Not Applicable",
JOptionPane.WARNING_MESSAGE);
return null;
}
mxICell srcCell = (mxICell) getCellAt((int) dropCell.getGeometry().getX(), (int) dropCell.getGeometry().getY());
if (getPasteToPoint() != null) {
srcCell = (mxICell) getCellAt(getPasteToPoint().x, getPasteToPoint().y);
}
if (srcCell == null) {
target = null;
} else if (dropCell.getId().equals(srcCell.getId())) {
target = model.getParent(srcCell);
} else {
if (model.isSubProcess(srcCell) || graph.isSwimlane(srcCell)) {
target = srcCell;
} else {
target = model.getParent(srcCell);
}
}
}
}
if (dropCell.isVertex() && !graph.isOrganizationElement(dropCell)) {
if (model.isMessage(dropCell)) {
GraphUtils.setElementStyles(graph, dropCell, "init");
}
if (Constants.SETTINGS.getProperty("labelWrap", "0").equals("1")) {
model.setStyle(dropCell, dropCell.getStyle() + ";whiteSpace=wrap;");
GraphUtils.setElementStyles(graph, dropCell, "whiteSpace");
}
}
if (dropCell.getValue() instanceof BoundaryEvent) {
if (target == null || (!model.isTask(target) && !model.isSubProcess(target) && !model.isCallActivity(target))) {
JOptionPane.showMessageDialog(null, Resources.get("WarningBoundaryEventMustBeAttachedToActivityBoundary"), "Validation Error!",
JOptionPane.WARNING_MESSAGE);
return null;
}
}
}
return graph.moveCells(cells, dx, dy, true, target, location);
}
public ImageIcon getFoldingIcon(mxCellState state) {
if (state != null) {
// ==============start==============
if (getGraph().getModel().isCollapsedSubProcess(state.getCell())) {
return new ImageIcon(GraphComponent.class.getResource("/org/yaoqiang/graph/shape/markers/subprocess.png"));
// ==============end================
} else {
if (isFoldingEnabled() && !graph.getModel().isEdge(state.getCell())) {
Object cell = state.getCell();
boolean tmp = graph.isCellCollapsed(cell);
if (graph.isCellFoldable(cell, !tmp)) {
return (tmp) ? collapsedIcon : expandedIcon;
}
}
}
}
return null;
}
public Rectangle getFoldingIconBounds(mxCellState state, ImageIcon icon) {
if (getGraph().getModel().isCollapsedSubProcess(state.getCell())) {
FlowNode flowNode = (FlowNode) ((mxICell) state.getCell()).getValue();
double scale = getGraph().getView().getScale();
Rectangle iconBounds = state.getRectangle();
int imgWidth = (int) (32 * scale);
int imgHeight = (int) (16 * scale);
String compensationMarker = null;
String loopMarker = null;
if (flowNode instanceof Activity) {
Activity subProcess = (Activity) flowNode;
compensationMarker = subProcess.isForCompensation() ? "" : null;
if (subProcess.getLoopCharacteristics() != null) {
loopMarker = "";
}
} else if (flowNode instanceof ChoreographyActivity) {
ChoreographyActivity subProcess = (ChoreographyActivity) flowNode;
if (!subProcess.getLoopType().equals("None")) {
loopMarker = "";
}
}
if (flowNode instanceof AdHocSubProcess) {
if (loopMarker != null || compensationMarker != null) {
if (loopMarker != null && compensationMarker != null) {
iconBounds.setRect(iconBounds.getX() + iconBounds.getWidth() / 2, iconBounds.getY() + iconBounds.getHeight() - imgHeight, imgWidth / 2,
imgHeight);
} else {
iconBounds.setRect(iconBounds.getX() + (2 * iconBounds.getWidth() - imgWidth) / 4, iconBounds.getY() + iconBounds.getHeight()
- imgHeight, imgWidth / 2, imgHeight);
}
} else {
iconBounds.setRect(iconBounds.getX() + (iconBounds.getWidth() - imgWidth) / 2, iconBounds.getY() + iconBounds.getHeight() - imgHeight,
imgWidth / 2, imgHeight);
}
} else {
if (loopMarker != null || compensationMarker != null) {
if (loopMarker != null && compensationMarker != null) {
iconBounds.setRect(iconBounds.getX() + (2 * iconBounds.getWidth() + imgWidth) / 4, iconBounds.getY() + iconBounds.getHeight()
- imgHeight, imgWidth / 2, imgHeight);
} else {
iconBounds.setRect(iconBounds.getX() + iconBounds.getWidth() / 2, iconBounds.getY() + iconBounds.getHeight() - imgHeight, imgWidth / 2,
imgHeight);
}
} else {
iconBounds.setRect(iconBounds.getX() + (2 * iconBounds.getWidth() - imgWidth) / 4, iconBounds.getY() + iconBounds.getHeight() - imgHeight,
imgWidth / 2, imgHeight);
}
}
return iconBounds;
} else {
return super.getFoldingIconBounds(state, icon);
}
}
public boolean isGridEnabledEvent(MouseEvent event) {
boolean enable = Constants.SETTINGS.getProperty("snapToGrid", "0").equals("1");
return (event != null) ? enable ? !event.isAltDown() : event.isAltDown() : false;
}
public boolean isConstrainedEvent(MouseEvent event) {
return (event != null) ? event.isShiftDown() || getGraph().getModel().isBoundaryEvent(graph.getSelectionCell())
|| getGraph().getModel().isMessage(graph.getSelectionCell())
&& getGraph().getModel().isMessageFlow(graph.getModel().getParent(graph.getSelectionCell())) || getGraph().isAutoPool(graph.getSelectionCell())
: false;
}
public CellEditor getCellEditor() {
return (CellEditor) cellEditor;
}
public Object getEditingValue(Object cell, EventObject trigger) {
GraphModel model = getGraph().getModel();
if (model.isGroupArtifact(cell) || model.isDataStore(cell) || model.isDataObject(cell)) {
return model.getValue(cell);
} else if (model.isSequenceFlow(cell)) {
return ((BaseElement) model.getValue(cell)).get("name").toValue();
}
return graph.convertValueToString(cell);
}
public void startEditing() {
Object cell = graph.getSelectionCell();
if (getGraph().isChoreography(cell) || getGraph().isSubChoreography(cell)) {
cell = GraphUtils.getChoreographyActivity(getGraph(), cell);
}
startEditingAtCell(cell);
}
public void paintAuxiliaryLines(Graphics2D g, Rectangle bounds) {
g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[] { 30.0f, 3.0f, 2.0f, 3.0f }, 0.0f));
g.setColor(Color.BLACK);
g.drawLine(bounds.x, 0, bounds.x, graphControl.getHeight());
g.drawLine(bounds.x + bounds.width / 2, 0, bounds.x + bounds.width / 2, graphControl.getHeight());
g.drawLine(bounds.x + bounds.width, 0, bounds.x + bounds.width, graphControl.getHeight());
g.drawLine(0, bounds.y, graphControl.getWidth(), bounds.y);
g.drawLine(0, bounds.y + bounds.height / 2, graphControl.getWidth(), bounds.y + bounds.height / 2);
g.drawLine(0, bounds.y + bounds.height, graphControl.getWidth(), bounds.y + bounds.height);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy