How to Set the Size (or Location) of an Open Group Node
Questions & AnswersSummary
Description
Group nodes that are being represented by GroupNodeRealizer instances, which implement the AutoBoundsFeature interface, will automatically adjust their sizes to fit their contents unless they are empty. In particular, this auto resize feature actively prevents an open group node from
- becoming smaller than the size needed to entirely enclose its content,
- being "moved away" from its content.
In order to manually change the size or location of an open group node, there are two possibilities:
- Permanently disabling the auto resize feature. This allows to set any size or location for the group node, i.e., it can be made smaller than its actual content, for example.
- Keeping the auto resize feature and using the group node's insets to accomodate additional space.
To specify a permanent fixed custom size one should disable the auto resize feature using the AutoBoundsFeature.setAutoBoundsEnabled(boolean) method with false as the argument:
// Get the node realizer instance.
NodeRealizer groupNodeRealizer = graph.getRealizer(groupNode);
// Turn off auto bounds.
groupNodeRealizer.getAutoBoundsFeature().setAutoBoundsEnabled(false);
// Manually assign a new size.
groupNodeRealizer.setSize(100, 200);
With AutoBoundsFeature enabled, the only way the size of an open group node can be changed, is to appropriately modify the group node's insets. Class GroupNodeRealizer provides two sets of insets, namely minimal insets and border insets. The former is used to specify the padding around the exact bounding box of the group node's content, while the latter provides a means to accomodate additional space.
// Get the node realizer instance.
NodeRealizer nr = graph.getRealizer(groupNode);
if (nr instanceof GroupNodeRealizer) {
GroupNodeRealizer groupNodeRealizer = (GroupNodeRealizer)nr;
// Enlarge the open group node by enlarging the border insets to the right.
YInsets borderInsets = groupNodeRealizer.getBorderInsets();
groupNodeRealizer.setBorderInsets(
new YInsets(borderInsets.top, borderInsets.left, borderInsets.bottom, borderInsets.right + 20));
// Resetting all insets effectively shrinks the group node (if not already at its minimum).
groupNodeRealizer.setMinimalInsets(new YInsets(0, 0, 0, 0));
groupNodeRealizer.setBorderInsets(new YInsets(0, 0, 0, 0));
}
Changing the location of an open group node is ultimately only possible by moving its actual content.
/**
* Moves a given group node by effectively only moving its contained child nodes.
*/
public void moveGroupNode(Node groupNode, double dx, double dy) {
HierarchyManager hm = ((Graph2D)groupNode.getGraph()).getHierarchyManager();
// Find the children contained in the given group node.
NodeList childNodes = new NodeList();
addChildren(hm, groupNode, childNodes);
// Move the children.
moveNodes(childNodes.nodes(), dx, dy);
}
/**
* Recursively adds the (non-group node) children of a given group node to
* the 'childNodes' NodeList.
*/
private void addChildren(HierarchyManager hm, Node groupNode, NodeList childNodes) {
for (NodeCursor nc = hm.getChildren(groupNode); nc.ok(); nc.next()) {
Node n = nc.node();
if (hm.isGroupNode(n)) {
addChildren(hm, n, childNodes);
}
else {
childNodes.add(n);
}
}
}
/**
* Moves the nodes accessible via the given NodeCursor.
*/
public void moveNodes(Graph2D graph, NodeCursor nodes, double dx, double dy) {
for (; nodes.ok(); nodes.next()) {
NodeRealizer nr = graph.getRealizer(nodes.node());
if (nr.getAutoBoundsFeature() != null && nr.getAutoBoundsFeature().isAutoBoundsEnabled()) {
continue;
}
// Only move the node, if it doesn't have the auto resize feature (enabled).
nr.moveBy(dx, dy);
}
}