TableViewer Contentprovider

Status
Nicht offen für weitere Antworten.

Clip

Bekanntes Mitglied
Hallo,

ich habe einen TableViewer. Diesem teile ich mittels setInput() eine Datenquelle mit. Als ContentProvider habe ich ArrayContentProvider angegeben. Dieser tut leider laut API spezifikation nichts bei inputChanged()
Code:

inputChanged(Viewer viewer, Object oldInput, Object newInput)
This implementation does nothing.


Was ist ein guter Contentprovider wenn ich Tabellen benutzen will und gleichzeitig den Eclipse Adapter Mechanismus[1] benutzen möchte?
Gleichzeitig soll sich der Inhalt der Tabelle mittels Listener und tabelViewer.refrech() aktualisieren lassen.

[1]
Eclipse Rich Client Platform - Designing, Coding, and Packaging Java Applications
Kapitel 5.4.2
Seite: 73 unten.
 

byte

Top Contributor
Wenn Du wirklich nur ein Array im TableViewer darstellen willst, dann kannste ruhig den ArrayContentProvider nehmen. Normalerweise arbeitet man aber mit eigenen Datenstrukturen und implementiert sich demnach auch einen eigenen ContentProvider und LabelProvider.

Aktualisieren kannst Du übrigens immer mittels tableViewer.refresh(). Das hat gar nix damit zu tun, welchen ContentProvider Du nun verwendest. Demnach brauchst Du auch nicht zwingend die inputChanged() zu implementieren, sondern aktualisierst den tableViewer einfach per Refresh in einem Listener.
 

Clip

Bekanntes Mitglied
Hallo und danke für die Antwort!
ich möchte natürlich kein Array darstellen sonder eine Tabelle. Zum Probieren hat ders aber ersteinmal getan.
Mit dem TableViewer.refresh() klappt es aber nicht bei mir :(
Ich habe mal :
Code:
		tableViewer.setInput(Session.getInstance().getRack(getRackID()).getSamples());	
		Session.getInstance().getRack(getRackID()).addUpdatableObjectListener(new IUpdatableObjectListener(){
			public void updatableObjectChanged(UpdatableObject parent, UpdatableObject current) {
				tableViewer.refresh();	
				MessageDialog.openInformation(null, "Info!", new Integer(((Rack)current).getSamples().length).toString());
			}			
		});

Die Methode "updatableObjectChanged" wird ausgeführt! Der Nachrichtendialog in dessen Rumpf wird immer dann angezeigt wenn es eine Änderung om Model gibt. Die Methode getSamples() liefert sogar die aktualisierte Länge des Array (der Samples im Rack) zurück.
Komischerweise wird aber die Tabelle nicht geupdated. :(

Gibt es einen Trick oder sowas?
 

Wildcard

Top Contributor
Da gibts eigentlich gar nicht viel zu erklären, du musst nur die Methoden des Interfaces erfüllen, und die Javadocs dazu sind ja recht klar.
Der ContentProvider ist dazu da Daten aus dem Model zu extrahieren, so das also anders als in Swing keine Anforderungen an das Model selbst gestellt werden. Du kannst auf jedem Model arbeiten solange du einen passenden ContentProvider zur Verfügung stellst.
 

Clip

Bekanntes Mitglied
Das mit dem passenden Content Provider ist ha genau das Problem.

Mein Provider benutzt das Interface IStructuredContentProvider
Dieses stellt die Methode public Object[] getElements(Object parent) zur Verfügung.
In diesem könnte ich z.B. mittels Rack.getSamples() alle Samples als Array zurückgeben.

Im Labelprovider würde das dann in etwa so aussehen:
Code:
		public String getColumnText(Object element, int columnIndex) {
			if (element instanceof Sample)
				return ((Sample)element).getName();
			else
				return null;
		}

Das bewirkt aber, dass alle Samples in der ersten Spalte meiner Tabelle dargestellt werden.

Meine Sampleklasse hat je ein X und ein Y Wert. Ich möchte aber, dass ein Sample Object an der Stelle in der Tabelle dargestellt wird, die diesen Werten entspricht.
 

byte

Top Contributor
Dafür wird doch die Column als Argument übergeben. Du musst es halt entsprechend auswerten, z.b. so:

Code:
public String getColumnText(Object element, int columnIndex) {
         if (element instanceof Sample)
            Sample sample = (Sample)element;
            switch(columnIndex) {
            case 0: return ...;
            case 1: return ...;
            case default: return ...;
            }
         else
            return null;
      }
 

Wildcard

Top Contributor
Der ContentProvider gibt für getElements Objekte zurück die die Rows repräsentieren.
Alles andere muss der LabelProvider erledigen
void org.eclipse.jface.viewers.TableViewer.setLabelProvider(IBaseLabelProvider labelProvider) hat gesagt.:
The table viewer implementation of this Viewer framework method ensures that the given label provider is an instance of either ITableLabelProvider or ILabelProvider.

If the label provider is an ITableLabelProvider, then it provides a separate label text and image for each column. Implementers of ITableLabelProvider may also implement ITableColorProvider and/or ITableFontProvider to provide colors and/or fonts.

If the label provider is an ILabelProvider, then it provides only the label text and image for the first column, and any remaining columns are blank. Implementers of ILabelProvider may also implement IColorProvider and/or IFontProvider to provide colors and/or fonts.
 

Clip

Bekanntes Mitglied
Also ein Problem habe ich noch.

Mein Labelprovider:
Code:
	private class RackTableLabelProvider extends LabelProvider implements ITableLabelProvider{

		public Image getColumnImage(Object element, int columnIndex) {
			if (element instanceof Sample && columnIndex == ((Sample)element).getX()){
				return AbstractUIPlugin.imageDescriptorFromPlugin(Application.PLUGIN_ID, IImageKeys.SAMPLE).createImage();
			}
			return null;
		}
	

		public String getColumnText(Object element, int columnIndex) {
			if (element instanceof Sample && columnIndex == ((Sample)element).getX())
				return ((Sample)element).getName();
			else				
				return null;
		}
				
	}

Mein ContentProvider:
Code:
	private class RackTableContentProvider extends LabelProvider implements IStructuredContentProvider{

		public Object[] getElements(Object inputElement) {
			return rack.getSamples();
		}
		
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			
		}	
	}

Der Contentprovider erstellt also für jedes Sample eine Tabellenreihe. Innerhalb der Tabellenreihe filter ich dann alle Einträge raus, die nicht in die Spalte passen (sample.x != columnIndex).
Mir fehlt die Möglichkeit Die Y Achse (die Zeilen) bestimmen zu können.
Oder mache ich grundlegend was falsch?

Ps.: Seit ich meine eigenen Content und Labelprovider benutze geht der Tablerefresh :)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen

Ähnliche Java Themen


Oben