From 4c8453af88fa53e2e0300df4dbca46b655a36920 Mon Sep 17 00:00:00 2001 From: John Hendrikx Date: Fri, 15 Jul 2022 01:34:55 +0200 Subject: [PATCH 1/2] Fix bug where ObjectBinding returns null when revalidated immediately Introduced with the fluent bindings PR --- .../javafx/beans/binding/ObjectBinding.java | 5 ++++- .../beans/value/LazyObjectBindingTest.java | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/modules/javafx.base/src/main/java/javafx/beans/binding/ObjectBinding.java b/modules/javafx.base/src/main/java/javafx/beans/binding/ObjectBinding.java index 84f62a8416c..af3f93d48b9 100644 --- a/modules/javafx.base/src/main/java/javafx/beans/binding/ObjectBinding.java +++ b/modules/javafx.base/src/main/java/javafx/beans/binding/ObjectBinding.java @@ -180,7 +180,10 @@ public final void invalidate() { valid = false; onInvalidating(); ExpressionHelper.fireValueChangedEvent(helper); - value = null; // clear cached value to avoid hard reference to stale data + + if (!valid) { // if still invalid after calling listeners... + value = null; // clear cached value to avoid hard reference to stale data + } } } diff --git a/modules/javafx.base/src/test/java/test/javafx/beans/value/LazyObjectBindingTest.java b/modules/javafx.base/src/test/java/test/javafx/beans/value/LazyObjectBindingTest.java index 72da81b3c26..23a630c0673 100644 --- a/modules/javafx.base/src/test/java/test/javafx/beans/value/LazyObjectBindingTest.java +++ b/modules/javafx.base/src/test/java/test/javafx/beans/value/LazyObjectBindingTest.java @@ -52,6 +52,24 @@ void shouldBeInvalidInitially() { assertFalse(binding.isValid()); } + @Test + void invalidationWhichBecomesValidDuringCallbacksShouldReturnCorrectValue() { + LazyObjectBindingStub binding = new LazyObjectBindingStub<>() { + @Override + protected String computeValue() { + return "A"; + } + }; + + binding.addListener(obs -> { + assertEquals("A", binding.get()); + }); + + binding.invalidate(); // becomes valid again immediately + + assertEquals("A", binding.get()); + } + @Nested class WhenObservedWithInvalidationListener { private InvalidationListener invalidationListener = obs -> {}; From 3485656941f80c1eca4a919b11d76abdd3b1ce29 Mon Sep 17 00:00:00 2001 From: John Hendrikx Date: Fri, 15 Jul 2022 09:15:03 +0200 Subject: [PATCH 2/2] Change explanatory comment to block comment --- .../main/java/javafx/beans/binding/ObjectBinding.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/javafx.base/src/main/java/javafx/beans/binding/ObjectBinding.java b/modules/javafx.base/src/main/java/javafx/beans/binding/ObjectBinding.java index af3f93d48b9..131aa4177ee 100644 --- a/modules/javafx.base/src/main/java/javafx/beans/binding/ObjectBinding.java +++ b/modules/javafx.base/src/main/java/javafx/beans/binding/ObjectBinding.java @@ -181,8 +181,13 @@ public final void invalidate() { onInvalidating(); ExpressionHelper.fireValueChangedEvent(helper); - if (!valid) { // if still invalid after calling listeners... - value = null; // clear cached value to avoid hard reference to stale data + /* + * Cached value should be cleared to avoid a strong reference to stale data, + * but only if this binding didn't become valid after firing the event: + */ + + if (!valid) { + value = null; } } }