Ein eigenes TreeModel schreiben

Aus Byte-Welt Wiki
Version vom 31. Januar 2022, 19:17 Uhr von L-ectron-X (Diskussion | Beiträge) (TreeModelListener verwalten)
Zur Navigation springenZur Suche springen

TreeModels enthalten die Daten, die ein JTree darstellen soll. In diesem Artikel werden wir uns damit befassen, wie man Schritt für Schritt ein eigenes dynamisches TreeModel aufbaut. Nach der Lektüre dieses Artikels sollte der Leser in der Lage sein, selbstständig eigene TreeModels zu entwickeln.

Überblick

Damit der JTree das darzustellende Datenformat verstehen kann, muss dieses einem entsprechenden Standard genügen. Den kleinsten gemeinsamen Nenner bildet hier das TreeModel.

Im Gegensatz zu JTable existiert für den JTree keine abstrakte Standardimplementierung seines Datenmodells. JTable bietet hier die Klasse AbstractTableModel welche das Interface TableModel implementiert an. Diese Klasse enthält bereits eine einfache Verarbeitung von TableModelEvents, reagiert also auf Veränderungen im TableModel. AbstractTableModel wird schließlich von DefaultTableModel beerbt, mit dem Tabellen mit Standard-Datentypen wie bspw. Integer, Double, Float, Boolean, String, Icon erzeugt werden können.

Mehr zu all dem im großen JTable (Tutorial)©.

Eine vergleichbare Klasse AbstractTreeModel gibt es in der Java-API nicht. Für eigene baumartig strukturierte Datentypen muss hier ein eigenes TreeModel geschrieben werden. Mit DefaultTreeModel gibt es schon eine Standardimplementierung eines TreeModels. Die Daten des Baums werden mit Hilfe von Objekten, die das Interface TreeNode implementieren, dargestellt. Veränderbare Daten erfordern den Einsatz von MutableTreeNode. Eine Standardimplementierung wird bereits mit DefaultMutableTreeNode von der Java-API mitgeliefert.

Mehr dazu im großen JTree (Tutorial)©.

Das Interface TreeModel

Das Interface TreeModel schreibt Methoden vor, die eine Klasse implementieren muss, wenn ein JTree die in ihr enthaltenen Daten grafisch darstellen können soll.

public interface TreeModel {
   void addTreeModelListener(TreeModelListener l);

   Object getChild(Object parent, int index);

   int getChildCount(Object parent);

   int 	getIndexOfChild(Object parent, Object child);

   Object getRoot();

   boolean isLeaf(Object node);

   void	removeTreeModelListener(TreeModelListener l);

   void valueForPathChanged(TreePath path, Object newValue);
}

Dynamisches TreeModel implementieren

Nehmen wir an, wir hätten bereits eine eigene Datenstruktur, die die Produktion von Fahrrädern speichert und die wir im JTree präsentieren und zur Laufzeit auch verändern wollen.

Um ein eigenes TreeModel zun implementieren, müssen wir nun also erstmal das TreeModel-Interface implementieren und damit alle von ihm vorgeschriebenen Methoden überschreiben:

public BicycleTreeModel implements TreeModel {

   public Object getChild(Object parent, int index) {

   }

   public int getChildCount(Object parent) {

   }

   public int getIndexOfChild(Object parent, Object child) {

   }

   public Object getRoot() {

   }

   public boolean isLeaf(Object node) {

   }

   public void removeTreeModelListener(TreeModelListener l) {

   }

   public void addTreeModelListener(TreeModelListener l) {

   }

   public void valueForPathChanged(TreePath path, Object newValue) {

   }
}

TreeModelListener verwalten

Komponenten wie der JTree interessieren sich für das Geschehen in einem TreeModel und lauschen auf Ereignisse, die sich durch Benutzeraktionen ergeben. Das kann z. B. das Hinzufügen, Ändern oder Löschen von Datenelementen im TreeModel sein.

Damit ein Ereignis-Interessent (TreeModelListener) die Benachrichtigungen über TreeModelEvents abonieren kann, muss er sich als Abonent registrieren.

Mit der Klasse EventListenerList gibt es in Java bereits eine fertige Ereignis-Lauscher-Liste, die für alle möglichen [...]ModelListener-Typen eingesetzt werden kann.
Im Folgenden kümmern wir uns also darum, dass wir diese EventListenerList in unser TreeModel einbauen und auch die Möglichkeit schaffen, dass sich Interessenten für die Benachrichtigung über TreeModelEvents an unserem "Abo-Dienst" anmelden und auch von ihm wieder abmelden können.

Zeit, um den bereits implementierten Methoden addTreeModelListener(TreeModelListener l) und removeTreeModelListener(TreeModelListener l) sinnvollen Code zu geben!

public BicycleTreeModel implements TreeModel {

   private EventListenerList listeners = new EventListenerList();

   [...]

   public void addTreeModelListener(TreeModelListener l) {
      listeners.remove(TreeModelListener.class, listener);
   }

   public void removeTreeModelListener(TreeModelListener l) {
      listeners.add(TreeModelListener.class, listener);
   }


   [...]
}

Ein Konstruktor für unser TreeModel

Baustelle.png Dieser Beitrag wird derzeit noch bearbeitet. Der Text ist deshalb unvollständig und kann Fehler oder ungeprüfte Aussagen enthalten.