java - ObservableList: ¿cómo detectar confiablemente un setAll?



javafx javafx-8 (1)

En algunos contextos, es necesario detectar (en un ListChangeListener, sin control sobre la lista en sí misma) un "todos los datos intercambiados", cuando se necesita borrar algún estado como la selección, en datos completamente nuevos, el estado antiguo no tiene sentido.

Los datos completamente nuevos pueden ser alcanzados por

  • list.setAll (...)
  • list.set (otherObservableList) si list es un ListProperty

Pensando en qué tipo de cambios podrían activarse en setAll (c es el cambio, los elementos son la lista observada, pseudo-código "subChangeCount" para contar los intercambios):

// 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()); 

Esto parece permitir una verificación de utilidad como:

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

En contraste, el código fx interno, al escuchar los elementos de ComboBox:

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

almacena el antiguo itemCount y lo compara con el tamaño eliminado actual (con el que no me siento cómodo, el estado antiguo se vuelve obsoleto con demasiada frecuencia para mi gusto), sin embargo, existe una buena probabilidad de que me esté perdiendo algo con mi enfoque.

La pregunta es:

¿En qué contexto fallaría mi método de utilidad (y el enfoque central detectaría el setAll correctamente)?


Desafortunadamente, no hay una forma confiable de detectar esto en el lado del oyente.

La lucha comienza con la implementación predeterminada, que en su mayoría se parece a esto:

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

Si pasa una Colección vacía para establecer setAll el resultado y el evento que se setAll son exactamente los mismos que cuando hubiera llamado clear .

Por lo tanto, su método wasSetOrClearedAll devuelve true cuando también se ha llamado a clear (al igual que la implementación central).

Entonces, al final no hay una detección genérica de setAll , todo depende de su caso de uso. Si puede reducir lo que está intentando detectar, puede escribir un filtro para eso.





observablelist