On Wed, 24 Jan 2024 05:35:42 GMT, Prasanta Sadhukhan <psadhuk...@openjdk.org> wrote:
>> When using a TreeCellRenterer which creates new components in >> getTreeCellRendererComponent() in a JTree that is not visible, changes to >> the nodes cause a memory leak. >> When a node is changed, the Method getNodeDimensions() is called to >> calculate the new dimensions for the node. In this method, >> getTreeCellRendererComponent() is called to obtain the renderer component >> (what else...) and [this component is added to >> rendererPane](https://github.com/openjdk/jdk/blob/36f4b34f1953af736706ec67192204727808bc6c/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTreeUI.java#L3283-L3284). >> It is not removed from the rendererPane afterwards. >> Only when the tree is painted, the paint() method does a removeAll on the >> rendererPane [in this >> code](https://github.com/openjdk/jdk/blob/36f4b34f1953af736706ec67192204727808bc6c/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTreeUI.java#L1500) >> >> FIx is added to remove the components from rendererPane when the JTree UI is >> changed/uninstalled only when tree is not visible since they are already >> removed when tree is painted in paint() method.. > > Prasanta Sadhukhan has updated the pull request incrementally with one > additional commit since the last revision: > > Retain last component in rendererPane. Testcase added src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTreeUI.java line 3285: > 3283: for (int i = 0; i < > rendererPane.getComponentCount(); i++) { > 3284: rendererPane.remove(i); > 3285: } ~~~java for (int i = 0; i < rendererPane.getComponentCount(); i++) { rendererPane.remove(i); } ~~~ This code will not work for two or more children! For two children It does: 1. `i = 0` 2. `remove(i)` removes first child, which shifts other children and decrements component count to `1`! 3. `i++` so `i` is now `1` 4. check `i < rendererPane.getComponentCount()`, which is `1 < 1`. So loop is quit and one child is not removed. For three children It does: 1. `i = 0` 2. `remove(i)` removes first child, which shifts other children and decrements component count to `2`! 3. `i++` so `i` is now `1` 4. check `i < rendererPane.getComponentCount()`, which is `1 < 2` 5. `remove(i)` removes second child, which was the third child initially and decrements component count to `1` 6. `i++` so `i` is now `2` 7. check `i < rendererPane.getComponentCount()`, which is `2 < 1` . So loop is quit and one child is not removed. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/17458#discussion_r1466820969