RFR: 8240506: TextFieldSkin/Behavior: misbehavior on switching skin
Marius Hanl
mhanl at openjdk.java.net
Mon Jun 28 13:47:06 UTC 2021
On Thu, 17 Jun 2021 12:41:56 GMT, Jeanette Winzenburg <fastegal at 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
More information about the openjfx-dev
mailing list