From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../hjp5/html/k100246.html | 990 +++++++++++++++++++++ 1 file changed, 990 insertions(+) create mode 100644 Master/Reference Architectures and Patterns/hjp5/html/k100246.html (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100246.html') diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100246.html b/Master/Reference Architectures and Patterns/hjp5/html/k100246.html new file mode 100644 index 0000000..8f12f82 --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100246.html @@ -0,0 +1,990 @@ + + + +Handbuch der Java-Programmierung, 5. Auflage + + + + + + + + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage +
 <<  +  <   +  >   + >>  + API  +Kapitel 38 - Swing: Komponenten II +
+
+ + + + +

38.3 JTree

+
+ +
+ + + + +

38.3.1 Erzeugen eines Baums

+ +

+Nach JTable +ist JTree +die zweite der »großen« Elementarkomponenten in Swing. +Sie dient zur Darstellung, Navigation und Bearbeitung baumartiger, +hierarchischer Datenstrukturen. + +

+Ein einfaches Beispiel für derartige Baumstrukturen stellt etwa +das Dateisystem unter UNIX oder Windows dar. Es besteht aus einer +Wurzel (dem Root-Verzeichnis) und darin enthaltenen Unterverzeichnissen. +Die Unterverzeichnisse können ihrerseits weitere Unterverzeichnisse +enthalten usw. Dadurch entsteht eine beliebig tief geschachtelte Struktur +von Verzeichnissen, die baumartig durchlaufen und bearbeitet werden +kann. Andere Beispiele für Baumstrukturen sind die syntaktischen +Elemente einer Programmiersprache, die Aufbauorganisation eines Unternehmens +oder das Inhaltsverzeichnis in einem Buch. + +

+Im Umgang mit Bäumen haben sich folgende Begriffe eingebürgert: +

+ +

+Der eigentliche Aufwand beim Erzeugen eines Baums liegt im Aufbau +eines passenden Datenmodells, das seiner Struktur nach meist ebenfalls +hierarchisch ist. Das Instanzieren des JTree +ist dann vergleichsweise einfach. Die beiden wichtigsten Konstruktoren +der Klasse JTree +sind: +

+ + + + + +
+ +
+public JTree(TreeModel newModel)
+public JTree(TreeNode root)
+
+
+
+javax.swing.JTree
+ +

+Der erste von beiden erwartet ein vordefiniertes TreeModel +zur Darstellung der Elemente des Baums. Ein TreeModel +kapselt alle relevanten Informationen über die Struktur des Baums. +Es liefert auf Anfrage dessen Wurzel, stellt Informationen über +einen bestimmten Knoten zur Verfügung oder liefert dessen Unterknoten. + +

+An den zweiten Konstruktor wird lediglich die Wurzel des Baums übergeben. +Sie wird vom Konstruktor automatisch in ein geeignetes TreeModel +eingebettet. Beide Varianten sind prinzipiell gleichwertig. Zwar erfragt +der JTree +die zur Darstellung und Navigation erforderlichen Daten immer beim +TreeModel. +Aber das mit der Baumwurzel des zweiten Konstruktors instanzierte +DefaultTreeModel +ist in der Lage, diese Informationen aus den Knoten und den darin +gespeicherten Verweisen auf ihre Unterknoten zu entnehmen (alle nötigen +Informationen werden in den TreeNodes +selbst gehalten). Wir werden später auf beide Arten, Bäume +zu konstruieren, noch genauer eingehen. + +

+Ein JTree +besitzt nicht so viele Konfigurationsoptionen wie eine JTable. +Die wichtigste von ihnen regelt, ob die Wurzel des Baums bei seiner +Darstellung angezeigt oder unterdrückt werden soll. Auf sie kann +mit den Methoden setRootVisible +und isRootVisible +zugegriffen werden: +

+ + + + + +
+ +
+public void setRootVisible(boolean rootVisible)
+public boolean isRootVisible()
+
+
+
+javax.swing.JTree
+ +

+Wir wollen uns zunächst ein einfaches Beispiel ansehen. Das folgende +Programm erzeugt eine rekursive Baumstruktur mit Wurzel und zwei Unterebenen, +deren Knoten aus Objekten des Typs DefaultMutableTreeNode +bestehen. Diese im Paket javax.swing.tree +gelegene Klasse ist eine Standardimplementierung des TreeNode-Interfaces, +das beschreibt, wie ein Knoten Informationen über seine Unter- +und Vaterknoten zur Verfügung stellen kann. Die vier wichtigsten +Methoden von TreeNode +sind: +

+ + + + + +
+ +
+public int getChildCount()
+public TreeNode getChildAt(int childIndex)
+
+public TreeNode getParent()
+
+public boolean isLeaf()
+
+
+
+javax.swing.tree.TreeNode
+ +

+Mit getChildCount +kann die Anzahl der Unterknoten ermittelt werden. Sie werden von 0 +an durchnummeriert, getChildAt +liefert einen beliebigen Unterknoten. Ein Knoten kennt seinen Vaterknoten, +der mit getParent +ermittelt werden kann. Mit isLeaf +kann zudem abgefragt werden, ob ein Knoten ein Blatt ist oder weitere +Unterknoten enthält. Zur Beschriftung des Knotens bei der visuellen +Darstellung verwendet ein JTree +die Methode toString +der Knotenklasse. + +

+Mit DefaultMutableTreeNode +steht eine recht flexible Implementierung von TreeNode +zur Verfügung, die auch Methoden zum Einfügen und Löschen +von Knoten bietet (sie implementiert übrigens das aus TreeNode +abgeleitete Interface MutableTreeNode): +

+ + + + + +
+ +
+public DefaultMutableTreeNode(Object userObject)
+
+public void add(MutableTreeNode newChild)
+public void insert(MutableTreeNode newChild, int childIndex)
+public void remove(int childIndex)
+public void removeAllChildren()
+
+public void setUserObject(Object userObject)
+public Object getUserObject()
+
+
+
+javax.swing.tree.DefaultMutableTreeNode
+ +

+Mit add +wird ein neuer Kindknoten an das Ende der Liste der Unterknoten angefügt, +mit insert +kann dies an einer beliebigen Stelle erfolgen. remove +entfernt einen beliebigen und removeAllChildren +alle Kindknoten. Anwendungsbezogene Informationen werden in einem +UserObject gehalten, das direkt an den Konstruktor übergeben +werden kann. Mit setUserObject +und getUserObject +kann auch nach der Konstruktion noch darauf zugegriffen werden. Das +UserObject ist auch der Lieferant für die Knotenbeschriftung: +jeder Aufruf von toString +wird an das UserObject weitergeleitet. +

+ + + + + + + + + + + +
+ +

+DefaultMutableTreeNode +stellt noch weitaus mehr als die hier beschriebenen Methoden zur Verfügung. +Die Klasse ist sehr vielseitig und kann auch unabhängig von der +Verwendung in einem JTree +zum Aufbau und zur Verarbeitung baumartiger Datenstrukturen verwendet +werden.

+ + + + +
 Tipp 
+
+ +

+Das folgende Programm erzeugt eine Wurzel mit fünf Unterknoten, +die jeweils drei weitere Unterknoten enthalten. Anschließend +wird der Wurzelknoten an den Konstruktor eines JTree +übergeben und dieser durch Einbetten in eine JScrollPane +(um automatisches Scrollen zu ermöglichen) in einem JFrame +platziert. + + +

+ + + + + +
+ +
+001 /* Listing3811.java */
+002 
+003 import java.awt.*;
+004 import java.awt.event.*;
+005 import javax.swing.*;
+006 import javax.swing.tree.*;
+007 
+008 public class Listing3811
+009 extends JFrame
+010 {
+011   public Listing3811()
+012   {
+013     super("JTree 1");
+014     addWindowListener(new WindowClosingAdapter(true));
+015     //Einfaches TreeModel bauen
+016     DefaultMutableTreeNode root, child, subchild;
+017     root = new DefaultMutableTreeNode("Root");
+018     for (int i = 1; i <= 5; ++i) {
+019       String name = "Child-" + i;
+020       child = new DefaultMutableTreeNode(name);
+021       root.add(child);
+022       for (int j = 1; j <= 3; ++j) {
+023         subchild = new DefaultMutableTreeNode(name + "-" + j);
+024         child.add(subchild);
+025       }
+026     }
+027     //JTree erzeugen
+028     JTree tree = new JTree(root);
+029     tree.setRootVisible(true);
+030     //JTree einfügen
+031     Container cp = getContentPane();
+032     cp.add(new JScrollPane(tree), BorderLayout.CENTER);
+033   }
+034 
+035   public static void main(String[] args)
+036   {
+037     Listing3811 frame = new Listing3811();
+038     frame.setLocation(100, 100);
+039     frame.setSize(250, 200);
+040     frame.setVisible(true);
+041   }
+042 }
+
+
+Listing3811.java
+ +Listing 38.11: Ein einfacher JTree

+ +

+Mit aufgeklapptem zweiten und vierten Knoten sieht das Programm wie +in Abbildung 38.9 dargestellt +aus. Auf der linken Seite wird der Baum im Metal-, auf der rechten +im Windows-Look-and-Feel gezeigt. +

+ + +

+ +

+Abbildung 38.9: Ein einfacher JTree im Metal- und Windows-Look-and-Feel

+ + + + +

38.3.2 Selektieren von Knoten

+ + + + +

Konfiguration der Selektionsmöglichkeit

+ +

+Das Selektieren von Knoten wird durch das TreeSelectionModel +gesteuert, auf das mit Hilfe der Methoden setSelectionModel +und getSelectionModel +zugegriffen werden kann: +

+ + + + + +
+ +
+public void setSelectionModel(TreeSelectionModel selectionModel)
+public TreeSelectionModel getSelectionModel()
+
+
+
+javax.swing.JTree
+ +

+Standardmäßig erlaubt ein JTree +das Selektieren mehrerer Knoten. Soll die Selektionsmöglichkeit +auf einen einzelnen Knoten beschränkt werden, muss ein eigenes +TreeSelectionModel +an setSelectionModel +übergeben werden. Dazu kann eine Instanz der Klasse DefaultTreeSelectionModel +erzeugt und durch Aufruf von setSelectionMode +und Übergabe einer der Konstanten SINGLE_TREE_SELECTION, +CONTIGUOUS_TREE_SELECTION +oder DISCONTIGUOUS_TREE_SELECTION +konfiguriert werden: +

+ + + + + +
+ +
+public void setSelectionMode(int mode)
+
+
+
+javax.swing.tree.DefaultTreeSelectionModel
+ + + + +

Abfragen der Selektion

+ +

+JTree +stellt eine Reihe von Methoden zur Verfügung, mit denen abgefragt +werden kann, ob und welche Knoten selektiert sind. Die wichtigsten +von ihnen sind: +

+ + + + + +
+ +
+public TreePath getSelectionPath()
+public TreePath[] getSelectionPaths()
+
+public TreePath getLeadSelectionPath()
+
+
+
+javax.swing.JTree
+ +

+Mit getSelectionPath +wird das selektierte Element ermittelt. Bei aktivierter Mehrfachselektion +liefert die Methode das erste aller selektierten Elemente. Ist kein +Knoten selektiert, wird null +zurückgegeben. getSelectionPaths +gibt ein Array mit allen selektierten Knoten zurück. getLeadSelectionPath +liefert das markierte Element. + +

+Alle beschriebenen Methoden liefern Objekte des Typs TreePath. +Diese Klasse beschreibt einen Knoten im Baum über den Pfad, der +von der Wurzel aus beschritten werden muss, um zu dem Knoten zu gelangen. +Mit getLastPathComponent +kann das letzte Element dieses Pfads bestimmt werden. In unserem Fall +ist das gerade der selektierte Knoten. Mit getPath +kann der komplette Pfad ermittelt werden. An erster Stelle liegt dabei +die Wurzel des Baums, an letzter Stelle das selektierte Element: +

+ + + + + +
+ +
+public Object getLastPathComponent()
+public Object[] getPath()
+
+
+
+javax.swing.tree.TreePath
+ +

+Soll ermittelt werden, ob und welche Elemente im Baum selektiert sind, +können die Methoden isSelectionEmpty +und isPathSelected +aufgerufen werden: +

+ + + + + +
+ +
+public boolean isSelectionEmpty()
+public boolean isPathSelected(TreePath path)
+
+
+
+javax.swing.JTree
+

+ + + + + + + + + +
+ +

+Alternativ zum TreePath +kann auf die selektierten Elemente auch mit Hilfe ihrer internen Zeilennummer +zugriffen werden. Dazu besitzt jedes angezeigte Element im +Baum eine fortlaufende Nummer, die mit 0 bei der Wurzel beginnt und +sich dann zeilenweise bis zum letzten Element fortsetzt. Die zugehörigen +Methoden heißen getSelectionRows +und getLeadSelectionRow. +Abhängig davon, wie viele Knoten oberhalb eines bestimmten Knotens +sichtbar oder verdeckt sind, kann sich die Zeilennummer während +der Lebensdauer des Baums durchaus verändern, und es gibt Methoden, +um zwischen Knotenpfaden und Zeilennummern zu konvertieren. Wir wollen +auf dieses Konzept nicht weiter eingehen.

+ + + + +
 Hinweis 
+
+ +

+Dient der JTree +zur Steuerung anderer Komponenten (etwa in explorerartigen Oberflächen), +muss das Programm meist unmittelbar auf Änderungen der Selektion +durch den Anwender reagieren. Dazu kann es einen TreeSelectionListener +instanzieren und ihn mit addTreeSelectionListener +beim JTree +registrieren. Bei jeder Selektionsänderung wird dann die Methode +valueChanged +aufgerufen und bekommt ein TreeSelectionEvent +als Argument übergeben: +

+ + + + + +
+ +
+public void valueChanged(TreeSelectionEvent event)
+
+
+
+javax.swing.event.TreeSelectionListener
+ +

+Dieses stellt unter anderem die Methoden getOldLeadSelectionPath +und getNewLeadSelectionPath +zur Verfügung, um auf den vorherigen oder aktuellen Selektionspfad +zuzugreifen: +

+ + + + + +
+ +
+public TreePath getOldLeadSelectionPath()
+public TreePath getNewLeadSelectionPath()
+
+
+
+javax.swing.event.TreeSelectionEvent
+ +

+Das folgende Programm erweitert Listing 38.11 +um die Fähigkeit, das selektierte Element auf der Konsole auszugeben. +Dazu definiert es ein TreeSelectionModel +für Einfachselektion und fügt einen TreeSelectionListener +hinzu, der jede Selektionsänderung dokumentiert: + + +

+ + + + + +
+ +
+001 /* Listing3812.java */
+002 
+003 import java.awt.*;
+004 import java.awt.event.*;
+005 import javax.swing.*;
+006 import javax.swing.event.*;
+007 import javax.swing.tree.*;
+008 
+009 public class Listing3812
+010 extends JFrame
+011 {
+012   public Listing3812()
+013   {
+014     super("JTree 2");
+015     addWindowListener(new WindowClosingAdapter(true));
+016     //Einfaches TreeModel bauen
+017     DefaultMutableTreeNode root, child, subchild;
+018     root = new DefaultMutableTreeNode("Root");
+019     for (int i = 1; i <= 5; ++i) {
+020       String name = "Child-" + i;
+021       child = new DefaultMutableTreeNode(name);
+022       root.add(child);
+023       for (int j = 1; j <= 3; ++j) {
+024         subchild = new DefaultMutableTreeNode(name + "-" + j);
+025         child.add(subchild);
+026       }
+027     }
+028     //JTree erzeugen und Einfachselektion aktivieren
+029     JTree tree = new JTree(root);
+030     TreeSelectionModel tsm = new DefaultTreeSelectionModel();
+031     tsm.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+032     tree.setSelectionModel(tsm);
+033     tree.setRootVisible(true);
+034     //JTree einfügen
+035     Container cp = getContentPane();
+036     cp.add(new JScrollPane(tree), BorderLayout.CENTER);
+037     //TreeSelectionListener hinzufügen
+038     tree.addTreeSelectionListener(
+039       new TreeSelectionListener()
+040       {
+041         public void valueChanged(TreeSelectionEvent event)
+042         {
+043           TreePath tp = event.getNewLeadSelectionPath();
+044           if (tp != null) {
+045             System.out.println("  Selektiert: " + tp.toString());
+046           } else {
+047             System.out.println("  Kein Element selektiert");
+048           }
+049         }
+050       }
+051     );
+052   }
+053 
+054   public static void main(String[] args)
+055   {
+056     try {
+057       Listing3812 frame = new Listing3812();
+058       frame.setLocation(100, 100);
+059       frame.setSize(250, 200);
+060       frame.setVisible(true);
+061     } catch (Exception e) {
+062     }
+063   }
+064 }
+
+
+Listing3812.java
+ +Listing 38.12: Ein JTree mit TreeSelectionListener

+ + + + +

Verändern der Selektion

+ +

+Die Selektion kann auch programmgesteuert verändert werden: +

+ + + + + +
+ +
+public void clearSelection()
+
+public void addSelectionPath(TreePath path)
+public void addSelectionPaths(TreePath[] paths)
+
+public void setSelectionPath(TreePath path)
+public void setSelectionPaths(TreePath[] paths)
+
+
+
+javax.swing.JTree
+ +

+Mit clearSelection +wird die Selektion vollständig gelöscht. Mit addSelectionPath +und addSelectionPaths +kann die Selektion um ein einzelnes oder eine Menge von Knoten erweitert +werden. Mit setSelectionPath +und setSelectionPaths +werden - unabhängig von der bisherigen Selektion - die als Argument +übergebenen Knoten selektiert. + + + + +

38.3.3 Öffnen und Schließen der Knoten

+ +

+Der Anwender kann die Knoten mit Maus- oder Tastaturkommandos öffnen +oder schließen. Dadurch werden die Unterknoten entweder sichtbar +oder versteckt. Das Programm kann diesen Zustand mit den Methoden +isCollapsed +und isExpanded +abfragen: +

+ + + + + +
+ +
+public boolean isExpanded(TreePath path)
+public boolean isCollapsed(TreePath path)
+
+public boolean hasBeenExpanded(TreePath path)
+
+public boolean isVisible(TreePath path)
+public void makeVisible(TreePath path)
+
+public void expandPath(TreePath path)
+public void collapsePath(TreePath path)
+
+
+
+javax.swing.JTree
+ +

+isExpanded +liefert true, +wenn der Knoten geöffnet ist, isCollapsed, +wenn er geschlossen ist. hasBeenExpanded +gibt an, ob der Knoten überhaupt schon einmal geöffnet wurde. +isVisible +gibt genau dann true +zurück, wenn der Knoten sichtbar ist, d.h. wenn alle seine Elternknoten +geöffnet sind. Mit makeVisible +kann ein Knoten sichtbar gemacht werden. Mit expandPath +kann er geöffnet und mit collapsePath +geschlossen werden. + + + + +

38.3.4 Verändern der Baumstruktur

+ +

+Es ist ohne weiteres möglich, den Inhalt und die Struktur des +Baums nach dem Anlegen des JTree +zu ändern. Es können neue Knoten eingefügt, bestehende +entfernt oder vorhandene modifiziert werden. Wird die Klasse DefaultMutableTreeNode +als Knotenklasse verwendet, reicht es allerdings nicht aus, einfach +die entsprechenden Methoden zum Ändern, Einfügen oder Löschen +auf den betroffenen Knoten aufzurufen. In diesem Fall würde zwar +die Änderung im Datenmodell durchgeführt werden, aber die +Bildschirmdarstellung würde sich nicht verändern. + +

+Änderungen im Baum müssen immer über das Modell ausgeführt +werden, denn nur dort ist der JTree +standardmäßig als TreeModelListener +registriert und wird über Änderungen unterrichtet. Werden +diese dagegen direkt auf den Knoten ausgeführt, bleiben sie dem +Modell verborgen und die Anzeige wird inkonsistent. + +

+Für einfache Änderungen reicht es aus, eine Instanz der +Klasse DefaultTreeModel +als TreeModel +zu verwenden. Sie wird durch Übergabe des Wurzelknotens instanziert +und stellt eine Vielzahl von Methoden zum Einfügen, Löschen +und Ändern der Knoten zur Verfügung. Alle Änderungen +werden durch Versenden eines TreeModelEvent +automatisch an alle registrierten TreeModelListener +weitergegeben und führen dort zu entsprechenden Aktualisierungen +der Bildschirmdarstellung. + +

+Die zum Ändern des Modells benötigten Methoden von DefaultTreeModel +sind: +

+ + + + + +
+ +
+public void insertNodeInto(
+  MutableTreeNode newChild,
+  MutableTreeNode parent,
+  int index
+)
+
+public void removeNodeFromParent(MutableTreeNode node)
+
+public void nodeChanged(TreeNode node)
+
+public TreeNode[] getPathToRoot(TreeNode aNode)
+
+
+
+javax.swing.tree.DefaultTreeModel
+ +

+Mit insertNodeInto +wird ein neuer Kindknoten an einer beliebigen Position zu einem Elternknoten +hinzugefügt. Mit removeNodeFromParent +wird ein beliebiger Knoten aus dem Baum entfernt (er darf auch Unterknoten +enthalten), und nodeChanged +sollte aufgerufen werden, wenn der Inhalt eines Knotens sich so geändert +hat, dass seine Bildschirmdarstellung erneuert werden muss. getPathToRoot +schließlich ist eine nützliche Hilfsmethode, mit der das +zur Konstruktion eines TreePath-Objekts +erforderliche Knoten-Array auf einfache Weise erstellt werden kann. + +

+Das folgende Programm zeigt einen Baum, der zunächst nur den +Wurzelknoten enthält. Dieser ist vom Typ DefaultMutableTreeNode +und wird in ein explizit erzeugtes DefaultTreeModel +eingebettet, dass an den Konstruktor des JTree +übergeben wird. Neben dem JTree +enthält das Programm drei Buttons, mit denen ein neuer Knoten +eingefügt sowie ein vorhandener gelöscht oder seine Beschriftung +geändert werden kann. + + +

+ + + + + +
+ +
+001 /* Listing3813.java */
+002 
+003 import java.awt.*;
+004 import java.awt.event.*;
+005 import javax.swing.*;
+006 import javax.swing.event.*;
+007 import javax.swing.tree.*;
+008 
+009 public class Listing3813
+010 extends JFrame
+011 implements ActionListener
+012 {
+013   protected DefaultMutableTreeNode root;
+014   protected DefaultTreeModel       treeModel;
+015   protected JTree                  tree;
+016 
+017   public Listing3813()
+018   {
+019     super("JTree 3");
+020     addWindowListener(new WindowClosingAdapter(true));
+021     //JTree erzeugen und Einfachselektion aktivieren
+022     root = new DefaultMutableTreeNode("Root");
+023     treeModel = new DefaultTreeModel(root);
+024     tree = new JTree(treeModel);
+025     TreeSelectionModel tsm = new DefaultTreeSelectionModel();
+026     tsm.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+027     tree.setSelectionModel(tsm);
+028     tree.setRootVisible(true);
+029     //JTree einfügen
+030     Container cp = getContentPane();
+031     cp.add(new JScrollPane(tree), BorderLayout.CENTER);
+032     //ButtonPanel
+033     JPanel panel = new JPanel(new FlowLayout());
+034     String[] buttons = new String[]{"AddChild", "Delete", "Change"};
+035     for (int i = 0; i < buttons.length; ++i) {
+036       JButton button = new JButton(buttons[i]);
+037       button.addActionListener(this);
+038       panel.add(button);
+039     }
+040     cp.add(panel, BorderLayout.SOUTH);
+041   }
+042 
+043   public void actionPerformed(ActionEvent event)
+044   {
+045     String cmd = event.getActionCommand();
+046     TreePath tp = tree.getLeadSelectionPath(); 
+047     if (tp != null) {
+048       DefaultMutableTreeNode node;
+049       node = (DefaultMutableTreeNode)tp.getLastPathComponent();
+050       if (cmd.equals("AddChild")) {
+051         DefaultMutableTreeNode child;
+052         child = new DefaultMutableTreeNode("child");
+053         treeModel.insertNodeInto(child, node, node.getChildCount()); 
+054         TreeNode[] path = treeModel.getPathToRoot(node);
+055         tree.expandPath(new TreePath(path));
+056       } else if (cmd.equals("Delete")) {
+057         if (node != root) {
+058           TreeNode parent = node.getParent();
+059           TreeNode[] path = treeModel.getPathToRoot(parent);
+060           treeModel.removeNodeFromParent(node); 
+061           tree.setSelectionPath(new TreePath(path));
+062         }
+063       } else if (cmd.equals("Change")) {
+064         String name = node.toString();
+065         node.setUserObject(name + "C");
+066         treeModel.nodeChanged(node); 
+067       }
+068     }
+069   }
+070 
+071   public static void main(String[] args)
+072   {
+073     try {
+074       String plaf = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
+075       UIManager.setLookAndFeel(plaf);
+076       Listing3813 frame = new Listing3813();
+077       frame.setLocation(100, 100);
+078       frame.setSize(300, 300);
+079       frame.setVisible(true);
+080     } catch (Exception e) {
+081     }
+082   }
+083 }
+
+
+Listing3813.java
+ +Listing 38.13: Einfügen, Ändern und Löschen in einem +Baum

+ +

+Alle Button-Aktionen werden in actionPerformed +ausgeführt. Darin wird zunächst das Action-Kommando abgefragt +und dann in Zeile 046 +der Pfad des selektierten Elements bestimmt. Ist dieser nicht leer, +werden die Kommandos wie folgt ausgeführt: +

+ +

+Nach einigen Einfügungen, Änderungen und Löschungen +sieht die Programmausgabe beispielsweise so aus: +

+ + +

+ +

+Abbildung 38.10: Ein veränderbarer JTree

+
+ + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 +
 <<  +  <   +  >   + >>  + API  +© 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de +
+ + + -- cgit v1.2.3