Skip to content

Conversation

@credmond
Copy link
Contributor

@credmond credmond commented Nov 24, 2025

Fixes #1606. Existing behaviour never worked as expected, nodes were removed from expandedNodeCache (expandedNodeCache.remove(getBean())) everytime a row was collapsed.

This meant that ExpandableTableRowSkin's tableRow.itemProperty() listener was was getting null from the cache, and unable to remove the children, to clean-up the row.

This problem went unnoticed until now because a table refresh was re-creating all cells anyway, so the un-removed nodes were getting discarded anyway. Now though, there are new optimisations in TableView which means these leftover nodes are visible as they're never never cleaned up from the rows.

The fix is to clean them up as I believe was originally intended.

…odes were removed from expandedNodeCache (expandedNodeCache.remove(getBean())) everytime a row was collapsed.

This meant that ExpandableTableRowSkin's tableRow.itemProperty() listener was was getting null from the cache, and unable to remove the children, to clean-up the row.

This problem went unnoticed until now because a table refresh was re-creating all cells anyway. Now though, there are optimisations in TableView which means these leftover nodes are visible / never cleaned up.
Copy link

@Maran23 Maran23 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks correct! Removing the expanded node when the item changed is the correct approach here.

This should also improve the performance a bit since we are not eagerly removing the node from the cache anymore (on every collapse) - just when we need to - that is when the item changed. Therefore, we are also not recreating the same expanded node more often then we need to.

@Override
protected void invalidated() {
getTableView().refresh();
if (!getValue()) expandedNodeCache.remove(getBean());
Copy link
Contributor Author

@credmond credmond Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this from the cache here meant it's not available later, in the skin.

tableRow.itemProperty().addListener((observable, oldValue, newValue) -> {
if (oldValue != null) {
Node expandedNode = this.expander.getExpandedNode(oldValue);
Node expandedNode = this.expander.removeExpandedNode(oldValue);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without the fix in place, expandedNode may be null and therefore never removed from the row.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TableRowExpanderColumn no longer works due to *misbehaving* code

2 participants