【问题标题】:Why are there no ObservableQueues in JavaFX?为什么 JavaFX 中没有 ObservableQueues?
【发布时间】:2015-04-11 13:20:34
【问题描述】:

为什么 JavaFX 中没有 ObservableQueue?如果我们查看 FXCollections 的 Java 9 文档(只是想看看 8 是否有任何更改),我们会看到用于创建 Observable 集、列表和映射的静态辅助方法。还有一些方法可以创建 Observable 浮点和整数数组。但是,没有办法创建 ObservableQueue。 Java中的Queue接口有很多有趣的实现,包括ArrayDeque、DelayQueue、ConcurrentLinkedQueue、PriorityQueue等。JavaFX中不支持创建ObservableQueues背后的逻辑是什么。

【问题讨论】:

    标签: java javafx queue observablelist


    【解决方案1】:

    作为@eckig(现已删除)答案中的@TomasMikula cmets,可能对ObservableQueue 的需求不足。如果你有一个可靠的用例,你应该考虑submitting a feature request

    与此同时,创建一个快速而肮脏的ObservableQueue 实现Queue 并通过子类化ObservableListBase 并包装Queue 实现来添加“可观察性”并不难。子类化ObservableListBase 是“快速”部分,但也是“脏”部分,因为您公开了List 方法以及Queue 方法;因为任意Queue 没有get(int index),所以实现它的唯一方法(我可以看到)是迭代到index。任何使用get 来遍历ObservableQueue,将其视为List,都将在O(n^2) 时间运行。有了这个警告,以下应该可以很好地工作:

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

    您可以在此注册ListChangeListeners,以便在队列修改时收到通知。 (请注意,如果你想支持提取器和更新通知,你需要做更多的工作......)。

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

    【讨论】:

      猜你喜欢
      • 2013-12-05
      • 2017-01-11
      • 1970-01-01
      • 1970-01-01
      • 2021-03-04
      • 2022-01-15
      • 1970-01-01
      • 2016-09-03
      • 2018-12-13
      相关资源
      最近更新 更多