Wenn Sie UI -Programme mit Java Swing entwickeln, müssen Sie wahrscheinlich auf die Verwendung eines Baumes mit Kontrollkästchen stoßen. Java Swing bietet diese Komponente jedoch nicht. Wenn Sie diese Anforderung haben, müssen Sie einen Baum selbst mit Kontrollkästchen implementieren.
Es gibt Unterschiede zwischen CheckBoxTree und JTree auf zwei Ebenen:
1. Auf der Modellebene benötigt jeder Knoten von CheckBoxTree ein Mitglied, um zu speichern, ob es ausgewählt ist, aber JTree -Knoten nicht.
2. In der Ansichtsebene zeigt jeder Knoten von CheckBoxTree ein mehr Kontrollkästchen an als der Knoten von JTree.
Da es zwei Unterschiede gibt, solange wir diese beiden Unterschiede mit unserer eigenen Implementierung ausfüllen, wird der Baum mit Kontrollkästchen implementiert.
Fangen Sie nun an, den ersten Unterschied zu lösen. Um den ersten Unterschied zu lösen, muss ein neuer Knotenklassen -CheckBoxTeReenode definiert werden, der den DefaultMutabletreenode erbt und ein neues Mitglied ausgewählt wird, um anzugeben, ob der Knoten ausgewählt ist. Wenn ein CheckBoxTree ausgewählt ist, wird das Kontrollkästchen überprüft, wenn ein Knoten ausgewählt ist, und die Motivation für die Verwendung von CheckBoxTree besteht darin, einen Unterbaum gleichzeitig auszuwählen. Wenn dann ein Knoten ausgewählt oder abgebrochen wird, sollte sein Vorfahrknoten und der Nachkommenknoten einige Änderungen vornehmen. Hier wenden wir die folgenden rekursiven Regeln an:
1. Wenn ein Knoten manuell ausgewählt ist, sollten alle Nachkommen ausgewählt werden. Wenn der Knoten ausgewählt ist, um alle Kinder aus dem übergeordneten Knoten auszuwählen, wird sein übergeordneter Knoten ausgewählt.
2. Wenn ein Knoten manuell deaktiviert ist, sollten alle seine Nachkommen deaktiviert werden. Wenn der übergeordnete Knoten des Knotens ausgewählt ist, ist der übergeordnete Knoten nicht überprüft.
Hinweis: Die beiden oben genannten Regeln sind rekursive Regeln. Wenn sich ein Knoten ändert und einen anderen Knoten ändert, ändert sich auch ein anderer Knoten. In den beiden oben genannten Regeln führt die manuelle Auswahl oder die manuelle Deaktivierung eines Knotens zu einer nicht-manuellen Auswahl oder einer ungehinderten Auswahl anderer Knoten. Diese nicht-manuelle Auswahl oder Nichtauswahl dieser nicht-manuellen Auswahl oder Unverwaltung gilt nicht für die oben genannten Regeln.
Der Quellcode von CheckBoxTeenode, der gemäß den oben genannten Regeln implementiert ist, lautet wie folgt:
Paketdemo; importieren javax.swing.tree.defaultMutabletreenode; Public Class CheckBoxTeenode erweitert DefaultMutabletreenode {geschützte boolean identifizierte; public checkBoxTeenode () {this (null); } public checkBoxTeenode (Object UserObject, True, False); } public checkBoxTeenode (Object userObject, boolean erlaubt Children, boolean isselected) {super (userObject, erlauben Kinder); this. isSelected = isSelected; } public boolean isSelected () {return iselected; } public void setSelected (boolean _isSelected) {this. isSelected = _isSelected; if (_isSelected) {// if ausgewählt, wählen Sie alle untergeordneten Knoten aus, wenn (Kinder! if (_isSelected! }} // Überprüfen Sie, ob alle untergeordneten Knoten des übergeordneten Knotens ausgewählt sind, dann wählen Sie den übergeordneten Knoten CheckBoxTeenode pnode = (CheckBoxTeenode) übergeordnet; // Überprüfen Sie, ob alle untergeordneten Knoten des Pnode ausgewählt sind, wenn (pnode! = Null) {int index = 0; for (; index <pnode.children.size (); ++ Index) {CheckBoxTeenode pchildnode = (CheckBoxTeenode) pnode.children.get (index); if (! pChildnode.ISSelected ()) Break; } / * * Zeigt an, dass alle untergeordneten Knoten von Pnode ausgewählt wurden, der übergeordnete Knoten ausgewählt ist. * Diese Methode ist eine rekursive Methode, sodass hier nicht itereriert werden muss, da * Wenn der übergeordnete Knoten ausgewählt ist, wird der übergeordnete Knoten selbst nach oben geprüft. */ if (index == pnode.children.size ()) {if (pnode.isSelected ()! }}} else { / * * Wenn die Stornierung des übergeordneten Knotens dazu führt, dass der untergeordnete Knoten abgebrochen wird, sollten zu diesem Zeitpunkt alle untergeordneten Knoten ausgewählt werden; * Andernfalls führt die Stornierung des untergeordneten Knotens dazu zu, dass der übergeordnete Knoten storniert wird, und die Stornierung des übergeordneten Knotens wird dazu führen, dass der untergeordnete Knoten storniert wird, * ist jedoch nicht erforderlich, um den untergeordneten Knoten zu diesem Zeitpunkt zu stornieren. */ if (Kinder! = null) {int index = 0; for (; index <childhes.size (); ++ Index) {CheckBoxTeenode childnode = (CheckBoxTeenode) childhes.get (index); if (! Childnode.ISSelected ()) Break; } // beim Abbrechen von oben nach unten if (index == Kinder.SIZE ()) {für (int i = 0; i <chirids.size (); ++ i) {CheckBoxTeenode node = (CheckBoxTeenode) children.get (i); if (node.isSelected ()! }}} // Abbrechen, solange ein untergeordneter Knoten nicht ausgewählt ist, sollte der übergeordnete Knoten nicht ausgewählt werden. CheckBoxTeenode pnode = (CheckBoxTeenode) übergeordnet; if (pnode! = null && pnode.isSelected ()! }}} Der erste Unterschied wird gelöst, indem das Kontrollkästchen -Definitions -Definitions -Definition von defaultMutabletreenode erben wird, und der zweite Unterschied muss als nächstes gelöst werden. Der zweite Unterschied ist der Unterschied im Erscheinungsbild, und jeder Knoten von JTree wird über Treecellrenderer angezeigt. Um den zweiten Unterschied zu beheben, definieren wir ein neues CheckBoxTreeCellRenderer für Klasse, der die TreecellRenderer -Schnittstelle implementiert. Der Quellcode von CheckBoxTeRepererer ist wie folgt:
Paketdemo; Import Java.awt.Color; importieren java.awt.component; Import Java.awt.Dimension; importieren javax.swing.jcheckbox; import Javax.swing.jpanel; import Javax.swing.jtree; import Javax.swing.uimanager; import Javax.swing.plaf.coloruireSource; import Javax.swing.Tree.TreeCellRenderer; Public Class CheckBoxTreeCellRenderer erweitert JPanel implementiert TreecellRenderer {Protected JCheckBox Check; geschützte CheckBoxTeelabel -Etikett; public checkBoxTreeCellRenderer () {setLayout (null); add (check = new jCheckbox ()); add (label = new CheckBoxTeelabel ()); check.setbackground (uimanager.getColor ("Tree.TextBackground")); label.setforenground (uimanager.getColor ("Tree.Textforeground")); }/*** Gibt ein <code> jpanel </code> zurück, das ein <code> jCheckBox </code> Objekt* und ein <code> jLabel </code> -Objekt enthält. Und entscheiden Sie, ob <code> jCheckBox </code> * ausgewählt wird, basierend darauf, ob jeder Knoten ausgewählt ist. */ @Override Public Component getTreeCellRendererComponent (JTREE TREE, Objektwert, boolean ausgewählt, boolean erweitert, boolean blatt, int row, boolean hasfocus) {String StringValue = Tree.convertValUeTotext (Wert, ausgewählt, erweitert, laften, lafte, zeile, hasFocus); setEnabled (baum.issenabled ()); check.setSelected (((checkBoxTeenode). label.setfont (tree.getFont ()); label.setText (stringValue); label.setSelected (ausgewählt); label.setFocus (HASFOCUS); if (Leaf) label.seticon (uimanager.geticon ("tree.leaficon")); sonst wenn (erweitert) label.seticon (uimanager.geticon ("tree.openicon")); sonst label.seticon (uimanager.geticon ("tree.closesecon")); gib dies zurück; } @Override öffentliche Dimension getPreferredSize () {Dimension dCheck = check.getPreferredSize (); Dimension dlabel = label.getPreferredSize (); Neue Dimension zurückgeben (DCheck.width + dlabel.width, dcheck.height <dlabel.height? dlabel.height: dcheck.height); } @Override public void dolayout () {Dimension dCheck = check.getPreferredsize (); Dimension dlabel = label.getPreferredSize (); int yCheck = 0; int ylabel = 0; if (dcheck.height <dlabel.height) yCheck = (dlabel.height - dcheck.height) / 2; sonst ylabel = (dcheck.height - dlabel.height) / 2; check.setLocation (0, yCheck); check.setBounds (0, yCheck, dcheck.width, dcheck.height); label.setLocation (dcheck.width, ylabel); label.setBounds (dcheck.width, ylabel, dlabel.width, dlabel.height); } @Override public void retbackground (Farbfarbe) {if (Farbinstanz von ColorUiresource) color = null; Super.Setbackground (Farbe); }} Bei der Implementierung von CheckBoxTreeCellRenderer gibt die GetTreeCellRendererComponent -Methode JPanel zurück, anstatt JLabel wie defaultTreecellRenderer zurückzugeben. Daher kann das JLabel im JPanel nicht auf die Auswahl reagieren. Daher haben wir eine Unterklasse von JLabel CheckBoxTeelabel neu implementiert, die auf die Auswahl reagieren kann, und der Quellcode lautet wie folgt:
Paketdemo; Import Java.awt.Color; Import Java.awt.Dimension; importieren java.awt.graphics; import Javax.swing.icon; import Javax.swing.jlabel; import Javax.swing.uimanager; import Javax.swing.plaf.coloruireSource; Public Class CheckBoxTreelabel erweitert JLabel {private boolean identifiziert; privater boolescher Hasfocus; public checkBoxTeelabel () {} @Override public void retbackground (Farbfarbe) {if (Farbinstanz von ColorUireSource) color = null; Super.Setbackground (Farbe); } @Override public void Paint (Grafik g) {String str; if ((str = getText ())! sonst g.setColor (uimanager.getColor ("tree.textbackground"); Dimension D = GetPreferredSize (); int imageOffset = 0; Icon currenticon = geticon (); if (currenticon! G. -FillRect (ImageOffset, 0, D. Width - 1 - ImageOffset, D.Height); if (hasfocus) {g.setColor (uimanager.getColor ("tre.SelectionBorderColor")); G.Drawrect (ImageOffset, 0, D. Width - 1 - ImageOffset, D.Height - 1); }}} super.paint (g); } @Override öffentliche Dimension getPreferredSize () {Dimension retDimension = super.getPreferredSize (); if (retdimension! = null) retdimension = neue Dimension (retdimension.width + 3, retdimension.height); Return -Retimension; } public void setSelected (boolean identifiziert) {this. isSelected = isselected; } public void setfocus (boolean hasfocus) {thas.hasfocus = hasfocus; }} Durch Definieren von CheckBoxTeenode und CheckBoxTreeCellRenderer. Wir haben die beiden grundlegenden Unterschiede zwischen CheckBoxTree und JTree gelöst, aber es gibt immer noch ein detailliertes Problem, das gelöst werden muss, dh CheckBoxTree kann entscheiden, ob ein bestimmter Knoten als Antwort auf Benutzerereignisse ausgewählt werden soll. Zu diesem Zweck fügen wir einen CheckBoxTree -Listener hinzu, der auf Benutzermausereignisse reagiert. Der Quellcode dieser Klasse lautet wie folgt:
Paketdemo; Import Java.awt.event.Mouseadapter; import Java.awt.event.mouseeEvent; import Javax.swing.jtree; import Javax.swing.tree.treepath; importieren javax.swing.tree.defaultTreemodel; public class checkboxTeReenodeselectionListener erweitert Mouseadapter {@Override public void mouseclicked (MouseEvent Event) {Jtree tree = (jTree) event.getSource (); int x = event.getX (); int y = event.gety (); int row = tree.getRowforlocation (x, y); Treepath path = tree.getPathForrow (Reihe); if (path! if (node! = null) {boolean isselected =! node.isSelected (); node.setSelected (identifiziert); ((StandardTreemodel) tree.getModel ()). Nodestructurechanged (Knoten); }}}}} Bisher wurden alle von CheckBoxTree geforderten Komponenten abgeschlossen, und der nächste Schritt ist die Verwendung. Der Quellcode für die Verwendung dieser Komponenten ist unten angegeben:
Paketdemo; importieren javax.swing.jframe; import Javax.swing.jscrollpane; import Javax.swing.jtree; importieren javax.swing.tree.defaultTreemodel; öffentliche Klasse Demomain {public static void main (String [] args) {jframe Fram = new JFrame ("CheckBoxTeedemo"); Frame.SetBounds (200, 200, 400, 400); JTREE TREE = new Jtree (); CheckBoxTeenode rootNode = new CheckBoxTeenode ("root"); CheckBoxTeenode node1 = new CheckBoxTeenode ("node_1"); CheckBoxTeenode node1_1 = Neue CheckBoxTeenode ("node_1_1"); CheckBoxTeenode node1_2 = Neue CheckBoxTeenode ("node_1_2"); CheckBoxTeenode node1_3 = neu checkBoxTeenode ("node_1_3"); node1.add (node1_1); node1.add (node1_2); node1.add (node1_3); CheckBoxTeenode node2 = new CheckBoxTeenode ("node_2"); CheckBoxTeenode node2_1 = Neue CheckBoxTeenode ("node_2_1"); CheckBoxTeenode node2_2 = Neue CheckBoxTeenode ("node_2_2"); node2.add (node2_1); node2.add (node2_2); rootNode.add (node1); rootNode.add (node2); StandardTreemodel model = new StandardTreemodel (rootNode); tree.addMouselistener (neue CheckBoxTeenodeselectionListener ()); Tree.SetModel (Modell); Tree.SetCellRenderer (neue CheckBoxTreeCellRenderer ()); JScrollPane scroll = new Jscrollpane (Baum); scroll.setBounds (0, 0, 300, 320); Frame.GetContentPane (). add (scrollen); Frame.SetDefaultCloseOperation (jframe.exit_on_close); Frame.SetVisible (True); }}Die Ausführungsergebnisse sind in der folgenden Abbildung dargestellt:
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.