On Mon, 28 Jun 2021 12:55:47 GMT, Marius Hanl <mh...@openjdk.org> wrote:
>> The issue is about memory leaks and side-effects (like NPEs) when switching >> skins. >> >> Details (copied from issue for convenience): >> >> memory leak in TextInputControlBehavior: >> - listener accidentally added twice (removed once) >> - keyPad mappings not properly installed/disposed >> >> memory leak TextFieldBehavior: >> - listeners to scene/focusOwner property not removed, >> >> memory leak in TextInputControlSkin: >> - event handlers related to inputMethods not removed >> >> issues in TextFieldSkin: >> - memory leak due to behavior leaking >> - memory leaks due to manually added change/invalidation listeners that are >> not removed >> - memory leaks due to not removing children with strong references to skin >> - side-effects (f.i. NPEs) due to listeners/bindings that are still active >> after dispose >> >> Fix was to properly install/remove those listeners/handlers. Added tests >> that failed/passed before/after the fix, respectively, also added tests >> passing before that must pass after the fix. > > modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TextFieldBehavior.java > line 75: > >> 73: } >> 74: >> 75: focusListener = (observable, oldValue, newValue) -> { > > Shouldn't this focusListener also be wrapped in a weakListener? Also this > lambda expression can be a one-liner (no braces needed) we are a bit inconsistent in wrapping (or not) listeners into their weak counterparts - behaviors tend to not :) That's okay - and less crowded by additional code - as long as they are removed properly, IMO. But just seeing: good question, as the focusOwner listener is wrapped, need to consult my notes. Thanks for the heads up! As to the single vs. multiple lines: ersonally, I tend to not change more than absolutely needed - it had the brackets before the fix so I kept them. > modules/javafx.controls/src/main/java/javafx/scene/control/skin/TextFieldSkin.java > line 389: > >> 387: /** {@inheritDoc} */ >> 388: @Override public void dispose() { >> 389: if (getSkinnable() == null) return; > > Just curious: Can the skinnable be null here? And is it fine then to never > call **super.dispose()** ? dispose has no precondition - it can be called multiple times (explicitly specified in its javadoc), so has to guard itself against having cleaned already. And super is called the first time. ------------- PR: https://git.openjdk.java.net/jfx/pull/534