Skip to content

Commit

Permalink
Merge pull request #77 from leewyatt/master
Browse files Browse the repository at this point in the history
Support for additional connections
  • Loading branch information
dlemmermann authored Aug 16, 2023
2 parents a0e4d11 + 9226b5f commit caa403b
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ public LinkStrategy<String> fromString(String string) {
scrollPane.setPrefWidth(220);
scrollPane.setFitToWidth(true);
parent.setRight(scrollPane);
primaryStage.setScene(new Scene(parent, 1280, 800));
Scene scene = new Scene(parent, 1280, 800);
scene.getStylesheets().add(TreeNodeViewApp.class.getResource("tree-node-view-app.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
CSSFX.start();

Expand Down Expand Up @@ -244,26 +246,34 @@ public static TreeNode<String> createTree2() {
TreeNode<String> root = new TreeNode<>("DO155 for DO");

TreeNode<String> node1 = new TreeNode<>("DO153 for DO");
node1.setExpanded(false);
//node1.setExpanded(false);
TreeNode<String> node2 = new TreeNode<>("DO155 for MOP");
node2.setExpanded(false);
//node2.setExpanded(false);
TreeNode<String> node3 = new TreeNode<>("DO155 for DC");
node3.setExpanded(false);
//node3.setExpanded(false);
root.getChildren().addAll(node1, node2, node3);

TreeNode<String> node11 = new TreeNode<>("D0011 from DA");
node11.setName("da");
TreeNode<String> node12 = new TreeNode<>("D0011 from MOP");
node12.setName("mop");
TreeNode<String> node13 = new TreeNode<>("D0011 from DC");
node13.setName("dc");

node1.getChildren().add(node11);
node2.getChildren().add(node12);
node3.getChildren().add(node13);


TreeNode<String> node121 = new TreeNode<>("Agent Concensus");
node121.setExpanded(false);
node121.setName("agent");
//node121.setExpanded(false);
node12.getChildren().add(node121);

node11.getLinkedNodes().addAll(node121);
node13.getLinkedNodes().add(node121);


TreeNode<String> node1211 = new TreeNode<>("D0148 for MOP");
TreeNode<String> node1212 = new TreeNode<>("D0148 for DC");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.tree-node-view .tree-content > .link-mop-agent.link-path,
.tree-node-view .tree-content > .link-extra-da-agent.link-line,
.tree-node-view .tree-content > .link-extra-dc-agent.link-line {
-fx-stroke: #DB5852;
}

.tree-node-view .tree-content > .link-mop-agent.link-arrow,
.tree-node-view .tree-content > .link-extra-da-agent.link-arrow,
.tree-node-view .tree-content > .link-extra-dc-agent.link-arrow {
-fx-background-color: #DB5852;
}
27 changes: 27 additions & 0 deletions gemsfx/src/main/java/com/dlsc/gemsfx/treeview/TreeNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,33 @@ public TreeNode(T value) {
setValue(value);
}

/**
* Represents the name identifier for this node.
* ------------------------------------------------
* The primary purpose of the 'name' is to assist in determining the style of the node and its links.
* For instance:
* 1. If the node's name is 'n', then the style class for the node would be 'node-n'.
* 2. For a regular parent-child relationship, if a node with name 'n' has a parent named 'm',
* the link connecting them will have a style class 'link-m-n'.
* 3. For any extra links, say from node 'p' to node 'n', the style class for the link would be 'link-extra-p-n'.
* ------------------------------------------------
* Important considerations:
* - If the 'name' is null, all the above rules become invalid.
* - Both the relevant node and the current node must possess non-null 'name' values for these styling rules to apply.
* ------------------------------------------------
* This naming convention aids in providing a systematic approach for styling, making it directly
* relatable to the node's relationship and connection type.
*/
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

private final ReadOnlyObjectWrapper<TreeNode<T>> parent = new ReadOnlyObjectWrapper<>(this, "parent", null);

public ReadOnlyObjectProperty<TreeNode<T>> parentProperty() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public class TreeNodeViewSkin<T> extends SkinBase<TreeNodeView<T>> {
private final Map<Integer, Double> levelToMaxDimensionMap = new HashMap<>();

private final List<TreeNode<T>> currentLevelNodesCache = new ArrayList<>();

private List<Node> additionalLinkedNodeList = new ArrayList<>();

private final Group contentGroup = new Group();

public TreeNodeViewSkin(TreeNodeView<T> view) {
Expand Down Expand Up @@ -89,11 +92,14 @@ private void addListenersToNode(TreeNode<T> node) {
node.getChildren().addListener(invalidationListener);
node.widthProperty().addListener(invalidationListener);
node.heightProperty().addListener(invalidationListener);
node.getLinkedNodes().addListener(invalidationListener);

// Add listeners to the new nodes (if any) and remove listeners from removed nodes (if any) when they are added/removed to/from the children list.
ListChangeListener<TreeNode<T>> nodeListChangeListener = createNodeListChangeListener();
childrenListListenerMap.put(node, nodeListChangeListener);
node.getChildren().addListener(nodeListChangeListener);
node.getLinkedNodes().addListener(nodeListChangeListener);

}

private void removeListenersFromNode(TreeNode<T> removedNode) {
Expand All @@ -107,11 +113,13 @@ private void removeListenersFromNode(TreeNode<T> removedNode) {
removedNode.getChildren().removeListener(invalidationListener);
removedNode.widthProperty().removeListener(invalidationListener);
removedNode.heightProperty().removeListener(invalidationListener);
removedNode.getLinkedNodes().removeListener(invalidationListener);
}

ListChangeListener<TreeNode<T>> nodeListChangeListener = childrenListListenerMap.remove(removedNode);
if (nodeListChangeListener != null) {
removedNode.getChildren().removeListener(nodeListChangeListener);
removedNode.getLinkedNodes().removeListener(nodeListChangeListener);
}

nodeToComponentsMap.remove(removedNode);
Expand Down Expand Up @@ -157,6 +165,7 @@ private void buildTree() {
if (root != null) {
calculatePositions(root);
drawNode(root);
drawAdditionalLinkedNodes();
} else {
contentGroup.getChildren().setAll(getSkinnable().getPlaceholder());
}
Expand Down Expand Up @@ -261,6 +270,10 @@ private void drawNode(TreeNode<T> node) {
return;
}
List<Node> nodes = view.getLinkStrategy().drawNodeLink(getSkinnable().getLayoutDirection(), levelToMaxDimensionMap.get(node.getLevel()), parent, parentPoint, computeNodeWidth(parent), computeNodeHeight(parent), node, point, computeNodeWidth(node), computeNodeHeight(node), view.getNodeLineGap(), view.getVgap(), view.getHgap());
if (parent.getName() != null && node.getName() != null) {
nodes.forEach(n -> n.getStyleClass().add("link-" + parent.getName() + "-" + node.getName()));
}

contentGroup.getChildren().addAll(nodes);
nodes.add(cell);
nodeToComponentsMap.put(node, nodes);
Expand Down Expand Up @@ -696,6 +709,29 @@ private void updateTree() {
if (root != null) {
calculatePositions(root);
drawNode(root);
drawAdditionalLinkedNodes();
}
}

private void drawAdditionalLinkedNodes() {
TreeNode<T> root = getSkinnable().getRoot();
if (root != null) {
root.stream().forEach(this::drawLinksForNode);
}
}

private void drawLinksForNode(TreeNode<T> node) {
Point2D sourcePosition = nodeToPositionMap.get(node);
for (TreeNode<T> linkedNode : node.getLinkedNodes()) {
Point2D targetPosition = nodeToPositionMap.get(linkedNode);
if (sourcePosition != null && targetPosition != null) {
List<Node> nodes = getSkinnable().getLinkStrategy().drawNodeLink(getSkinnable().getLayoutDirection(), levelToMaxDimensionMap.get(node.getLevel()), node, sourcePosition, computeNodeWidth(node), computeNodeHeight(node), linkedNode, targetPosition, computeNodeWidth(linkedNode), computeNodeHeight(linkedNode), getSkinnable().getNodeLineGap(), getSkinnable().getVgap(), getSkinnable().getHgap());
if (node.getName() != null && linkedNode.getName() != null) {
nodes.forEach(n -> n.getStyleClass().add("link-extra-" + node.getName() + "-" + linkedNode.getName()));
}
contentGroup.getChildren().addAll(nodes);
additionalLinkedNodeList.addAll(nodes);
}
}
}

Expand All @@ -704,6 +740,7 @@ private void updateTree() {
*/
private void clearMapsForUpdate() {
nodeToComponentsMap.clear();
additionalLinkedNodeList.clear();
nodeToPositionMap.clear();
nodeTotalDimensionMap.clear();
levelToMaxDimensionMap.clear();
Expand Down

0 comments on commit caa403b

Please sign in to comment.