Hi both, Thank you Marius for investigating this, and apologies for assuming it was a JFX bug (I did spend time trying to determine if it was ControlsFX misbehaving).
Thank you Daniel for following up. I created a PR on ControlsFX: https://github.com/controlsfx/controlsfx/pull/1607 ... Kind Regards, Cormac On Mon, 24 Nov 2025 at 15:50, Daniel Peintner <[email protected]> wrote: > Hi, > > Thank you both for reporting the problem and providing a solution. > I opened https://github.com/controlsfx/controlsfx/issues/1606 to keep > track of the problem. > > Marius, I think it would be good if you can provide a fix/PR. > > Note: I am not one of the maintainers of ControlsFX but a user and I think > it is good if we can resolve the problem. > > Thanks, > > -- Daniel > > > On Mon, Nov 24, 2025 at 6:50 AM Marius Hanl <[email protected]> wrote: > >> The refresh changes could only be a problem if something in the Code is >> misbehaving. >> I had a look, and indeed, the *expandedNode* is NEVER removed. The logic >> simply does not work, never did in the previous versions. >> Prior to 26-ea+15, the table refresh was recreating ALL cells. This >> masked the bug. >> But now, the refresh method really refreshes the existing cells. So rows >> and cells need to react to that, as they should before. >> >> The root cause is, that the *expandedNode* is removed from the HashMap >> before it could be cleaned up in the corresponding TableRowSkin. >> So when the TableRowSkin tries to remove the *expandedNode*, it is >> already null. >> Removing the code fixes the issue: >> >> public BooleanProperty getExpandedProperty(S item) { >> BooleanProperty value = expansionState.get(item); >> if (value == null) { >> value = new SimpleBooleanProperty(item, "expanded", >> false) { >> @Override >> protected void invalidated() { >> // if (!getValue()) { >> // expandedNodeCache.remove(getBean()); >> // } >> getTableView().refresh(); >> } >> }; >> expansionState.put(item, value); >> } >> return value; >> } >> >> Again, this was also problematic before, but masked by the recreation. >> >> To restore the old behavior, you could write: >> >> TableView<Person> table = new TableView<>() { >> @Override >> public void refresh() { >> getProperties().put("recreateKey", Boolean.TRUE); >> } >> }; >> >> I don't know if ControlsFX is still somewhat maintained. Otherwise I can >> have file a PR there. >> >> -- Marius >> >> *Gesendet: *Sonntag, 23. November 2025 um 16:14 >> *Von: *"Cormac Redmond" <[email protected]> >> *An: *[email protected] >> *Betreff: *JFX 26-ea+15 TableView "bug" -- related to 8359599? >> Hi, >> >> Since 26-ea+15, there may be a "bug" with TableView which appears to be >> rendering duplicated nodes. >> >> I first noticed this when using ControlFX's TableRowExpanderColumn ( >> https://controlsfx.github.io/javadoc/11.2.2/org.controlsfx.controls/org/controlsfx/control/table/TableRowExpanderColumn.html), >> which has been working as expected for several years, right up until >> 26-ea+15. This column just provides a simple way to allow expansion of >> table rows. >> >> I have created a gist consisting of a single runnable class. It's quite >> small, and no dependencies are required (minimal ControlsFX code copied >> into it): >> >> >> https://gist.github.com/credmond/57ed65a20c1b4d1cf0272a71642077b0 >> >> >> Run this on 26-ea+15, and you'll see the issue re: duplicated rendering; >> run it on anything older, and there's no issue. If I had to guess, I'd say >> this issue is related to this commit (8359599): >> >> >> >> https://github.com/openjdk/jfx/commit/02756a810c54c4068505eca6d43c1ba2a136e04e >> >> >> >> The application starts out like this on all versions, there's three rows >> (number of rows is irrelevant): >> [image: image.png] >> >> Click the +'s and -'s more than once. >> >> 26-ea+15 "bug"; notice the duplications that appear just by clicking the >> + / -'s a couple of times: >> [image: image.png] >> >> 26-ea+14 (and previous) expected / normal behaviour: >> [image: image.png] >> >> >> >> >> Kind Regards, >> *Cormac Redmond* >> >> >> >> >
