DockContainerBranch.addContainer(int index, DockContainer container) inserts the region at index
but appends the container to the model list:
childContainers.add(container); // appended, index ignored
container.setParentContainer(this);
getItems().add(index, container.asRegion()); // inserted at index
Any call with index != childContainers.size() therefore leaves getChildContainers() and
getItems() in different orders. Every method that looks a child up in one list and writes to the
other by that index then addresses the wrong child — replaceContainer, setContainerSizePx0,
setContainerResizable and setContainerCollapsed all do exactly that.
Reproduction
No stage or scene needed (JavaFX toolkit started only because the containers are Nodes):
Bento bento = new Bento();
DockBuilding building = bento.dockBuilding();
DockContainerRootBranch root = building.root("root");
root.setOrientation(Orientation.HORIZONTAL);
DockContainerBranch center = building.branch("center");
root.addContainer(center);
DockContainerBranch sidebar = building.branch("sidebar");
root.addContainer(0, sidebar); // intent: sidebar left of center
// model = [center, sidebar]
// visual = [sidebar, center] // <-- already out of order
DockContainerLeaf a = building.leaf("a");
DockContainerLeaf c = building.leaf("c");
sidebar.addContainers(a, c);
sidebar.removeContainer(c); // sidebar prunes to one child
The prune calls root.replaceContainer(sidebar, a), which takes i = childContainers.indexOf(sidebar) = 1
and then does getItems().set(1, a.asRegion()) — but index 1 of getItems() is center.
Observed after the prune:
model = [center, a]
visual = [sidebar, a]
center and everything docked inside it is silently detached from the scene graph, while sidebar
stays on screen despite no longer being in the model. In our application that surfaced as the entire
editor area disappearing, and a user could trigger it by dragging alone.
Expected
getChildContainers() and getItems() stay in the same order, so addContainer(0, x) puts x
first in both.
Suggested fix
childContainers.add(index, container);
Version
0.16.0, and the code is unchanged on master as of today.
DockContainerBranch.addContainer(int index, DockContainer container)inserts the region atindexbut appends the container to the model list:
Any call with
index != childContainers.size()therefore leavesgetChildContainers()andgetItems()in different orders. Every method that looks a child up in one list and writes to theother by that index then addresses the wrong child —
replaceContainer,setContainerSizePx0,setContainerResizableandsetContainerCollapsedall do exactly that.Reproduction
No stage or scene needed (JavaFX toolkit started only because the containers are Nodes):
The prune calls
root.replaceContainer(sidebar, a), which takesi = childContainers.indexOf(sidebar) = 1and then does
getItems().set(1, a.asRegion())— but index 1 ofgetItems()is center.Observed after the prune:
centerand everything docked inside it is silently detached from the scene graph, whilesidebarstays on screen despite no longer being in the model. In our application that surfaced as the entire
editor area disappearing, and a user could trigger it by dragging alone.
Expected
getChildContainers()andgetItems()stay in the same order, soaddContainer(0, x)putsxfirst in both.
Suggested fix
Version
0.16.0, and the code is unchanged on
masteras of today.