Skip to content
miho edited this page Nov 4, 2014 · 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.getContentPane();

    // creating a skin factory and attach it to the flow
    FXSkinFactory skinFactory = new FXSkinFactory(rootPane);
    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?

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

How can I load flows?

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

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 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 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);
Clone this wiki locally