为什么JavaFX中没有ObservableQueues? [英] Why are there no ObservableQueues in JavaFX?
问题描述
为什么JavaFX中没有ObservableQueue?如果我们查看FXCollections的Java 9文档(只是为了查看是否有任何更改),我们会看到静态帮助器方法来创建Observable集,列表和映射。还有一些方法可以创建Observable浮点数和整数数组。但是,无法创建ObservableQueue。 Java中的Queue接口有许多有趣的实现,包括ArrayDeque,DelayQueue,ConcurrentLinkedQueue,PriorityQueue等。为什么不支持在JavaFX中创建ObservableQueues的原因是什么。
Why are there no ObservableQueue in JavaFX? If we look at the Java 9 documentation (just to see if there are any changes from 8) for FXCollections, we see static helper methods to create Observable sets, lists, and maps. There are also some methods to create Observable float and integer arrays. However, there is no way to create an ObservableQueue. The Queue interface in Java has many interesting implementations, including ArrayDeque, DelayQueue, ConcurrentLinkedQueue, PriorityQueue, etc. What is the logic behind the reason why there is no support for creating ObservableQueues in JavaFX.
推荐答案
@TomasMikula评论@ eckig(现已删除)的回答,可能只是对 ObservableQueue
。如果您有一个坚实的用例,您应该考虑提交功能请求。
As @TomasMikula comments in @eckig's (now-deleted) answer, there probably just is not enough demand for an ObservableQueue
. If you have a solid use-case, you should consider submitting a feature request.
与此同时,创建快速而肮脏的 ObservableQueue
实施<$ c $并不难c> Queue 并通过继承 ObservableListBase
并包装 Queue
实现来添加observability。子类 ObservableListBase
是快速部分,也是脏部分,因为您公开了 List
方法以及队列
方法;因为任意 Queue
没有 get(int index)
实现它的唯一方法(我可以看)是迭代到索引
。任何使用获取
来迭代 ObservableQueue
,将其视为列表
,将在 O(n ^ 2)
时间内运行。有了这个警告,以下内容应该可以很好地工作:
In the meantime, it's not too hard to create a quick-and-dirty ObservableQueue
implementing Queue
and adding "observability" by subclassing ObservableListBase
and wrapping a Queue
implementation. Subclassing ObservableListBase
is the "quick" part, but also the "dirty" part because you expose List
methods as well as Queue
methods; since an arbitrary Queue
doesn't have a get(int index)
the only way to implement that (that I can see) is to iterate through up to index
. Anything that uses get
to iterate through the ObservableQueue
, regarding it as a List
, will run in O(n^2)
time. With that caveat, the following should work pretty well:
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();
}
}
您可以注册 ListChangeListener
s,以此通知队列的修改。 (注意,如果你想支持提取器和更新通知,你需要做更多的工作......)。
You can register ListChangeListener
s with this to be notified of modifications to the queue. (Note that if you want to support extractors and update notifications, you'd need to do quite a bit more work...).
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());
}
}
这篇关于为什么JavaFX中没有ObservableQueues?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!