diff --git a/modules/core/org.eclipse.fx.core/src/main/java/org/eclipse/fx/core/collection/internal/VirtualObservableList.java b/modules/core/org.eclipse.fx.core/src/main/java/org/eclipse/fx/core/collection/internal/VirtualObservableList.java index 65fe5f4f2..a01b08a33 100644 --- a/modules/core/org.eclipse.fx.core/src/main/java/org/eclipse/fx/core/collection/internal/VirtualObservableList.java +++ b/modules/core/org.eclipse.fx.core/src/main/java/org/eclipse/fx/core/collection/internal/VirtualObservableList.java @@ -12,8 +12,6 @@ *******************************************************************************/ package org.eclipse.fx.core.collection.internal; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.OptionalLong; @@ -104,6 +102,37 @@ public void moveBy(long delta) { // TODO need to handle long overflow this.index.set(Math.max(0, this.index.get() + delta)); } + + // Overrides to resolve diamond inheritance conflicts with JavaFX 21+ default methods + @Override + public javafx.beans.value.ObservableValue when(javafx.beans.value.ObservableValue condition) { + return super.when(condition); + } + + @Override + public javafx.util.Subscription subscribe(java.util.function.Consumer subscriber) { + return super.subscribe(subscriber); + } + + @Override + public javafx.util.Subscription subscribe(java.util.function.BiConsumer subscriber) { + return super.subscribe(subscriber); + } + + @Override + public javafx.beans.value.ObservableValue map(java.util.function.Function mapper) { + return super.map(mapper); + } + + @Override + public javafx.beans.value.ObservableValue orElse(T value) { + return super.orElse(value); + } + + @Override + public javafx.beans.value.ObservableValue flatMap(java.util.function.Function> mapper) { + return super.flatMap(mapper); + } } class ListViewImpl extends ObservableListBase implements IndexRangeView { @@ -119,9 +148,7 @@ public ListViewImpl(long startIndex, int length) { FXObservableUtil.onInvalidate(this.length, v -> updateList()); FXObservableUtil.onInvalidate(VirtualObservableList.this.list, o -> updateList()); - this.listener = (c) -> { - fireChange(new SourceChangeEvent(this, c)); - }; + this.listener = (c) -> fireChange(new SourceChangeEvent(this, c)); this.data.addListener(this.listener); updateList(); } @@ -134,7 +161,7 @@ private void updateList() { (int) Math.min(_endIndex() + 1, VirtualObservableList.this.list.size()))); } - // Fill up the reset of the list + // Fill up the rest of the list if (list.size() < size()) { for (int i = list.size(); i < size(); i++) { list.add(null); @@ -209,22 +236,30 @@ public T get(int index) { public int size() { return this.length.get(); } + + // Overrides to resolve diamond inheritance conflicts with JavaFX 21+ default methods + @Override + public javafx.collections.transformation.FilteredList filtered(java.util.function.Predicate predicate) { + return super.filtered(predicate); + } + + @Override + public javafx.collections.transformation.SortedList sorted(java.util.Comparator comparator) { + return super.sorted(comparator); + } + + @Override + public javafx.collections.transformation.SortedList sorted() { + return super.sorted(); + } } static class SourceChangeEvent extends ListChangeListener.Change { private final Change change; - private final Method getPermutation; public SourceChangeEvent(ObservableList list, Change change) { super(list); this.change = change; - try { - // TODO We should use MethodHandles - this.getPermutation = ListChangeListener.Change.class.getDeclaredMethod("getPermutation"); //$NON-NLS-1$ - this.getPermutation.setAccessible(true); - } catch (NoSuchMethodException | SecurityException e) { - throw new IllegalStateException(e); - } } @Override @@ -255,11 +290,18 @@ public List getRemoved() { @Override protected int[] getPermutation() { - try { - return (int[]) this.getPermutation.invoke(this.change); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - throw new IllegalStateException(e); + // Use the public getPermutation(int) method instead of reflection + // to access the protected getPermutation() method + if (!this.change.wasPermutated()) { + return new int[0]; + } + int from = this.change.getFrom(); + int to = this.change.getTo(); + int[] perm = new int[to - from]; + for (int i = from; i < to; i++) { + perm[i - from] = this.change.getPermutation(i); } + return perm; } @Override