2015-12-09 1 views
1

Я играл с JavaFX, наткнулся на учебник Oracle Using JavaFX Collections и столкнулся с вопросом. В примере 1-6 они используют FXCollections для сортировки ObservableList:Количество уведомлений об изменениях, созданных при сортировке 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? 

Согласно учебнику, только один уведомление об изменениях распечатываются. В учебнике упоминается, что будут использоваться четыре уведомления об изменении, если вместо FXCollections.sort() используется Collections.sort(), но я все еще получаю только один. Любые идеи почему? Что нужно сделать, чтобы получить четыре уведомления об изменении?

ответ

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
  • В свою очередь, эта операция требует огонь только уведомление о роде

Примечание (I): источник для JDK8u45 для FXCollections.sort здесь ...

/** 
* 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); 
    } 
} 

Примечание (II): источник ObservableListWrapper.sort ...

@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 invocati on триггеры один раз, после сортировки фактически выполнен.

Update

Collections.sort идиома вызывает List.sort. В Java 8, List.sort фактически реализована реализация default, но она не используется здесь, поскольку она переопределена, поэтому механизм на месте по-прежнему от ObservableListWrapper.

TL; DR

Я сомневаюсь, что есть какой-нибудь элегантный способ, чтобы получить столько уведомлений, как количество операций, необходимое для сортировки List, если вы не используете свою собственную реализацию ObservableList.

Быстрый трюк! (проверено на Java 8)

Я только что нашел трюк, чтобы вызвать несколько событий Changed.

Если вы используете следующую идиому:

Collections.sort(observableList.subList(0, observableList.size()));

Причина заключается в том, что subList возвратит List, следовательно, будет использоваться defaultList.sort.

+0

Спасибо за ваши обсуждения, он дает представление о том, как работает «FXCollections.sort()» и почему «FXCollections.sort()» запускает только одно уведомление об изменении. Но возникает вопрос, почему 'Collections.sort()' также запускает только одно уведомление об изменении (вместо четырех, как упоминалось в учебнике Oracle). – Roland

+0

@ Роланд не видел, что редактирование, должно быть, я пришел после того, как ответил. Я взгляну. – Mena

+0

@Roland см. Мое редактирование и быстрый трюк, чтобы вызвать несколько уведомлений об изменении. – Mena

Смежные вопросы