2015-02-11 17 views
6

Tại sao không có ObservableQueue trong JavaFX? Nếu chúng ta xem xét tài liệu Java 9 (chỉ để xem nếu có bất kỳ thay đổi nào từ 8) cho FXCollections, chúng ta sẽ thấy các phương thức trợ giúp tĩnh để tạo các bộ, danh sách và bản đồ có thể quan sát. Cũng có một số phương thức để tạo các mảng float và float. Tuy nhiên, không có cách nào để tạo ra một ObservableQueue. Giao diện hàng đợi trong Java có nhiều triển khai thú vị, bao gồm ArrayDeque, DelayQueue, ConcurrentLinkedQueue, PriorityQueue, vv Logic là gì đằng sau lý do tại sao không có sự hỗ trợ để tạo ObservableQueues trong JavaFX.Tại sao không có ObservableQueues trong JavaFX?

Trả lời

6

Khi nhận xét @TomasMikula trong câu trả lời của @ eckig (hiện đã bị xóa), có thể chỉ không đủ nhu cầu cho số ObservableQueue. Nếu bạn có một trường hợp sử dụng vững chắc, bạn nên xem xét submitting a feature request.

Trong khi đó, nó không phải là quá khó để tạo ra một cách nhanh chóng-và-bẩn ObservableQueue thực hiện Queue và thêm "năng quan sát" bởi subclassing ObservableListBase và quấn một thực hiện Queue. Phân lớp ObservableListBase là phần "nhanh", nhưng cũng là phần "bẩn" vì bạn phơi bày các phương pháp List cũng như các phương pháp Queue; vì một tùy ý Queue không có get(int index) cách duy nhất để thực hiện điều đó (mà tôi có thể thấy) là lặp qua tối đa index. Mọi thứ sử dụng get để lặp qua số ObservableQueue, liên quan đến số này là List, sẽ chạy trong thời gian O(n^2). Trong bối cảnh đó, những điều sau đây nên làm việc khá tốt:

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

} 

Bạn có thể đăng ký ListChangeListener s với điều này để được thông báo về những thay đổi vào hàng đợi. (Lưu ý rằng nếu bạn muốn hỗ trợ các trình gỡ bỏ và cập nhật các thông báo, bạn cần phải thực hiện nhiều công việc hơn một chút ...).

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

} 
Các vấn đề liên quan