2015-02-11 22 views
6

Perché non c'è ObservableQueue in JavaFX? Se guardiamo alla documentazione di Java 9 (solo per vedere se ci sono modifiche da 8) per FXCollections, vediamo i metodi di supporto statici per creare set, elenchi e mappe osservabili. Esistono anche alcuni metodi per creare array float e interi osservabili. Tuttavia, non c'è modo di creare un ObservableQueue. L'interfaccia Queue in Java ha molte implementazioni interessanti, tra cui ArrayDeque, DelayQueue, ConcurrentLinkedQueue, PriorityQueue, ecc. Qual è la logica alla base del motivo per cui non vi è alcun supporto per la creazione di ObservableQueues in JavaFX.Perché non ci sono ObservableQueues in JavaFX?

risposta

6

Come @TomasMikula commenti nella risposta di @ eckig (ora cancellata), probabilmente non c'è abbastanza richiesta per un ObservableQueue. Se hai un caso d'uso solido, dovresti considerare submitting a feature request.

Nel frattempo, non è troppo difficile creare un breve-e-sporco ObservableQueue attuazione Queue e aggiungendo "osservabilità" sottoclasse ObservableListBase e avvolgendo un'implementazione Queue. La sottoclasse ObservableListBase è la parte "rapida", ma anche quella "sporca" perché esponi i metodi List e i metodi Queue; dato che un arbitrario Queue non ha un get(int index) l'unico modo per implementarlo è quello di iterare fino a index. Tutto ciò che utilizza get per iterare attraverso lo ObservableQueue, considerandolo come List, verrà eseguito nel tempo O(n^2). Con questo avvertimento, il seguente dovrebbe funzionare abbastanza bene:

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

} 

È possibile registrare ListChangeListener s con questo ricevere una notifica di modifiche alla coda. (Nota che se vuoi supportare gli estrattori e aggiornare le notifiche, devi fare un po 'più di lavoro ...).

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

} 
Problemi correlati