我正在玩JavaFX,偶然发现了Oracle的Using JavaFX Collections教程,并遇到了一个问题。在示例1-6中,他们使用git lfs
对FXCollections
:
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()
时会有四个更改通知,但我仍然只有一个。有什么想法吗?获得四个更改通知需要做些什么?
答案 0 :(得分:1)
来自SortableList
API(似乎无法在线找到javadoc):
SortableList是一个可以高效排序的列表 与Collections.sort()方法形成对比,威胁都列出了 同样的方式。例如。 ObservableList只能对一个通知进行排序和触发。
本质:
FXCollections.sort
上调用ObservableList
,SortableList
来自FXCollections.sort
ObservableList
会将您的SortableList
投放到((SortableList<? extends T>)list).sort();
,并调用com.sun.javafx.collections.ObservableListWrapper
FXCollections.sort
注意(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);
});
};
。