排序ObservableList时引发的更改通知数

时间:2015-12-09 15:33:08

标签: java javafx

我正在玩JavaFX,偶然发现了Oracle的Using JavaFX Collections教程,并遇到了一个问题。在示例1-6中,他们使用git lfsFXCollections

进行排序
ObservableList

根据教程,只打印出一个更改通知。该教程提到在使用List<String> list = new ArrayList<String>(); list.add("d"); list.add("b"); list.add("a"); list.add("c"); ObservableList<String> observableList = FXCollections.observableList(list); observableList.addListener(new ListChangeListener() { @Override public void onChanged(ListChangeListener.Change change) { System.out.println("Detected a change! "); } }); FXCollections.sort(observableList); // one notification, as expected // Collections.sort(observableList); // also only one notification. why? 而不是Collections.sort()时会有四个更改通知,但我仍然只有一个。有什么想法吗?获得四个更改通知需要做些什么?

1 个答案:

答案 0 :(得分:1)

来自SortableList API(似乎无法在线找到javadoc):

  

SortableList是一个可以高效排序的列表   与Collections.sort()方法形成对比,威胁都列出了   同样的方式。例如。 ObservableList只能对一个通知进行排序和触发。

本质:

  • 您在FXCollections.sort上调用ObservableListSortableList来自FXCollections.sort
  • ObservableList会将您的SortableList投放到((SortableList<? extends T>)list).sort();,并调用com.sun.javafx.collections.ObservableListWrapper
  • 具体类型似乎是FXCollections.sort
  • 反过来,该操作声称仅在排序
  • 时触发 1 通知

注意(I):此处/** * Sorts the provided observable list. * Fires only <b>one</b> change notification on the list. * @see Collections#sort(java.util.List) */ @SuppressWarnings("unchecked") public static <T extends Comparable<? super T>> void sort(ObservableList<T> list) { if (list instanceof SortableList) { ((SortableList<? extends T>)list).sort(); // here's what happens } else { List<T> newContent = new ArrayList<T>(list); Collections.sort(newContent); list.setAll((Collection<T>)newContent); } } 的JDK8u45源代码...

ObservableListWrapper.sort

注(II)@Override public void sort(Comparator<? super E> comparator) { if (backingList.isEmpty()) { return; } int[] perm = getSortHelper().sort(backingList, comparator); // here's the single change fired fireChange(new SimplePermutationChange<E>(0, size(), perm, this)); } 的来源......

fireChange

正如您所看到的,Collections.sort调用在实际执行排序后触发一次

<强>更新

List.sort成语调用List.sort。 在Java 8中,default实际上有一个ObservableListWrapper实现,但由于它被覆盖,因此不会在此处使用,因此适当的机制仍然来自List

<强> TL; DR

我怀疑是否有任何优雅的方法可以获得与ObservableList排序所需的操作次数相同的通知,除非您使用自己的Changed实现。

快速技巧!(在Java 8中测试)

我刚发现了一个实际触发多个Collections.sort(observableList.subList(0, observableList.size()));事件的技巧。

如果您使用以下习语:

subList

原因是List会返回default,因此会使用List.sort $scope.getToken = function(){ // console.log $scope.login to make sure I'm not sending empty data console.log($scope.login); $http({ method: 'POST', url: '../../api/v1/Oauth.php', data: { 'login' : $scope.login, 'password' : $scope.password } }).then(function successCallback(response) { console.log(response); }, function errorCallback(response) { console.log(response); }); };