-
Notifications
You must be signed in to change notification settings - Fork 67
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);
VWorkflows automatically computes the connector size depending on the window size and the number of connectors. Sometimes, the connector sizes are not optimal. VisualizationRequests
support maximum and minimum connector sizes.
VNode n = ...
n.getVisualizationRequest().set(
VisualizationRequest.KEY_MAX_CONNECTOR_SIZE, 10.0);