Jtree Knoten ändern

Zipp

Mitglied
Ich habe mich am JTree mal versucht.
Dank diesem Tutorual win ich auch schon weit gekommen. Mein Problem ist jetzt das ändern von Knoten.

Ich habe die Klassen aus dem vierten Teil überneommen und versucht sie so zu erweitern, dass ich Knoten umbennen kann. Dafür habe ich die Klasse ChangeableModel um folgende Klasse erweitert:
Java:
  public void change(TreePath path, MutableTreeNode node) {
    Object parent = path.getParentPath().getLastPathComponent();
    Object child = path.getLastPathComponent();
    int index = getIndexOfChild(parent, child);
    ((MutableTreeNode)parent).insert(node, index);

    TreeModelEvent event = new TreeModelEvent(this, path.getParentPath(),
        new int[] { index }, new Object[] { node });
    for (TreeModelListener listener : listeners) {
      listener.treeNodesChanged(event);
    }
  }

Desweiteren habe ich eine Klasse ChangeAction angelegt, die sich an den Klassen AddAction und RemoveAction orierntiert:
Java:
class ChangeAction extends TreeAction {
  public ChangeAction(JTree tree, ChangeableModel model) {
    super(tree, model);
  }
  
  @Override
  protected void invoked() {
    TreePath[] paths = tree.getSelectionPaths();
    if (paths != null) {
      tree.clearSelection();
      for (TreePath path : paths) {
        MutableTreeNode node = new MutableTreeNode("changed");
        model.change(path, node);
      }
    }
  } 
}

Jetzt zu meinem Problem:
Der Knoten wird wie erwartet ausgetauscht und es wird auch "changed" angezeigt. Problem ist, das das Icon nicht mehr stimmt, sowie die Linien vor dem Icon (bei Windows ist es ein + und ein - Zeichen). Wenn ich einen Knoten ändern wird immer das Icon für ein Blatt angezeigt.
Weiß jemand welchen fehler ich gemacht habe?
Und eine kleinere Frage: Wie bekommt man denn TreePath, zu dem Knoten den ich gerade geändert habne, so dass ich ihn über
Java:
tree.addSelectionPath
auswählen kann?
 

Ebenius

Top Contributor
Du machst den Fehler, dass Du den Knoten zum Parent hinzufügst, den alten Knoten aber nicht entfernst. Und Du sagst den Zuhörern (also dem JTree) [c]listener.treeNodesChanged(event);[/c]. Das passt erstens nicht zum hinzufügen des Knotens. Und zweitens ist dieser Event-Typ dafür gedacht, dass sich der Wert eines Knotens ändert, die Struktur aber nicht. Da jedoch der alte Knoten ggf. Kinder hatte, oder der neue welche haben kann, musst Du eine Strukturänderung bekannt geben. Probier's mal so (ungetestet):
[java=5] public void change(TreePath path, MutableTreeNode node) {
Object parent = path.getParentPath().getLastPathComponent();
Object child = path.getLastPathComponent();
int index = getIndexOfChild(parent, child);
((MutableTreeNode)parent).remove(index);
((MutableTreeNode)parent).insert(node, index);

TreeModelEvent event = new TreeModelEvent(this, path.getParentPath(),
new int[] { index }, new Object[] { node });
for (TreeModelListener listener : listeners) {
listener.treeStructureChanged(event);
}
}[/code]

Den neuen Pfad machst Du einfach aus dem alten...
Java:
TreePath newPath = path.getParentPath().pathByAddingChild(newNode)
Ebenius
 

Zipp

Mitglied
Danke für die schnelle Antwort. So ähnlich hatte ich das auch mal ausprobiert, aber beim Entfernen des "alten" Knotens werden auch seine Kinder gelöscht, sodass diese dann nicht mehr am neuen hängen.
 
Zuletzt bearbeitet:

Ebenius

Top Contributor
Hm, aber wenn Du den Knoten nicht ändern möchtest (der Knoten enthält ja die Kinder) sondern nur das User Object (meist ein Text), dann solltest Du das anders machen. In etwa:

Java:
  public void setNodeValue(TreePath path, Object value) {
    Object parent = path.getParentPath().getLastPathComponent();
    Object child = path.getLastPathComponent();
    int index = getIndexOfChild(parent, child);
    ((MutableTreeNode)child).setUserObject(value);
 
    TreeModelEvent event = new TreeModelEvent(this, path.getParentPath(),
        new int[] { index }, new Object[] { node });
    for (TreeModelListener listener : listeners) {
      listener.treeNodesChanged(event);
    }
  }
Ebenius
 

Zipp

Mitglied
Beim Thema JTree bin ich wieder an ein Problem gekommen, welches ich irgendwie nicht nachvollziehen kann. Ich möchte, dass die Kinder eines Knoten in einer bestimten Reihenfolge (beispielsweise alphabetisch). Daher übergebe ich der addNode-Methode neben dem Pfad zum Eltern-Knoten und dem neuen Knoten auch noch einen Index um den Knoten an einer besimmten stelle einzufügen.

Das Problem liegt natürlich wieder beim verändern des Knotens. Wenn das UserObject geändert wird, kann es sein, dass es in einer anderen Position muss, damit die Reihenfolge weiter stimmt.

Daher habe ich mir Folgendes überlegt:
Java:
  public void changeUserObject(TreePath path, Object newUserObject, int newIndex) {
    DefaultMutableTreeNode parent = (DefaultMutableTreeNode) path.getParentPath().getLastPathComponent();
    DefaultMutableTreeNode child = (DefaultMutableTreeNode) path.getLastPathComponent();
    int oldIndex = getIndexOfChild(parent, child);
    
    child.setUserObject(newUserObject);
    

    if (oldIndex != newIndex) {
      if (newIndex > oldIndex) {
        --newIndex;
      }
      parent.remove(oldIndex); 
      parent.insert(child, newIndex);
    }

    int[] indices = new int[parent.getChildCount()];
    for (int i=0; i < indices.length; i++) {
      indices[i] = i;
    }
    
    Object[] children = new Object[parent.getChildCount()];
    for (int i=0; i < children.length; i++) {
      children[i] = parent.getChildAt(i);
    }
    
    TreeModelEvent event = new TreeModelEvent(this, path.getParentPath(), indices, children);
    for (TreeModelListener listener : listeners) {
      listener.treeNodesChanged(event);
      //listener.treeStructureChanged(event);
    }
  }
Ich ändere das UserObject und wenn die beiden Positionen nicht übereinstimmten, wird der Knoten aus der Rheinfolge gelöscht und wieder hinzugefügt. Danach erstelle ich zwei Arrays für die Positionen und Objekte die geändert wurden. Um es einfach zu machen füge ich jedes Kind ein.

Das Model ist richtig, aber die Anzeige nicht. Manchmal muss ich auf einen Knoten klicken, damit er aktualisiert wird und das richtige UserObject angezeigt wird. Das kann ich mir eigentlich nicht erklären, da doch jedens Objekt in den Arrays aktualisiert werden soll, oder nicht?:bahnhof:
Wenn ich neben treeNodesChanged() auch noch treeStructureChanged() (auskommentierte Zeile) aufrufe, dann simmt es, aber die Tree kollabiert dann teilweise, was ich auch nicht haben will.

Hat jemand eine Idee? Oder habe ich wieder einen grundsätzlichen Denkfehler?
 

Ebenius

Top Contributor
Das Model ist richtig, aber die Anzeige nicht.
Diese Aussage ist wahrscheinlich falsch. Das Modell setzt die falschen Events ab, deswegen aktualisiert sich der JTree nicht dort wo man das möchte. Ergo ist eigentlich das Modell falsch implementiert.

Wenn ich neben treeNodesChanged() auch noch treeStructureChanged() (auskommentierte Zeile) aufrufe, dann simmt es, aber die Tree kollabiert dann teilweise, was ich auch nicht haben will.
treeStructureChanged() ist sehr schwergewichtig. Danach liest der JTree das gesamte Modell neu ein. Dann stimmt natürlich alles wieder. Aber das will man so wirklich nicht. Was Du machen musst sieht so aus (PseudoCode):
Java:
public void valueForPathChanged(TreePath path, Object newValue) {
  if (sortierungÄndertSichNicht) {
    // Hier neuen Wert im Modell abspeichern
    fireTreeNodesChanged(this, path.getParentPath().getPath(), new int[] { indexDesKnotenImElternknoten }, new Object[] { newValue });
  } else {
    // Hier Knoten entfernen
    fireTreeNodesRemoved(this, path.getParentPath().getPath(), new int[] { indexDesEhemaligenKnotenImElternknoten }, new Object[] { oldValue });
    // Hier neuen Knoten an geänderter Position wieder eintragen
    fireTreeNodesInserted(this, path.getParentPath().getPath(), new int[] { indexDesNeuenKnotenImElternknoten }, new Object[] { newValue });
  }
}
Ebenius
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G JTree -- Node nach ändern in anderen Knoten AWT, Swing, JavaFX & SWT 15
richis-fragen JTree +/- verschwidet wenn Knoten keine Kinder hat... AWT, Swing, JavaFX & SWT 6
E Swing Copy und Paste eines einzelnen Knoten aus einem JTree AWT, Swing, JavaFX & SWT 1
N Swing JTree Problem beim erstellen der Knoten AWT, Swing, JavaFX & SWT 0
T JTree, Knoten mehrmals verwenden AWT, Swing, JavaFX & SWT 5
M JTree mit eigenen Knoten - Zugriff auf Daten AWT, Swing, JavaFX & SWT 6
C Knoten anzeigenb eim DnD in einem JTree AWT, Swing, JavaFX & SWT 4
H JTree - nach Auswahl aus JFileChooser wird nur der erste Knoten angezeigt AWT, Swing, JavaFX & SWT 3
S JTree - Knoten mit animiertem GIF/Icon AWT, Swing, JavaFX & SWT 5
algorismi Knoten im JTree deaktivieren AWT, Swing, JavaFX & SWT 4
B JTree - pro Knoten kann nur ein Blatt eingefügt werden AWT, Swing, JavaFX & SWT 5
G JTree Knoten ein / ausblenden AWT, Swing, JavaFX & SWT 3
P JTree Knoten schliessen AWT, Swing, JavaFX & SWT 16
S JTree rendern der Knoten [+] und [-], nicht der Node Icons AWT, Swing, JavaFX & SWT 2
G JTree: mehrere Knoten selektieren! AWT, Swing, JavaFX & SWT 2
S JTree, Knoten anhand eines Pfades öffnen? AWT, Swing, JavaFX & SWT 2
masta // thomas JTree - Knoten ausblenden. AWT, Swing, JavaFX & SWT 3
S Blätter oder Knoten im JTree ordnen AWT, Swing, JavaFX & SWT 3
D JTree - Knoten einfügen und automatisch in den Editiermodus AWT, Swing, JavaFX & SWT 2
L nur den JTree Knoten auf der Console ausgeben? AWT, Swing, JavaFX & SWT 6
W JTree, bei Drag Over über den Knoten "markieren" AWT, Swing, JavaFX & SWT 3
S JTree hinzugefügte Knoten anzeigen AWT, Swing, JavaFX & SWT 9
K Frage zu einem älteren Beitrag: JTree letzter Knoten auswähl AWT, Swing, JavaFX & SWT 2
G Knoten im Jtree mit unterscheidlichen Farben darstellen AWT, Swing, JavaFX & SWT 5
S Knoten im JTree hinzufügen/löschen mit eigenem Jtree AWT, Swing, JavaFX & SWT 8
R JTree: TreeCellRenderer und Selektion eines Knoten AWT, Swing, JavaFX & SWT 10
G JTree - einzelnen Knoten löschen AWT, Swing, JavaFX & SWT 11
M Freiraum zwischen Knoten im JTree AWT, Swing, JavaFX & SWT 14
B Sichtbare Knoten im aktuellen Viewport eines JTree AWT, Swing, JavaFX & SWT 4
P JTree Knoten Öffnen - PER Programm AWT, Swing, JavaFX & SWT 5
D Knoten in JTree ausblenden. AWT, Swing, JavaFX & SWT 12
M JTree - Wie kann man einen einzelnen Knoten deselektieren? AWT, Swing, JavaFX & SWT 3
T Knoten in Jtree anders darstellen AWT, Swing, JavaFX & SWT 2
P JTree: Alle Knoten geöffnet anzeigen AWT, Swing, JavaFX & SWT 2
M Einen Knoten im JTree zusammenklappen? AWT, Swing, JavaFX & SWT 6
M JTree: Wie einen Knoten editieren? AWT, Swing, JavaFX & SWT 5
X JTree: Selektion nach dem Entfernen von Knoten AWT, Swing, JavaFX & SWT 2
W JTree Knoten oder Blatt AWT, Swing, JavaFX & SWT 3
W JTree löschen & überprüfen von Knoten oder Blatt AWT, Swing, JavaFX & SWT 3
W JTree Knoten irgendwo hinzufügen AWT, Swing, JavaFX & SWT 2
FrittenFritze JTree, LazyLoading und "Rückwärtstraversion" AWT, Swing, JavaFX & SWT 3
J Falsches Rendern durch JCheckBox in eigenem JTree AWT, Swing, JavaFX & SWT 6
F jTree und das Model aus einer eigenen Klasse AWT, Swing, JavaFX & SWT 1
F Jtree aus Klasse mit Arraylisten AWT, Swing, JavaFX & SWT 1
A Swing JList zu JTree AWT, Swing, JavaFX & SWT 11
RalleYTN Modaler Dialog und JTree Node mit sehr... seeeeehr vielen Elementen AWT, Swing, JavaFX & SWT 6
Z Swing JTree DefaultMultipleTreeNode Repräsentation ändern AWT, Swing, JavaFX & SWT 1
Z Swing Drag&Drop zwischen JTable und JTree AWT, Swing, JavaFX & SWT 4
W Swing Anzeigefehler bei JTree AWT, Swing, JavaFX & SWT 1
S Zwei JTree, ein Model, bei Selection im ersten JTree soll der zweite die Inhlate anzeigen AWT, Swing, JavaFX & SWT 2
S JRadioButton und JCheckBox im JTree AWT, Swing, JavaFX & SWT 14
H Swing JTree: Zählt der rootNode mit? AWT, Swing, JavaFX & SWT 2
krgewb Swing JTree - Farbe von nodes ändern AWT, Swing, JavaFX & SWT 4
R JTree behandeln AWT, Swing, JavaFX & SWT 2
U dynamisches JTree erstellen AWT, Swing, JavaFX & SWT 2
J JTree updaten AWT, Swing, JavaFX & SWT 2
H JTree in JScrollPane passt sich nicht an Größe von JPanel an AWT, Swing, JavaFX & SWT 2
T Swing API Frage zu Verzeichnisbäumen und JTree AWT, Swing, JavaFX & SWT 1
T JTree mit Symbolen? AWT, Swing, JavaFX & SWT 8
R Anfängerfrage: Ansichten des JTree AWT, Swing, JavaFX & SWT 1
H Swing JTree Minimumgröße AWT, Swing, JavaFX & SWT 2
F Swing JTree + DiffUtils // Markierung Nodes aufheben AWT, Swing, JavaFX & SWT 2
I JTree wird nicht angezeigt AWT, Swing, JavaFX & SWT 3
M Swing JTree AWT, Swing, JavaFX & SWT 4
M Nodes in JTree nicht anzeigen AWT, Swing, JavaFX & SWT 0
T JTree mit Cloud verbinden AWT, Swing, JavaFX & SWT 0
H JTree Probleme AWT, Swing, JavaFX & SWT 9
F Swing Drag and Drop in JTree aus verschiedenen Listen AWT, Swing, JavaFX & SWT 6
M JButton wird von JTree überdeckt AWT, Swing, JavaFX & SWT 4
J Auf Dateien in JTree zugreifen AWT, Swing, JavaFX & SWT 15
F jTree.startEditingAtPath(path); funktioniert nicht bei eigenem CellEditor? AWT, Swing, JavaFX & SWT 8
D Swing JTree Steuerung AWT, Swing, JavaFX & SWT 11
S Swing JTree verwirrt mich AWT, Swing, JavaFX & SWT 2
T JTree - Elemente mit Doppelklick auswählen AWT, Swing, JavaFX & SWT 6
J JTree speichern AWT, Swing, JavaFX & SWT 4
N Swing JTree TreeCellRenderer mit html und automatischen Zeilenumbruch AWT, Swing, JavaFX & SWT 8
O Swing JTree um Label (oder Panel) erweitern AWT, Swing, JavaFX & SWT 9
B JTree mit Ordneransicht in JPanel einbinden AWT, Swing, JavaFX & SWT 4
D JTree node reagiert bei Klick nicht immer AWT, Swing, JavaFX & SWT 2
M Swing JTree: Wie kann ich die Hintergrundfarbe der selection ändern?!?! AWT, Swing, JavaFX & SWT 7
D Mehrmals auf Node im JTree klicken AWT, Swing, JavaFX & SWT 2
D JSplitPane, Jtree, CardLayout (constraint must be a string) AWT, Swing, JavaFX & SWT 9
N Swing FileFilter lässt JTree sich nicht öffnen AWT, Swing, JavaFX & SWT 2
X Swing 2 TreeModel und ein JTree synchronisieren AWT, Swing, JavaFX & SWT 3
N Swing JTree TreePath zu Windows Pfad? AWT, Swing, JavaFX & SWT 2
RELAXccc Swing JTree + JScrollPane, refresh Problem AWT, Swing, JavaFX & SWT 17
X Swing JTree aktualisieren AWT, Swing, JavaFX & SWT 2
V Swing JTree - Umbenennen selbst handlen. AWT, Swing, JavaFX & SWT 2
E Übergebenem JTree Blätter hinzufügen AWT, Swing, JavaFX & SWT 2
E Wert eines selektierten Knotens in einem JTree auslesen AWT, Swing, JavaFX & SWT 3
A Swing JTree - Nodes expanden AWT, Swing, JavaFX & SWT 2
D JTree nach Klick auf einen Hyperlink aktualisieren AWT, Swing, JavaFX & SWT 3
B JTree AWT, Swing, JavaFX & SWT 9
T Menüacceleratoren verschwinden bei JTree AWT, Swing, JavaFX & SWT 5
1 Swing JTree collapse child nodes AWT, Swing, JavaFX & SWT 4
B JTree - sehr individuell AWT, Swing, JavaFX & SWT 3
G Swing JTree - Verbindungslinien entfernen AWT, Swing, JavaFX & SWT 4
A Swing Herausfinden ob bei JTree Klick auf "+"/"-" anahnd x,y AWT, Swing, JavaFX & SWT 2
S Swing JTree und seine Listener... AWT, Swing, JavaFX & SWT 4
L Swing JTree wird nicht selektiert AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben