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

Reply via email to