2013-07-11 11 views
5

Sto avendo difficoltà a capire l'associazione dati nella mia applicazione Eclipse RCP. Non riesco proprio a capire come dovrebbe funzionare ..Le migliori pratiche per l'associazione dati una lista in Eclipse RCP applicazione

Ecco cosa voglio fare

ho una visione in cui deve essere visualizzato un elenco di testi. I testi vengono "memorizzati" in una semplice List<String> che è fornito tramite un singoletto (a scopo dimostrativo;)). Quindi chiunque utilizzi lo ListProvider otterrà l'elenco dei testi. Quando la lista cambia, voglio che la mia vista aggiorni automaticamente i contenuti della tabella.

Ecco quello che ho fatto finora

mio provider dell'elenco è un Observable che provvederà a darne comunicazione osservatori quando la lista modifiche.

A mio avviso creo un osservatore per guardare il fornitore di lista e quando l'osservatore viene notificato rinfresco mio punto di vista.

Codice in materia di ListProvider:

public class ListProvider extends Observable { 

    private Stack<String> hist; 
    private static ListProvider instance; 

    // Singleton implementation 
    public static ListProvidergetInstance() { 
     if (null == instance) { 
      instance = new ListProvider 
     } 
     return instance; 
    } 

    public void add(String text) { 
     if (this.hist.size() == MAX_SIZE) { 
      this.hist.remove(MAX_SIZE-1); 
     } 
     this.hist.add(0, text); 
     // notify all observers 
     this.setChanged(); 
     this.notifyObservers(); 
    } 
} 

codice per la vista:

public class TestView extends ViewPart { 

private TableViewer viewer; 

[...] 

class ViewContentProvider implements IStructuredContentProvider { 
    public void inputChanged(Viewer v, Object oldInput, Object newInput) { 
    } 
    public void dispose() { 
    } 
    public Object[] getElements(Object parent) { 
     return ClipboardHistory.getInstance().getList().toArray(); 
    } 
} 

public void createPartControl(Composite parent) { 
    viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); 
    IContentProvider contentProvider = new ViewContentProvider(); 
    viewer.setContentProvider(contentProvider); 
    viewer.setLabelProvider(new ViewLabelProvider()); 
    viewer.setInput(getViewSite()); 

    Observer listObserver = new Observer() { 
     @Override 
     public void update(Observable o, Object arg) { 
      // update the table viewer 
      viewer.refresh(); 
     } 
    }; 

    ListProvider.getInstance().addObserver(listObserver); 
} 
} 

Domanda

Sta usando Observer e Observable il modo "giusto" per andare o sono io manca qualcosa? Non sono sicuro che abbia afferrato il concetto di RCP Databinding ...

+0

io non sono sicuro circa la portata degli elementi nella vostra lista, ma avete considerato l'aggiunta di un semplice elenco SWT (http://help.eclipse.org/juno/index.jsp?topic=%2Forg.eclipse.platform .doc.isv% 2Freference% 2Fapi% 2Forg% 2Feclipse% 2Fswt% 2Fwidgets% 2FList.html) oggetto per la tua vista invece di un tableviewer ecc ecc – nbz

+0

Inoltre potrebbe essere meglio usare un ListViewer (http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc. isv% 2Freference% 2Fapi% 2Forg% 2Feclipse% 2Fjface% 2Fviewers% 2FListViewer.html) invece di un TableViewer. – nbz

+0

Grazie per l'input. Al momento è solo una lista ma voglio aggiungere più dati ad altre colonne in seguito. Usare un ListViewer cambierebbe il modo in cui osservo l'elenco? – Friederike

risposta

5

vi consiglio di leggere JFace Databinding e fare uso di ViewerSupport, ObservableListContentProvider e BeanProperties per semplificare il lavoro.

È anche possibile vedere un esempio di lavoro JFace Databinding Snippet: Model to TableViewer binding per un riferimento, in cui il legame è fatto finalmente con l'aiuto di ViewerSupport:

(...) 
TableViewer peopleViewer = new TableViewer(committers); 
ViewerSupport.bind(peopleViewer, new WritableList(viewModel.getPeople(), 
    Person.class), BeanProperties.value(Person.class, "name")); 

Con questi aiutanti non sarà necessario per l'attuazione del Observer per la vostra elenca, e se vuoi che il tuo viewer aggiorni le sue etichette quando i dati sono modificati dai un'occhiata nello stesso esempio a PropertyChangeSupport, che ti permette di aggiornare il visualizzatore ad ogni modifica su qualsiasi elemento della lista che hai notificato attraverso di esso. È importante utilizzare BeanProperties per il binding.

+0

Questa sembra una buona soluzione. Ma c'è un modo per usare validatori e convertitori con un visualizzatore di tabelle usando questo? – Lii

1

Io non credo che ci sia qualcosa di sbagliato con il vostro approccio con una sola possibile eccezione. È necessario fare in modo che lo spettatore viene aggiornata nel thread UI:

Display.getDefault().asyncExec(new Runnable() { 
    @Override 
    public void run() { 
     viewer.refresh(); 
    } 
}); 

Tuttavia ci sono cose che si possono fare per rendere l'aggiornamento tavolo più efficiente. Nel codice di cui sopra sembra solo aggiungere un singolo elemento nella parte superiore della tabella, in modo da sarebbe meglio con una chiamata a:

viewer.insert(text, 0); 
+0

Grazie per la nota sul thread dell'interfaccia utente. Per quanto riguarda l'ottimizzazione con 'viewer.insert', non penso sia più efficiente. Non posso essere sicuro di quali modifiche sono state apportate al mio modello. Quindi dovrei controllare gli aggiornamenti/inserimenti/cancellazioni. Questo è molto più costoso di ottenere di nuovo l'intera lista e mostrarla. ;) – Friederike

Problemi correlati