2014-11-18 4 views
18

В некоторых контекстах необходимо обнаружить - в ListChangeListener, без контроля над самим списком - «все данные поменялись», f.i. когда нам нужно очистить какое-то состояние, например отбор - на совершенно новых данных старое состояние бессмысленно.ObservableList: как надежно обнаружить setAll?

Совершенно новые данные могут быть достигнуты

  • list.setAll (...)
  • list.set (otherObservableList), если список является ListProperty

Думая о каком типе изменения могут быть запущены на setAll (c - изменение, элементы - наблюдаемый список, псевдокод subChangeCount для подсчета подклассов):

// initially empty 
assertEquals(0, items.size()); 
items.setAll(1, 2, 4); 
assertEquals(1, c.subChangeCount()); 
assertTrue(c.wasAdded() && !c.wasReplaced()); 
assertEquals(0, c.getFrom()); 
assertEquals(c.getList().size(), c.getAddedSize()); 

// initially not empty 
assertTrue(items.size() > 0); 
items.setAll(1, 2, 4); 
assertEquals(1, c.subChangeCount()); 
assertTrue(c.wasReplaced()); 
assertEquals(0, c.getFrom()); 
assertEquals(c.getList().size(), c.getAddedSize()); 

Это, кажется, позволяет проверку полезности как:

boolean wasSetOrClearedAll(Change c) { 
    if (c.getList().isEmpty()) return true; 
    c.next(); 
    if (c.getAddedSize() == c.getList().size()) return true; 
    return false; 
} 

В отличие от этого, внутренний код FX, F.I. слушая COMBOBOX»пунктов:

while (c.next()) { 
    comboBox.wasSetAllCalled = comboBox.previousItemCount == c.getRemovedSize(); 
    ... 
} 
comboBox.previousItemCount = getItemCount(); 

хранит старый ITEMCOUNT, и сравнить с текущим removedSize (который я неудобно, старое состояние становится несвежим слишком часто, на мой вкус), тем не менее, есть хорошая вероятность что я что-то пропускаю с моим подходом.

Вопрос:

, в каком контексте будет мой метод утилита не в состоянии (и основной подход позволил бы обнаружить SetAll правильно)?

+0

Каков конкретный тип наблюдаемого списка, который вы используете? Похоже, ListProperty является абстрактным классом, который не объявляет setAll (...) – Zeki

+0

@zeki hmm .. все ObservableLists должны иметь setAll (T ... item) - конечно, без поддержки, поэтому возьмите все, что имеет его (ListProperty ничего особенного, он просто маршрутизирует setAll его резервного списка) – kleopatra

+0

В этом случае вы можете расширить ListProperty и запустить setAll событие перед вызовом супер метода? – Zeki

ответ

4

К сожалению, надежного способа обнаружения этого на стороне слушателя нет.

Борьба начинается с РЕАЛИЗАЦИЕЙ по умолчанию, который в основном выглядит следующим образом:

@Override 
public boolean setAll(Collection<? extends E> col) { 
    beginChange(); 
    try { 
     clear(); 
     addAll(col); 
    } finally { 
     endChange(); 
    } 
    return true; 
} 

Если передать пустую коллекцию в setAll результате и событие, запускаемые оба точно так же, как когда вы бы назвали clear.

Так что ваш метод wasSetOrClearedAll возвращает true, когда clear также был вызван (как и в случае реализации ядра).

Так что в конце нет общего обнаружения setAll, все зависит от вашего прецедента. Если вы можете сузить то, что вы пытаетесь обнаружить, вы можете написать для этого фильтр.

+0

ahhh ... даже не подумал присмотреться к основной реализации ;-) Хороший аргумент, спасибо! clear/setAll быть одинаковым - достаточно хорошо - В основном мне нужны некоторые средства для надежного выброса всего состояния , связанного со старыми товарами (без ссылок на предметы, только на их прежние должности). hmm ... вернуться к мысли – kleopatra

+0

И ListChangeListener.Change.getRemoved()/getFrom()/getTo() не достаточно хорош для очистки? – eckig

+0

hmm .. нет, если я следую основным реализациям selectModels. Впрочем, это багги. Наверное, нужно подумать с нуля, может быть, setAll не такой особый случай, ведь :-) – kleopatra

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