> This PR contains changes to make it easier to implement properties which want > to conserve resources until they're observed themselves. > > `isObserved` is promoted from `ObjectBinding` to the `ObservableValue` > interface, allowing you to ask any `ObservableValue` if it is currently > observed (ie. if it has any listeners registered on it). All JavaFX > `ObservableValue`s implementations are modified to implement this method. > > The protected methods `observed` and `unobserved` are added to all extendable > (non final) `ObservableValue`s provided by JavaFX. The `observed` call back > is only called when the observable currently has 0 listeners and will soon > have 1 listener. During the call back, `isObserved` still returns `false` > (see below for why this was chosen). The `unobserved` call back is only > called when the last listener was removed and the observable has 0 listeners. > During the call back, `isObserved` will already return `false`. > > The reason why `observed` is called before `isObserved` starts returning > `true` (and also why `unobserved` works the opposite) is to make it easy to > implement a parent-child relationship where a nested property becoming > observed may need to trigger behavior in its parent. Given a parent class and > two nested properties `foo` and `bar`: > > class FooProperty extends ObjectPropertyBase<Foo> { > void observed() { > nestedPropertyObserved(); // call to parent > } > > void unobserved() { > nestedPropertyUnobserved(); // call to parent > } > } > > The parent may determine whether any of the properties is observed with a > helper: > > private boolean isANestedPropertyObserved() { > return foo.isObserved() || bar.isObserved(); > } > > The `nestedPropertyObserved` and `nestedPropertyUnobserved` methods can now > be implemented simply as: > > private void nestedPropertyObserved() { > if (!isANestedPropertyObserved()) { > // take action as no properties were observed before, but now > one will become observed > } > } > > private void nestedPropertyUnobserved() { > if (!isANestedPropertyObserved()) { > // take action as a property was observed before, but the > last listener is about to be removed > } > } > > If `isObserved` would change immediately, this becomes more difficult as the > observed status of the property that has just become observed would need to > be excluded to determine if this is the first observation of a nested > property or a later one. > > - Add `isObserved` to `ObservableValue` to check if it is observed and > implement it in all overriding classes > - Add `observed`/`unobserved` protected methods to all extendable observables > - Use *Base classes in a few places (avoids duplication code) > - Simplify `LazyObjectBinding` > - In `ObjectBinding`, `isObserved` has become public as it is specified by > the `ObservableValue` interface now
John Hendrikx has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains two commits: - Merge branch 'master' into feature/delayed-infra - Add delayed listener registration support - Add isObserved to ObservableValue to check if it is observed - Add observed/unobserved protected methods to all subclassable observables - Use *Base classes in a few places (avoids duplication code) - Simplify LazyObjectBinding - In ObjectBinding, isObserved has become public as it is specified by the ObservableValue interface now ------------- Changes: https://git.openjdk.org/jfx/pull/1023/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1023&range=01 Stats: 1225 lines in 43 files changed: 802 ins; 211 del; 212 mod Patch: https://git.openjdk.org/jfx/pull/1023.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1023/head:pull/1023 PR: https://git.openjdk.org/jfx/pull/1023