Warum gibt es in JavaFX keine ObservableQueue? Wenn wir für FXCollections die Java 9-Dokumentation betrachten (nur um zu sehen, ob es Änderungen von 8 gibt), sehen wir statische Hilfsmethoden, um Observable-Sets, Listen und Maps zu erstellen. Es gibt auch einige Methoden zum Erstellen von Observable-Float- und Integer-Arrays. Es gibt jedoch keine Möglichkeit, eine ObservableQueue zu erstellen. Die Warteschlangenschnittstelle in Java hat viele interessante Implementierungen, einschließlich ArrayDeque, DelayQueue, ConcurrentLinkedQueue, PriorityQueue usw. Was ist die Logik hinter dem Grund, warum es keine Unterstützung für die Erstellung von ObservableQueues in JavaFX gibt?Warum gibt es in JavaFX keine ObservableQueues?
Antwort
Da @TomasMikula Kommentare in @ eckigs (jetzt gelöschte) Antwort gibt, gibt es wahrscheinlich nicht genug Nachfrage für eine ObservableQueue
. Wenn Sie einen soliden Anwendungsfall haben, sollten Sie submitting a feature request in Betracht ziehen.
In der Zwischenzeit ist es nicht allzu schwer, eine schnelle und unsaubere ObservableQueue
Umsetzung Queue
und das Hinzufügen von „Beobachtbarkeit“ durch eine Queue
Implementierung Subklassen ObservableListBase
und Verpackung zu schaffen. Subclassing ObservableListBase
ist der "schnelle" Teil, aber auch der "schmutzige" Teil, weil Sie List
Methoden sowie Queue
Methoden aussetzen; da eine beliebige Queue
hat keine get(int index)
die einzige Möglichkeit zu implementieren, dass (die ich sehen kann) ist bis zu index
durchlaufen. Alles, was get
verwendet, um durch die ObservableQueue
zu durchlaufen, in Bezug auf es als List
, wird in O(n^2)
Zeit ausgeführt. Mit diesem Vorbehalt sollte Folgendes ziemlich gut funktionieren:
import java.util.LinkedList;
import java.util.Queue;
import javafx.collections.ObservableListBase;
public class ObservableQueue<E> extends ObservableListBase<E> implements Queue<E> {
private final Queue<E> queue ;
/**
* Creates an ObservableQueue backed by the supplied Queue.
* Note that manipulations of the underlying queue will not result
* in notification to listeners.
*
* @param queue
*/
public ObservableQueue(Queue<E> queue) {
this.queue = queue ;
}
/**
* Creates an ObservableQueue backed by a LinkedList.
*/
public ObservableQueue() {
this(new LinkedList<>());
}
@Override
public boolean offer(E e) {
beginChange();
boolean result = queue.offer(e);
if (result) {
nextAdd(queue.size()-1, queue.size());
}
endChange();
return result ;
}
@Override
public boolean add(E e) {
beginChange() ;
try {
queue.add(e);
nextAdd(queue.size()-1, queue.size());
return true ;
} finally {
endChange();
}
}
@Override
public E remove() {
beginChange();
try {
E e = queue.remove();
nextRemove(0, e);
return e;
} finally {
endChange();
}
}
@Override
public E poll() {
beginChange();
E e = queue.poll();
if (e != null) {
nextRemove(0, e);
}
endChange();
return e ;
}
@Override
public E element() {
return queue.element();
}
@Override
public E peek() {
return queue.peek();
}
@Override
public E get(int index) {
Iterator<E> iterator = queue.iterator();
for (int i = 0; i < index; i++) iterator.next();
return iterator.next();
}
@Override
public int size() {
return queue.size();
}
}
Sie ListChangeListener
s mit diesem Register können von Änderungen an der Warteschlange benachrichtigt. (Beachten Sie, dass Sie, wenn Sie Extraktoren unterstützen und Benachrichtigungen aktualisieren möchten, etwas mehr Arbeit benötigen ...).
import javafx.collections.ListChangeListener.Change;
public class ObservableQueueTest {
public static void main(String[] args) {
ObservableQueue<String> oq = new ObservableQueue<>();
oq.addListener((Change<? extends String> change) -> {
while (change.next()) {
if (change.wasAdded()) {
System.out.println("Added: "+change.getAddedSubList());
}
if (change.wasRemoved()) {
System.out.println("Removed: "+change.getRemoved());
}
if (change.wasUpdated()) {
System.out.println("Updated: "+oq.subList(change.getFrom(), change.getTo()));
}
if (change.wasReplaced()) {
System.out.println("Replaced");
}
}
});
oq.offer("One");
oq.offer("Two");
oq.offer("Three");
System.out.println("Peek: "+oq.peek());
System.out.println("Remove...");
System.out.println(oq.remove());
System.out.println("Element:");
System.out.println(oq.element());
System.out.println("get(1): "+oq.get(1));
System.out.println("Poll: ");
System.out.println(oq.poll());
System.out.println("Poll again:");
System.out.println(oq.poll());
System.out.println("Poll should return null:");
System.out.println(oq.poll());
System.out.println("Element should throw exception:");
System.out.println(oq.element());
}
}