Verzweiflung: treeviewer

waves

Grünschnabel
ich versuche schon seit wochen einen treeviewer zu erstellen, jedoch bisher ohne erfolg. ich habe schon praktisch jedes tutorial durchgearbeitet aber scheinbar bin ich wohl zu blöd dafür. ich hoffe, hier kann mir jemand helfen.

wie gesagt will ich einen treeviewer erstellen. ich habe ein HSSQL datenbank. das query wird ausgeführt und ich erhalte eine ArrayList mit diesen werden als String zurück:

Code:
E-Nature
Music
Movies

ich will diese werde nun in einen treeviewer packen. jeder node hat dann noch diverse subnodes (01, 02, 03 etc.) diese sollte man dann ausklappen können, indem man auf das + links von den werden klickt. also so:

Code:
+ E-Nature
- Music
  01
  02
  03
+ Movies

da ich schon relativ viele tutorials durchgegangen bin und keinen erfolg hatte, wäre es super, wenn jemand mit die code "schnippsel" posten könnte!

danke für hilfe jeglicher art!
 
Was genau verstehst du nicht?
Den Sinn von ITreeContentProvider?
Den Sinn von ILabelProvider?
Die Zusammenarbeit der beteiligten Instanzen?
Wie du von den Datenbank-Daten auf einen Baummodell abbildest?

Du sagst zwar, dass du verschiedene Einführungen gelesen hast, aber wo du im Augenblick stehst sagst du nicht. Zeig doch mal deine bisherigen Versuche, dann reden wir nicht aneinander vorbei.
 
ich habe es gestern nun doch geschafft gemaess tutorial zumindest den beispiel treeviwer zum laufen zu bringen. nun habe ich eigentlich nur noch dieses problem:


da ich die werte fuer den treeviewer in einer arraylist have (als strings), der treeviewer aber scheinbar einen file-typen verlangt, weiss ich nicht genau, wie ich nun diese struktur vom treeviewer anzeigen lassen kann:

Code:
+ E-Nature
- Music
  01
  02
  03
+ Movies

der code vom beispiel, wo der inhalt in den treeviewer eingefuegt wird, sieht so aus:

Code:
...
private TreeViewer tv = new TreeViewer(sash_form);
tv.setContentProvider(new FileTreeContentProvider());
tv.setLabelProvider(new FileTreeLabelProvider());
tv.setInput(new File("C:\\"));
tv.addFilter(new AllowOnlyFoldersFilter());
...

Dort wo zur zeit "C:\\" steht, moechte ich nun die struktur von oben anzeigen. leider weiss ich nicht wie.

Ich habe eine ArrayList mit diesen Strings:
E-Nature
Music
Movies

Ich habe dann noch weitere ArrayLists mit strings mit diesen werten:
01
02
03
etc.

die werte von der zweiten arraylist sollen als subnode bei jedem von den 3 oben erwaehnten werten in der ersten arraylist im treeviewer ersichtlich sein.

ich hoffe, ich konnte mein problem klarer erklaeren!
danke fuer hilfe :)
 
Zuletzt bearbeitet:
ok, also geht es um die Konvertierung in ein Baummodell.

Zwischen dem Holen der Daten und der Anzeige schaltet man einen "Klassenverbund", der als Modell bezeichnet wird. Das könnte hier z.b. so aussehen:

Code:
package main.model;

import java.util.ArrayList;
import java.util.List;

public class CD {
	private String cdName;
	private ArrayList tracks;
	
	public CD( String cdName ) {
		this.cdName= cdName;
		tracks= new ArrayList();
	}
	
	public boolean addTrack(Track o) {
		return tracks.add(o);
	}
	public List getTracks() {
		return tracks;
	}

	public String toString() {
		return cdName;
	}
}
Eine Instanz der Klasse CD repräsentiert eine CD

Code:
package main.model;

public class Track {
	private String trackName;
	private int trackLength; // in seconds
	private CD belongsTo;
	
	public Track(String name, int length, CD to) {
		belongsTo = to;
		trackLength = length;
		trackName = name;
	}
	
	public CD getBelongingCD() {
		return belongsTo;
	}
 
	public String toString() {
		return trackName;
	}
	
}
Eine Instanz der Klasse Track repräsentiert einen Track und ist immer mit einer CD assoziiert.

Ich bau mir mit folgendem Code ein Beispielmodell:
Code:
    ArrayList cds= new ArrayList();
    for( int i= 0; i< 3; i++ ){
    	CD cd= new CD( "cd name " + i );
    	for( int j= 0; j< 10; j++ ) {
    		Track t= new Track( "track " + j, j*j, cd );
    		cd.addTrack( t );
    	}
    	cds.add( cd );
    }
    ListenContentProvider lp= new ListenContentProvider( cds );

das mit folgendem Code angezeigt werden kann:
Code:
package main;

import java.util.ArrayList;
import java.util.List;

import main.model.CD;
import main.model.Track;

import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;

public class ListenContentProvider implements ITreeContentProvider {

	private List cds;

	public ListenContentProvider( ArrayList cds ) {
		this.cds= cds;
	}

	public Object[] getChildren(Object parentElement) {
		if( parentElement instanceof CD )
			return ((CD) parentElement).getTracks().toArray();
		return new Object[] {};
	}

	public Object getParent(Object element) {
		if( element instanceof Track )
			return ((Track) element).getBelongingCD();
		return null;
	}

	public boolean hasChildren(Object element) {
		return element instanceof CD;
	}

	public Object[] getElements(Object inputElement) {
		return cds.toArray();

	}

	public void dispose() {	}
	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {	}
}

Ich hoffe du hast die Idee dahinter verstanden und bist nicht erschlagen :)
 
danke fuer die ausfuehrliche antwort!
aber ich befuerchte, ich habe es nicht ganz begriffen :-(

ich habe mal diese klassen, die du geposted hast, in mein projekt integriert.

was ich nun aber noch immer nicht weiss ist, wie ich diese daten nun in den treeviewer reinbringe.

dort wo der inahlt des treeviewers eingegeben wird, sieht der code bei mir so aus:

Code:
...
    tv = new TreeViewer(sash_form);
    tv.setContentProvider(new FileTreeContentProvider());
    tv.setLabelProvider(new FileTreeLabelProvider());
    tv.setInput(new File("C:\\"));
    tv.addFilter(new AllowOnlyFoldersFilter());
...

was muss ich denn jetzt bei:
Code:
tv.setInput(new File("C:\\"));

genau aendern, damit ich deine angegebenen inhalte im treeviewer anzeigen lassen kann? :confused:

mit dem code von dir:
Code:
    ArrayList cds= new ArrayList();
    for( int i= 0; i< 3; i++ ){
    	CD cd= new CD( "cd name " + i );
    	for( int j= 0; j< 10; j++ ) {
    		Track t= new Track( "track " + j, j*j, cd );
    		cd.addTrack( t );
    	}
    	cds.add( cd );
    }
    ListenContentProvider lp= new ListenContentProvider( cds );

erstelle ich ja die CD objekte, wie diese aber nun in den treeviewer einfuegen?

danke fuer weitere hilfe, bin dafuer echt dankbar! ;)
 
Hallo!

Ich habe das gute Beispiel von kabel2 mal ein wenig aufgebohrt ;-)
schau mal hier:
Code:
 package de.tutorials;
 
 import java.util.ArrayList;
 import java.util.List;
 
 import org.eclipse.jface.viewers.ILabelProvider;
 import org.eclipse.jface.viewers.ILabelProviderListener;
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.window.ApplicationWindow;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 
 import de.tutorials.domain.CompactDisc;
 import de.tutorials.domain.Track;
 
 public class JFaceTreeViewerExample extends ApplicationWindow {
 
 	public JFaceTreeViewerExample(Shell parentShell) {
 		super(parentShell);
 		setBlockOnOpen(true);
 		open();
 	}
 
 	protected Control createContents(Composite parent) {
 
 		TreeViewer treeViewer = new TreeViewer(parent);
 		treeViewer.setContentProvider(new ITreeContentProvider() {
 			public Object[] getChildren(Object parentElement) {
 				if (parentElement instanceof List) {
 		    		return ((List) parentElement).toArray();
 				} else if (parentElement instanceof CompactDisc) {
 		    		return ((CompactDisc) parentElement).getTracks().toArray();
 				}
 				return new Object[0];
 			}
 
 			public Object getParent(Object element) {
 				if (element instanceof Track) {
 		    		return ((Track) element).getAssociatedCompactDisc();
 				} else {
 					return null;
 				}
 			}
 
 			public boolean hasChildren(Object element) {
 				if (element instanceof List) {
 		    		return ((List) element).size() > 0;
 				} else if (element instanceof CompactDisc) {
 		    		return ((CompactDisc) element).getTracks().size() > 0;
 				} else {
 					return false;
 				}
 			}
 
 			public Object[] getElements(Object inputElement) {
 				return getChildren(inputElement);
 			}
 
 			public void dispose() {	}
 
 			public void inputChanged(Viewer viewer, Object oldInput,
 		    		Object newInput) {	}
 		});
 
 		treeViewer.setLabelProvider(new ILabelProvider() {
 			public Image getImage(Object element) {
 				return null;
 			}
 
 			public String getText(Object element) {
 				if (element instanceof CompactDisc) {
 		    		CompactDisc compactDisc = (CompactDisc) element;
 					return compactDisc.getName();
 				} else if (element instanceof Track) {
 					Track track = (Track) element;
 					return track.getName();
 				} else {
 					return null;
 				}
 			}
 
 			public void addListener(ILabelProviderListener listener) {	}
 
 			public void dispose() {	}
 
 			public boolean isLabelProperty(Object element, String property) {
 				return false;
 			}
 
 			public void removeListener(ILabelProviderListener listener) { }
 
 		});
 
 		treeViewer.setInput(initModel());
 
 		return super.createContents(parent);
 	}
 
 	private List initModel() {
 
 		List compactDiscs = new ArrayList();
 		for (int i = 0; i < 3; i++) {
 			CompactDisc compactDisc = new CompactDisc("cd name " + i);
 			for (int j = 0; j < 10; j++) {
 		    	Track t = new Track("track " + j, j * j, compactDisc);
 				compactDisc.addTrack(t);
 			}
 			compactDiscs.add(compactDisc);
 		}
 
 		return compactDiscs;
 	}
 
 	/**
 	 * @param args
 	 */
 	public static void main(String[] args) {
 		Display display = new Display();
 		Shell shell = new Shell(display);
 		new JFaceTreeViewerExample(shell);
 	}
 }

Code:
 package de.tutorials.domain;
 
 import java.util.ArrayList;
 import java.util.List;
 
 public class CompactDisc {
 	String name;
 
 	List tracks;
 
 	public CompactDisc(String name) {
 		this.name = name;
 		tracks = new ArrayList();
 	}
 
 	public boolean addTrack(Track o) {
 		return tracks.add(o);
 	}
 
 	public List getTracks() {
 		return tracks;
 	}
 
 	public String getName() {
 		return name;
 	}
 }

Code:
  package de.tutorials.domain;
 
 public class Track {
 	private String name;
 	private int length; // in seconds
 	private CompactDisc associatedCompactDisc;
 	
 	public Track(String name, int length, CompactDisc associatedCompactDisc) {
 		this.associatedCompactDisc = associatedCompactDisc;
 		this.length = length;
 		this.name = name;
 	}
 	
 	public CompactDisc getAssociatedCompactDisc() {
 		return associatedCompactDisc;
 	}
  
 	public String getName() {
 		return name;
 	}
    
 }

Gruß Tom
 
wow super, danke! das bringt mich echt meilen weiter! werde nun mal diese klassen genauer anschauen, damit ich das auch begreife. werde dann nochmals posten, falls ich an ein problem stosse.

aber:
kann es sein, dass man für einen simplen treeviewer ganze 16 klassen braucht? soviele habe ich zur zeit in meinem test-projekt! :suspekt: das sollte doch bestimmt mit 2-3 auch funktionieren oder irre ich mich da?
 
Von dieser Vorstellung solltest du dich lösen.

Du kannst das ganze auch in EINE EINZIGE Klasse packen. Ohne Innere Klassen. Du wirst nur durch die Tatsache eingeschränkt, dass Java Klassen nur von einer Klasse erben können (genau genommen, nicht mal das).
 
danke fuer die bisherigen tipps. ich habe den treeviewer nun auf ca. 3 klassen "runter bekommen"

der treeviewer funktioniert jetzt auch endlich! :)
nun habe ich noch ein letztes (!) problem. ich moechte ein selection listener machen, welcher mir den angeklickten node (inkl. dem parent node) per system.out.print() ausgibt. (bzw. das ausgibt, was man im treeviewer sieht)

leider habe ich das nicht zum laufen gebracht. :(

die struktur von meinem treeviewer sieht so aus:

Code:
+ Music
  - 01
  - 02
  - 03
+ Movies
  - 01
  - 02
...


bisher habe ich diesen code fuer den selection listener:

Code:
treeViewer1.addSelectionChangedListener(new ISelectionChangedListener() {
  public void selectionChanged(SelectionChangedEvent event) {
  IStructuredSelection selection = (IStructuredSelection) event.getSelection();
                            
  Object selected_file = selection.getFirstElement();
  DiscInArchive ddt = (DiscInArchive) selected_file;
  System.out.println(ddt.getName());
  }
});

der code funktioniert jedoch nur, wenn ich einen subnode (z.b. 01, 02, etc.) anklicke, wenn ich einen parent node anklicke (z.b. Movies), dann kriege ich einen fehler.
irgendwie muesste ich eine abfrage haben, welche rausfindet, ob dies nun ein objekt von der klasse "DiscInArchive" oder von "DiscArchive" ist.

hat mir da jemand ein tipp?
 
Zuletzt bearbeitet:
Zurück