Busqué este problema cuando estaba tratando de implementar un panel de desplazamiento cinético similar a los rollos de rueda de iPhone de Apple. Los elementos de la TreeSet
esta clase son:
/**
* Data object that contains a {@code DoubleExpression} bound to an item's
* relative distance away from the current {@link ScrollPane#vvalueProperty()} or
* {@link ScrollPane#hvalueProperty()}. Also contains the item index of the
* scrollable content.
*/
private static final class ItemOffset implements Comparable<ItemOffset> {
/**
* Used for floor or ceiling searches into a navigable set. Used to find the
* nearest {@code ItemOffset} to the current vValue or hValue of the scroll
* pane using {@link NavigableSet#ceiling(Object)} or
* {@link NavigableSet#floor(Object)}.
*/
private static final ItemOffset ZERO = new ItemOffset(new SimpleDoubleProperty(0), -1);
/**
* The current offset of this item from the scroll vValue or hValue. This
* offset is transformed into a real pixel length of the item distance from
* the current scroll position.
*/
private final DoubleExpression scrollOffset;
/** The item index in the list of scrollable content. */
private final int index;
ItemOffset(DoubleExpression offset, int index) {
this.scrollOffset = offset;
this.index = index;
}
/** {@inheritDoc} */
@Override
public int compareTo(ItemOffset other) {
double d1 = scrollOffset.get();
double d2 = other.scrollOffset.get();
if (d1 < d2) {
return -1;
}
if (d1 > d2) {
return 1;
}
// Double expression has yet to be bound
// If we don't compare by index we will
// have a lot of values ejected from the
// navigable set since they will be equal.
return Integer.compare(index, other.index);
}
/** {@inheritDoc} */
@Override
public String toString() {
return index + "=" + String.format("%#.4f", scrollOffset.get());
}
}
El DoubleExpression
puede tomar un momento para ser atado en una tarea runLater de la plataforma JavaFX, es por esto que el índice se incluye en esta clase de contenedor.
Como el scrollOffset
siempre está cambiando según la posición de desplazamiento del usuario en la rueda de desplazamiento, necesitamos una forma de actualizar. Por lo general, el orden es siempre el mismo, ya que el desplazamiento es relativo a la posición del índice del artículo. El índice nunca cambia, pero el desplazamiento puede ser negativo o positivo dependiendo de la distancia relativa de los elementos de la propiedad vValue o hValue actual del ScrollPane
.
Para actualizar bajo demanda solo cuando sea necesario, simplemente siga las instrucciones de la respuesta anterior de Tucuxi.
ItemOffset first = verticalOffsets.first();
verticalOffsets.remove(first);
verticalOffsets.add(first);
donde verticalOffsets es una TreeSet<ItemOffset>
. Si imprime el conjunto cada vez que se invoca este fragmento de actualización, verá que está actualizado.
+1 bonita pregunta – skaffman
¿Es solo curiosidad mórbida, o está buscando un beneficio específico, por ejemplo, en rendimiento o simplicidad de código? – greim
Estaba buscando una manera simple no invasiva de mantener el orden de una colección a medida que los eventos actualizan los objetos dentro de ella. Alterar la membresía tiene efectos secundarios en otros consumidores de la colección. IMO, activar un recurso de un elemento parece una funcionalidad básica para una colección ordenada. – Stevko