Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8208750

Attaching an InvalidationListener causes evaluation

    Details

    • Type: Bug
    • Status: Open
    • Priority: P3
    • Resolution: Unresolved
    • Affects Version/s: 9, 10, openjfx11
    • Fix Version/s: tbd
    • Component/s: javafx
    • Labels:
      None
    • Subcomponent:

      Description

      Attaching an InvalidationListener is not documented to cause an eager evaluation like ChangeListener does: ObservableValue's docs states:

      "Important note: attaching a ChangeListener enforces eager computation even if the implementation of the ObservableValue supports lazy evaluation."

      However, the internal class com.sun.javafx.binding.ExpressionHelper, which manages adding and removing listener operations, explicitly computes the value upon attaching an InvalidationListener:

          public static <T> ExpressionHelper<T> addListener(ExpressionHelper<T> helper, ObservableValue<T> observable, InvalidationListener listener) {
              if ((observable == null) || (listener == null)) {
                  throw new NullPointerException();
              }
              observable.getValue(); // validate observable
              return (helper == null)? new SingleInvalidation<T>(observable, listener) : helper.addListener(listener);
          }

      The line `observable.getValue(); // validate observable` is the explicit evaluation. The class SingleInvalidation does not do any evaluations.

      For comparison, ChangeListener uses:

          public static <T> ExpressionHelper<T> addListener(ExpressionHelper<T> helper, ObservableValue<T> observable, ChangeListener<? super T> listener) {
              if ((observable == null) || (listener == null)) {
                  throw new NullPointerException();
              }
              return (helper == null)? new SingleChange<T>(observable, listener) : helper.addListener(listener);
          }

      But in the constructor of SingleChange the evaluation happens in the line `this.currentValue = observable.getValue();` so it can be stored to observe changes. This is fine.

      This causes odd behavior such as the one in JDK-8089579.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                nlisker Nir Lisker
                Reporter:
                nlisker Nir Lisker
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated: