-
Notifications
You must be signed in to change notification settings - Fork 66
VWorkflows-Core provides a flow/graph model with multiple edge types and an abstract skin model that does not depend on a specific ui technology. Skins are created by factories that can be nested. They define hierarchical relations which allows for easy subflow visualization.
VWorkflows-FX is a JavaFX based UI for the core model. It utilizes components from the JFXtras project (Window control, ScalableContentPane). It supports
- subflow visualization
- arbitrary zoom levels
- multiple visualizations of the same flow (visualizations are synced and fully editable)
- zoom dependent visualization (level of detail)
- ...
// create a flow object
VFlow flow = FlowFactory.newFlow();
// add two nodes to the flow
VNode n1 = flow.newNode();
VNode n2 = flow.newNode();
// create input and output connectors of type "default-type"
Connector inN1 = n1.addInput("default-type");
Connector outN1 = n1.addOutput("default-type");
Connector inN2 = n2.addInput("default-type");
Connector outN2 = n2.addOutput("default-type");
// create a connections
flow.connect(outN1, inN2); // we assume a flow already exists
VFlow flow = ...
// make the flow visible
flow.setVisible(true);
// create a zoomable canvas
VCanvas canvas = new VCanvas();
Pane root = canvas.getContentPane();
// creating a skin factory and attach it to the flow
FXSkinFactory skinFactory = new FXSkinFactory(rootPane);
flow.setSkinFactories(skinFactory); // create a flow object
VFlow flow = FlowFactory.newFlow();
// create a subflow
VFlow subFlow = flow.newSubFlow(); WorkflowIO.saveToXML(Paths.get("flow-01.xml"), flow1.getModel()); VFlow flow = WorkflowIO.loadFromXML(Paths.get("flow-01.xml")); // we assume a flow already exists
VFlow flow = ...
// we assume that connector c1 and c2 exit
Connector c1 = ...
Connector c2 = ...
// check compatibility
ConnectionResult result = flow.tryConnect(c1,c2);
if (!result.getStatus().isCompatible()) {
// connection failed!
// use message string to create report status
String msg = result.getStatus().getMessage();
}It is not advised to access the UI directly. Sometimes, however, it is necessary to add UI framework specific functionality that is not part of the model.
NOTE: each VNode can be visualized by multiple views.
VNode n = ...
List<Window> windows = flow.getNodeSkinsById(n.getId()).stream().
filter(s -> s instanceof FXFlowNodeSkin).
map(s -> ((FXFlowNodeSkin) s).getNode()).
collect(Collectors.toList());It is not advised to access the UI directly. Sometimes, however, it is necessary to add UI framework specific functionality that is not part of the model.
NOTE: each Connector can be visualized by multiple views.
Connector c = ...
VNode n = c.getNode()
List<Node> connectorNodes = flow.getNodeSkinsById(n.getId()).stream().
filter(s -> s instanceof FXFlowNodeSkin).
map(s -> ((FXFlowNodeSkin) s).getgetConnectorNodeByReference(c)).
collect(Collectors.toList()); VNode n = ...
flow.getNodeSkinsById(n.getId()).stream().
filter(s -> s instanceof FXFlowNodeSkin).
map(s -> ((FXFlowNodeSkin) s).getNode()).
forEach(w->w.getLeftIcons().clear());This can be accomplished by creating a custom SkinFactory:
VFlow flow = ...
flow.setSkinFactories(new FXSkinFactory(root) {
@Override
public VNodeSkin createSkin(VNode n, VFlow flow) {
FXFlowNodeSkin skin = new FXFlowNodeSkin(this, getFxParent(), n, flow);
skin.getNode().getLeftIcons().add(new RotateIcon(skin.getNode()));
}
});VWorkflows uses a left-to-right layout for connectors/connections. Sometimes this is not flexible enougth. Therefore, it is possible to change the default behavior. The auto-layout positions input connectors either at the top or the left window border depending on incoming/outgoing connections.
Connector c = ...
c.getVisualizationRequest().set(VisualizationRequest.KEY_CONNECTOR_AUTO_LAYOUT, true);