On Thu, 17 Jun 2021 12:41:56 GMT, Jeanette Winzenburg <faste...@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. Just a formal review, I left some comments inline 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) 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()** ? modules/javafx.controls/src/main/java/javafx/scene/control/skin/TextFieldSkin.java line 390: > 388: @Override public void dispose() { > 389: if (getSkinnable() == null) return; > 390: getChildren().removeAll(textGroup, handleGroup); Also curious: Most of the skins don't remove their children in **dispose()**. Are they all wrong, or is this a special case here? modules/javafx.controls/src/test/java/test/com/sun/javafx/scene/control/behavior/BehaviorCleanupTest.java line 162: > 160: secondStage.hide(); > 161: } > 162: minor: this empty line can be removed ------------- Changes requested by mhanl (Author). PR: https://git.openjdk.java.net/jfx/pull/534