On Sun, 11 Dec 2022 20:12:17 GMT, John Hendrikx <jhendr...@openjdk.org> wrote:

> Packages fixed:
> - com.sun.javafx.binding
> - com.sun.javafx.collections
> - javafx.beans
> - javafx.beans.binding
> - javafx.collections
> - javafx.collections.transformation

This is the first half of the review. Will finish the classes under the 
`javafx` package in the 2nd iteration.

modules/javafx.base/src/main/java/com/sun/javafx/binding/BidirectionalContentBinding.java
 line 81:

> 79:         if ((obj1 instanceof ObservableList<?> list1) && (obj2 instanceof 
> ObservableList<?> list2)) {
> 80:             @SuppressWarnings("unchecked")
> 81:             final ListContentBinding<Object> binding = new 
> ListContentBinding<>((ObservableList<Object>) list1, (ObservableList<Object>) 
> list2);

Although the previous code has the same problem, this is sketchy. The two lists 
can be of different types while `ListContentBinding` requires the same type. 
This is a result of the `Bindings` public API that takes two `Objects`, so all 
type information is lost. Is it worth adding a comment about this since 
suppressing the warning can be understood as "trust me, this is fine".

modules/javafx.base/src/main/java/com/sun/javafx/binding/BidirectionalContentBinding.java
 line 81:

> 79:         if ((obj1 instanceof ObservableList<?> list1) && (obj2 instanceof 
> ObservableList<?> list2)) {
> 80:             @SuppressWarnings("unchecked")
> 81:             final ListContentBinding<Object> binding = new 
> ListContentBinding<>((ObservableList<Object>) list1, (ObservableList<Object>) 
> list2);

By the way, for these cases I usually use `var` as I find it has less clutter:

final var binding = new ListContentBinding<Object>(...)


You don't have to change this.

modules/javafx.base/src/main/java/com/sun/javafx/binding/ContentBinding.java 
line 87:

> 85:         if ((obj1 instanceof List<?> list1) && (obj2 instanceof 
> ObservableList<?> list2)) {
> 86:             @SuppressWarnings("unchecked")
> 87:             ListContentBinding<Object> binding = new 
> ListContentBinding<>((List<Object>) list1);

Another place where I would personally use `var`.

modules/javafx.base/src/main/java/com/sun/javafx/binding/ContentBinding.java 
line 89:

> 87:             ListContentBinding<Object> binding = new 
> ListContentBinding<>((List<Object>) list1);
> 88: 
> 89:             list2.removeListener(binding);

Another problem inherited from the existing code. What if the `obj2` is a 
`List` and `obj1` is an `ObservableList`? The docs don't say anything about the 
order.

Same question as before about adding a comment addressing the case that the two 
lists are not of the same type.

modules/javafx.base/src/main/java/com/sun/javafx/collections/MappingChange.java 
line 38:

> 36:     private List<F> removed;
> 37: 
> 38:     private static final Map<?, ?> NOOP_MAP = new Map<>() {

I think that we can do better with a bit of refactoring. The `Map` interface 
here is just `java.util.Function`. We can get rid of it and use `Function` 
instead. The `map` method call in `getRemoved` will be replaced with `apply`. 
The call sites needs just a little adjustment:
* In `TableView::TableViewArrayListSelectionModel` the `cellToIndicesMap` needs 
to change its type to `Function`, but it is also unused (didn't look what it 
was supposed to be for), so no issue there.
* In `TableView`, the method `fireCustomSelectedCellsListChangeEvent` needs to 
change its 2nd argument in the `MappingChange` constructor to 
`Function.indentity()` or something like `f -> f`.
* Same changes for `TreeTableView`.

I think that we can also use JavaFX's `Callback`, though I never use it if I 
can use `Function`.

modules/javafx.base/src/main/java/javafx/beans/binding/ListExpression.java line 
238:

> 236:     public Iterator<E> iterator() {
> 237:         final ObservableList<E> list = get();
> 238:         return (list == null)? ListExpression.<E>emptyList().iterator() 
> : list.iterator();

Might as well add a space before `?` in these lines if you want.

modules/javafx.base/src/main/java/javafx/beans/binding/ListExpression.java line 
406:

> 404:     private static <E> ObservableList<E> emptyList() {
> 405:         return (ObservableList<E>) EMPTY_LIST;
> 406:     }

I would move this below the declaration of `EMPTY_LIST`.

modules/javafx.base/src/main/java/javafx/beans/binding/MapExpression.java line 
326:

> 324:     private static <K, V> ObservableMap<K, V> emptyMap() {
> 325:         return (ObservableMap<K, V>) EMPTY_MAP;
> 326:     }

Same

modules/javafx.base/src/main/java/javafx/beans/binding/SetExpression.java line 
331:

> 329:     private static <E> ObservableSet<E> emptySet() {
> 330:         return (ObservableSet<E>) EMPTY_SET;
> 331:     }

Same

-------------

PR: https://git.openjdk.org/jfx/pull/972

Reply via email to