JTree und setSelectionPath

mas666

Mitglied
Hallo zusammen,

Ich versuche, automatisch ein bestimmtes Blatt in einem Baum anzuwählen. Ich bastle mir ein Array aus Objekten, die den Pfad ausmachen.

Also:
Code:
TreePath[] selPath = {null, null, null, null, null, null};  // Pfad enthält immer 6 Objekte

Dann werden die Objekte in das Array gefüllt, um dann daraus den Pfad zu erstellen:

Code:
TreePath selectedPath = new TreePath(selPath);

Danach rufe ich folgende Methoden auf:

Code:
tree.scrollPathToVisible( selectedPath.getParentPath() );
tree.setSelectionPath( selectedPath );

Das funktioniert nicht. Es wird keine Exception ausgelöst, es passiert einfach nix...
Jemand eine Idee?

Was mir spanisch vorkommt: Wenn ich das Blatt manuell anwähle (Mausklick) und den Pfad mit meinem TreeSelectionListener ausgebe, unterscheidet er sich von dem den ich generiert habe:

Erstellter Pfad mit System.out.println:
Code:
[ [a], [b], [ c], [d], [e], [f] ]

Pfad vom TreeSelectionEvent mit System.out.println:
Code:
[a, b, c, d, e, f]

Ich habe aber keinen Konstruktor oder keine Methode gefunden, die meinen Pfad anders zusammenstellt...

Jemand eine Idee?

Danke im Voraus
soma
 
naja, was soll denn passieren?!

TreePath[] selPath = {null, null, null, null, null, null}; // Pfad enthält immer 6 Objekte

Wo führt der Pfad denn hin? (null?!)

Schau dir doch mal getPath() in javax.swing.tree.DefaultMutableTreeNode an...

yourtree.setSelectionPath(yournode.getPath);
 
Hi benhaze,

Danke für Deinen Post. Leider hast Du den Meinen nicht richtig durchgelesen, sonst hättest Du folgendes bemerkt:

Dann werden die Objekte in das Array gefüllt, um dann daraus den Pfad zu erstellen.

Ausserdem habe ich geschrieben, dass ich keine Exception erhalte, deshalb sind diese Objekte auch sicherlich nicht null. Anstatt euch mit den wirklichen Objekten (oder was toString halt so ausgibt) zu langweilen habe ich ja auch dummies verwendet, siehe:

Erstellter Pfad mit System.out.println:

Code:
[ [a], [b], [ c], [d], [e], [f] ]

Pfad vom TreeSelectionEvent mit System.out.println:

Code:
[a, b, c, d, e, f]

Ich habe aber keinen Konstruktor oder keine Methode gefunden, die meinen Pfad anders zusammenstellt...

Hier ist ja offensichtlich auch der Kern des Problems. Mein Pfad wird nicht richtig zusammengestellt.

Du meintest:
Schau dir doch mal getPath() in javax.swing.tree.DefaultMutableTreeNode an...
yourtree.setSelectionPath(yournode.getPath);

Tja, wie soll ich sagen? Ich benutze natürlich keine DefaultMutableTreeNode-Objekte, ich arbeite mit einem TreeModel das vom AbstractTreeModel erbt und Nodes die das Interface TreeNode implementieren.

Aber wie gesagt:
Das Grundproblem scheint ein anderes zu sein. Wenn ich einen Pfad im Baum klicke und ihn ausgebe (TreeSelectionListener) ist das nicht dasselbe, wie wenn ich aus einem Objekt-Array einen Pfad erstelle, obwohl (und das habe ich geprüft!) die einzelnen Elemente des Objekt-Arrays aus dem ich den Pfad erstelle dieselben sind wie im angeklickten Pfad.

So, ich hoffe meine Problemschilderung war jetzt klarer.

Gruss
Soma
 
Üblicherweise versuche ich schon richtig zu lesen...

erst schreibst du:
TreePath[] selPath = {null, null, null, null, null, null}; // Pfad enthält immer 6 Objekte

dann schreibst du:
Dann werden die Objekte in das Array gefüllt, um dann daraus den Pfad zu erstellen:

dazu der code:
TreePath selectedPath = new TreePath(selPath);

was soll ich davon halten?

Außerdem verstehe ich das Wort *NATÜRLICH* in deiner Aussage nicht....
Ich benutze natürlich keine DefaultMutableTreeNode-Objekte
ist DefaultMutableTreeNode deprecated?! (oder böse?)
(meinetwegen ist es für dich nicht zu gebrauchen.....das ist mir aber egal....dein NATÜRLICH allerdings impliziert, das dies wohl NICHT egal ist und im unmittelbaren Zusammenhang mit deinem Problem steht....)

Ebenso bin ich niemals davon ausgegangen, das du DefaultMutableTreeNode nutzt (wäre dir aufgefallen, hättest du mein Post richtig gelesen...)

wie dem auch sei....

DefaultMutableTreeNode implementiert natürlich auch TreeNode.
Zusätzlich gibt es aber in der DefaultMutableTreeNode-Implementation noch die Methode -> getPath().
Diese Methode *könntest* du ebenfalls in deiner Implementation einbauen (oder sogar kopieren)....natürlich mit allem was dazugehört.....
schon funktioniert -> yourtree.setSelectionPath(yournode.getPath);

Deine Methode, den TreePath irgendwie zusammenzubacken, scheint mir unnötig....
 
Hi benhaze,

Danke für Dein erneutes Posten. Du hörst Dich etwas verärgert an, falls dies der Fall sein sollte, bitte entschuldige. Ich wollte weder anzweifeln, dass Du normalerweise richtig liest noch wollte ich mit meinem 'natürlich andeuten', dass Deine Tipps nicht zu gebrauchen wären.

Lass mich deshalb klarstellen:

- Ich dachte, ich stelle nur die wirklich relevanten Code-Zeilen in den Post. Deshalb hab ich den Teil wo das Array gefüllt wird nur in Textmässig wiedergegeben. Ich initialisiere ein Array mit 6 Einträgen (die anfänglich null sind), suche mit diversen verschachtelten und mühsam zu verstehenden Schleifen die einzelnen Pfadobjekte aus meinem Konstrukt und fülle damit das Array. Das Array hat dann folgende Form:

{ Project, Area, Room, System, Computer, Property }

D.h. das Array enthält Objekte des oben genannten Typs. Gleichzeitig zeigt das Array die grunbdsätzliche Struktur meines Baumes (Ein Projekt enthält, Areas, Areas enthalten Rooms, Rooms enthalten Systeme, Systeme enthalten Properties), die eben nicht nur Struktur meines Baumes sondern eben auch Struktur anderer Anzeigen ist. Deshalb habe ich ein Model erstellt, dass mit dieser Struktur etwas anzufangen weiss, deshalb habe ich auf den Gebrauch von DefaultMutableTreeNodes verzichtet.

Nun hoffe ich, dass Du mein 'natürlich' auch so interpretieren kannst wie es gemeint war, nämlich: "Ja ich weiss, mit einer DefaultMutableTreeNode wäre alles einfacher aber NATÜRLICH hat sich der doofe Soma das nicht von vornherein überlegt und nur das TreeNode interface implementiert."

Will heissen DefaultMutableTreeNodes sind IMHO weder böse noch schlecht noch depreceated sondern leider für mein System nicht zu gebrauchen, weil es ein bestehendes anzupassendes System ist und einen zu grossen Umbau bedingen würde.

DefaultMutableTreeNode implementiert natürlich auch TreeNode.
Zusätzlich gibt es aber in der DefaultMutableTreeNode-Implementation noch die Methode -> getPath().
Soweit klar, ich denke, das bekomme ich auch hin, bin dabei es auszuprobieren.

Deine Methode, den TreePath irgendwie zusammenzubacken, scheint mir unnötig....

Dann will ich einen Erklärungsversuch starten, wieso ich das mache:

- Ich habe eine Verbindung zu einem beliebigen Server (Industrielles Kontrollsystem oder auch PC)
- Dieser Server schickt mir eine Information im Textformat (im Stil: AA:BB:CC,DD)
- Nun referenziert AA eine Area, BB einen Room, CC einen Computer in einem System und DD eine Property
- Ich durchlaufe meine Projektstruktur und kann so relativ einfach die richtigen Objekte finden, die den Pfad ausmachen.
- Diesen Pfad möchte ich dann auswählen, so als hätte ich drauf gecklickt.

Bis hier habe ich (auch wenn ich Dein Argument, dass es mühsam ist, den Pfad so zu basteln gerne gelten lasse) auch keine Probleme!

Nun habe ich aber ein Array mit den richtigen Objekten:

{ Project, Area, Room, System, Computer, Property }

Wenn ich aber jetzt einen Pfad erstelle und eben die Funktion

Code:
tree.setSelectionPath( selectedPath );

aufrufe geschieht rein gar nichts. Was laut API bedeutet, dass der Pfad nicht exisitiert.

Also bin ich auf die Suche gegangen, was falsch sein könnte. Ich habe verifiziert, dass ich die richtigen Objekte in das Array fülle und habe dann meinen Pfad mit jenem Pfad verglichen, der vom TreeSelectionListener ausgegeben wird und habe festgestellt was ich im ersten Post eigentlich sagen wollte:

Der Pfad des TreeSelectionEvent hat bei toString() die folgende Form:

[ Project, Area, Room, System, Computer, Property ]

Mein erstellter Pfad hat allerdings diese Sruktur:

[ [Project], [Area], [Room], [System], [Computer], [Property] ]

Dies obwohl die API zum Konstruktor

Code:
public TreePath(Object[] path)

sagt, dass das Objekt-Array EINEN Pfad erstellen würde, was hier aber nicht so aussieht.

Weisst Du, wie man einen gültigen solchen Pfad erstellt, was ich dabei falsch mache oder was ich beachten muss?

Auch wenn ich mir Deinen Vorschlag zu herzen genommen habe und eine getPath()-Methode implementieren versuchen werde, bin ich trotzdem froh um eine Antwort.

Ich hoffe, es ist Dir klar, dass ich Dich nicht verärgern wollte? Wollte Dich nicht angreifen und so wie "lies zuerst mal richtig" sollte es auf keinen Fall klingen.

Gruss
Soma
 
ok,ok ...kein problem......bin heute etwas gereizt.....
hast du mal versucht den code zu *debuggen*?!

ich meine, was passiert bei setSelectionPath() genau?
warum ist ER der meinung, das es den pfad nicht gibt?
(was vergleicht ER?)
möglichweise baust du den path ja doch mit *falschen* objekten auf...
nimmst du für den path die konkreten objekte (also project,area,room?) oder nimmst du die TreeNodes (welche dann die konkreten objekte beinhalten)

was passiert, wenn du einfach getPath() UND getPathToRoot(TreeNode aNode, int depth) 1:1
von DefaultMutableTreeNode in deine Implementation kopierst?
Dann kannst du auch sehen, wie ER den Pfad zusammenbauen würde....
 
Es gibt Tage, da sieht man den Wald vor lauter Bäumen nicht. Ich habe meinen Fehler gefunden. Anstatt ein Array aus einzelnen (unvollständigen) TreePath-Objekten zu erstellen wäre es ratsamer nur die TreeNode-Objekte in das Array zu schreiben um danach sauber einen einzelnen Pfad zu generieren. Funktioniert TippTopp.

Ich habe auch die getPathToRoot-Methode angeschaut und sie wäre wahrscheinlich etwas konsistenter und einfacher als meine Methode. Leider kann ich meine TreeNode-Klassen nicht bearbeiten da sie (wie gesagt) aus einer bestehenden Programmierung stammen.

Anyway: Danke für Deine Zeit, deine Geduld und Deine Tipps.

Gruss
Soma
 
Zurück