Skip to content
Daniel Ziltener edited this page Dec 11, 2017 · 25 revisions

What is the difference between VWorkflows-core and -fx?

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)
  • ...

How can I create a simple workflow?

// 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);

How to visualize flows with JavaFX?

// 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.getContent();

// creating a skin factory and attach it to the flow
FXSkinFactory skinFactory = new FXSkinFactory(root);
flow.setSkinFactories(skinFactory);

How to create subflows?

// create a flow object
VFlow flow = FlowFactory.newFlow();
    
// create a subflow
VFlow subFlow = flow.newSubFlow();

How can I save flows?

NOTE: Serialization contains bugs that need fixing! Looking for volunteers!

WorkflowIO.saveToXML(Paths.get("flow-01.xml"), flow1.getModel());

How can I load flows?

NOTE: Serialization contains bugs that need fixing! Looking for volunteers!

VFlow flow = WorkflowIO.loadFromXML(Paths.get("flow-01.xml"));

How can I check whether connectors are compatible?

// 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();
}

How Can I get all receivers of a node?

To get a collection of all receivers of a node (nodes that are connected with an output of the node) it is necessary to request this information from the connections object of the parent flow.

Example (receivers of a node)

List<VNode> receivers
    = sender.getOutputs().stream().
      flatMap(o -> flow.getConnections(o.getType()).
      getAllWith(o).stream()).
      map(conn -> conn.getReceiver().getNode()).
      collect(Collectors.toList());

How can I access the skin of VNodes?

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.

Example (collect all windows of a VNode):

VNode n = ...

List<Window> windows = flow.getNodeSkinsById(n.getId()).stream().
            filter(s -> s instanceof FXFlowNodeSkin).
            map(s -> ((FXFlowNodeSkin) s).getNode()).
            collect(Collectors.toList());

How can I access the skin of a Connector?

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.

Example (collect all nodes of a Connector):

Connector c = ...
VNode n = c.getNode()

List<Node> connectorNodes = 
       flow.getNodeSkinsById(n.getId()).stream().
       filter(s -> s instanceof FXFlowNodeSkin).
       map(s -> ((FXFlowNodeSkin) s).
       getConnectorNodeByReference(c)).
       collect(Collectors.toList());

How can I add or remove icons from the node window?

Example (remove all left icons from a node window):

VNode n = ...

flow.getNodeSkinsById(n.getId()).stream().
       filter(s -> s instanceof FXFlowNodeSkin).
       map(s -> ((FXFlowNodeSkin) s).getNode()).
       forEach(w->w.getLeftIcons().clear());

How can I override the JavaFX node generation?

This can be accomplished by creating a custom SkinFactory:

Example (adding a rotation icon to each window):

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()));
        return skin;
    }
});

How can I specify the connector layout?

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 VNode/window border depending on incoming/outgoing connections.

Example (auto-layout)

Connector c = ...
c.getVisualizationRequest().set(
  VisualizationRequest.KEY_CONNECTOR_AUTO_LAYOUT, true);

How can I specify custom connector sizes?

VWorkflows automatically computes the connector size depending on the VNode/window size and the number of connectors. Sometimes, the connector sizes are not optimal. VisualizationRequests support maximum and minimum connector sizes.

Example (maximum connector size)

VNode n = ...
n.getVisualizationRequest().set(
  VisualizationRequest.KEY_MAX_CONNECTOR_SIZE, 10.0);

How can I disable edit capabilities?

To prevent VNodes/windows from being dragged around VisualizationRequest.KEY_DISABLE_EDITING can be used to disable editing capabilities.

NOTE: VNodes/windows still receive mouse events. They just don't move and cannot be resized.

Example (disabling edit capabilities)

VNode n = ...
n.getVisualizationRequest().set(
  VisualizationRequest.KEY_DISABLE_EDITING, true);