--- old/modules/base/src/main/java/javafx/collections/transformation/FilteredList.java 2016-05-11 18:54:18.633291200 +0300 +++ new/modules/base/src/main/java/javafx/collections/transformation/FilteredList.java 2016-05-11 18:54:18.444280400 +0300 @@ -180,6 +180,11 @@ return filtered[index]; } + @Override + public int getViewIndex(int index) { + return Arrays.binarySearch(filtered, 0, size, index); + } + private SortHelper getSortHelper() { if (helper == null) { helper = new SortHelper(); --- old/modules/base/src/main/java/javafx/collections/transformation/SortedList.java 2016-05-11 18:54:20.186380100 +0300 +++ new/modules/base/src/main/java/javafx/collections/transformation/SortedList.java 2016-05-11 18:54:19.998369300 +0300 @@ -224,6 +224,11 @@ return sorted[index].index; } + @Override + public int getViewIndex(int index) { + return perm[index]; + } + private void updatePermutationIndexes(Change change) { for (int i = 0; i < size; ++i) { int p = change.getPermutation(sorted[i].index); --- old/modules/base/src/main/java/javafx/collections/transformation/TransformationList.java 2016-05-11 18:54:21.747469400 +0300 +++ new/modules/base/src/main/java/javafx/collections/transformation/TransformationList.java 2016-05-11 18:54:21.542457600 +0300 @@ -148,4 +148,11 @@ return idx; } + /** + * Maps the index of the direct source list's element to an index in this list. + * @param index the index in the source list + * @return the index of the element in this list + * @see #getSource(), #getSourceIndex() + */ + public abstract int getViewIndex(int index); } --- old/modules/base/src/test/java/test/javafx/collections/FilteredListTest.java 2016-05-11 18:54:23.319559300 +0300 +++ new/modules/base/src/test/java/test/javafx/collections/FilteredListTest.java 2016-05-11 18:54:23.136548800 +0300 @@ -25,8 +25,6 @@ package test.javafx.collections; -import test.javafx.collections.Person; -import test.javafx.collections.MockListObserver; import com.sun.javafx.collections.ObservableListWrapper; import java.util.Arrays; import java.util.Collections; @@ -58,6 +56,27 @@ filteredList.addListener(mlo); } + private void compareIndices(FilteredList filtered) { + ObservableList source = filtered.getSource(); + for (int i = 0; i < filtered.size(); i++) { + // i as a view index + int sourceIndex = filtered.getSourceIndex(i); + assertEquals(i, filtered.getViewIndex(sourceIndex)); + assertSame(filtered.get(i), source.get(sourceIndex)); + } + for (int i = 0; i < source.size(); i++) { + // i as a source index + int viewIndex = filtered.getViewIndex(i); + if (viewIndex >= 0) { + assertEquals(i, filtered.getSourceIndex(viewIndex)); + assertSame(source.get(i), filtered.get(viewIndex)); + } + } + } + + private void compareIndices() { + compareIndices(filteredList); + } @Test public void testLiveMode() { @@ -73,12 +92,15 @@ list.addAll("a", "c", "d", "c"); assertEquals(Arrays.asList("a", "d"), filteredList); mlo.check1AddRemove(filteredList, Collections.emptyList(), 0, 2); + compareIndices(); + mlo.clear(); list.add("c"); mlo.check0(); list.add(1, "b"); assertEquals(Arrays.asList("a", "b", "d"), filteredList); mlo.check1AddRemove(filteredList, Collections.emptyList(), 1, 2); + compareIndices(); } @Test @@ -86,10 +108,13 @@ list.removeAll(Arrays.asList("c")); assertEquals(Arrays.asList("a", "d"), filteredList); mlo.check0(); + compareIndices(); + mlo.clear(); list.remove("a"); assertEquals(Arrays.asList("d"), filteredList); mlo.check1AddRemove(filteredList, Arrays.asList("a"), 0, 0); + compareIndices(); } @Test @@ -97,6 +122,7 @@ FXCollections.sort(list, (o1, o2) -> -o1.compareTo(o2)); mlo.check1Permutation(filteredList, new int[] {1, 0}); assertEquals(Arrays.asList("d", "a"), filteredList); + compareIndices(); } @Test @@ -110,6 +136,7 @@ mlo.check0(); pProperty.set((String s) -> !s.equals("d")); mlo.check1AddRemove(filteredList, Arrays.asList("a", "d"), 0, 3); + compareIndices(); } @Test @@ -122,20 +149,24 @@ filtered.addListener(lo); assertEquals(Arrays.asList(new Person("BB")), filtered); + compareIndices(filtered); list.get(0).name.set("AA"); lo.check1AddRemove(filtered, Collections.EMPTY_LIST, 0, 1); assertEquals(Person.createPersonsList("AA", "BB"), filtered); + compareIndices(filtered); lo.clear(); list.get(1).name.set("BBB"); lo.check1Update(filtered, 1, 2); assertEquals(Person.createPersonsList("AA", "BBB"), filtered); + compareIndices(filtered); lo.clear(); list.get(1).name.set("B"); lo.check1AddRemove(filtered, Person.createPersonsList("B"), 1, 1); assertEquals(Person.createPersonsList("AA"), filtered); + compareIndices(filtered); } @Test @@ -148,10 +179,12 @@ filtered.addListener(lo); assertEquals(Collections.EMPTY_LIST, filtered); + compareIndices(filtered); list.get(0).name.set("AA"); lo.check1AddRemove(filtered, Collections.EMPTY_LIST, 0, 1); assertEquals(Person.createPersonsList("AA"), filtered); + compareIndices(filtered); } @Test @@ -172,6 +205,7 @@ lo.checkAddRemove(1, filtered, Collections.EMPTY_LIST, 3, 5); lo.checkAddRemove(2, filtered, Collections.EMPTY_LIST, 6, 7); assertEquals(Person.createPersonsList("AA", "AA", "BB", "AA", "AA", "BC", "AA"), filtered); + compareIndices(filtered); lo.clear(); p1.name.set("AAA"); @@ -179,6 +213,7 @@ lo.checkUpdate(1, filtered, 3, 5); lo.checkUpdate(2, filtered, 6, 7); assertEquals(Person.createPersonsList("AAA", "AAA", "BB", "AAA", "AAA", "BC", "AAA"), filtered); + compareIndices(filtered); lo.clear(); p1.name.set("A"); @@ -186,6 +221,7 @@ lo.checkAddRemove(1, filtered, Person.createPersonsList("A", "A"), 1, 1); lo.checkAddRemove(2, filtered, Person.createPersonsList("A"), 2, 2); assertEquals(Person.createPersonsList( "BB", "BC"), filtered); + compareIndices(filtered); } private static class Updater extends ObservableListWrapper { @@ -220,6 +256,7 @@ list.updateAll(); lo.checkUpdate(0, filtered, 0, filtered.size()); + compareIndices(filtered); lo.clear(); list.get(0).name.set("AA0"); @@ -232,6 +269,7 @@ lo.checkAddRemove(0, filtered, Collections.EMPTY_LIST, 0, 1); lo.checkAddRemove(1, filtered, Person.createPersonsList("B6"), 2, 5); lo.checkUpdate(2, filtered, 1, 2); + compareIndices(filtered); } @Test @@ -240,6 +278,7 @@ assertEquals(list.size(), filteredList.size()); assertEquals(list, filteredList); mlo.check1AddRemove(filteredList, Arrays.asList("a", "d"), 0, 4); + compareIndices(); } @Test @@ -247,5 +286,6 @@ filteredList = new FilteredList<>(list); assertEquals(list.size(), filteredList.size()); assertEquals(list, filteredList); + compareIndices(); } } --- old/modules/base/src/test/java/test/javafx/collections/SortedListTest.java 2016-05-11 18:54:24.938651900 +0300 +++ new/modules/base/src/test/java/test/javafx/collections/SortedListTest.java 2016-05-11 18:54:24.725639700 +0300 @@ -85,26 +85,16 @@ compareIndices(); } - //TODO: replace with sorted.getViewIndex when JDK-8139848 is fixed - private int getViewIndex(SortedList sorted, int sourceIndex) { - for (int i = 0; i < sorted.size(); i++) { - if (sourceIndex == sorted.getSourceIndex(i)) { - return i; - } - } - return -1; - } - private void compareIndices(SortedList sorted) { ObservableList source = sorted.getSource(); for (int i = 0; i < sorted.size(); i++) { // i as a view index int sourceIndex = sorted.getSourceIndex(i); - assertEquals(i, getViewIndex(sorted, sourceIndex)); + assertEquals(i, sorted.getViewIndex(sourceIndex)); assertSame(sorted.get(i), source.get(sourceIndex)); // i as a source index - int viewIndex = getViewIndex(sorted, i); + int viewIndex = sorted.getViewIndex(i); assertEquals(i, sorted.getSourceIndex(viewIndex)); assertSame(source.get(i), sorted.get(viewIndex)); } --- old/modules/base/src/test/java/test/javafx/collections/TransformationListTest.java 2016-05-11 18:54:26.524742600 +0300 +++ new/modules/base/src/test/java/test/javafx/collections/TransformationListTest.java 2016-05-11 18:54:26.339732000 +0300 @@ -85,6 +85,11 @@ } @Override + public int getViewIndex(int index) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override public boolean removeAll(String... es) { throw new UnsupportedOperationException("Not supported yet."); }