При разработке программ пользовательского интерфейса с использованием Java Swing вы, вероятно, столкнетесь с необходимостью использования дерева с флажками, но Java Swing не предоставляет этот компонент, поэтому, если у вас есть это требование, вы должны реализовать дерево с флажками сами.
Существуют различия между Checkboxtree и Jtree на двух уровнях:
1. На уровне модели каждый узел Checkboberee нуждается в элементе, чтобы сохранить, выбран ли он, но узлы Jtree нет.
2. На слое представления каждый узел Checkboxtree отображает еще один флажок, чем узел Jtree.
Поскольку существует два различия, если мы заполняем эти два различия в нашей собственной реализации, будет реализовано дерево с флажками.
Теперь начните разрешать первое разницу. Чтобы решить первое разницу, необходимо определить новое чековое узел класса. Для фиксатора, если выбран узел, его флажок будет проверен, и мотивация для использования Checkboxtree - выбрать поддерев одновременно. Затем, когда узел выбран или отменен, его предок узел и узел потомка должны внести некоторые изменения. Здесь мы применяем следующие рекурсивные правила:
1. Если узел выбран вручную, все его потомки должны быть выбраны; Если узел выбран, чтобы сделать всех детей его родительского узла, то его родительский узел выбирается.
2. Если узел вручную не контролируется, все его потомки должны быть неконтролированы; Если исходный узел узела выбирается, его родительский узел не контролируется.
Примечание. Вышеуказанные два правила являются рекурсивными правилами. Когда узел меняется и приводит к изменению другого узла, другой узел также приведет к изменению других узлов. В двух вышеупомянутых правилах ручной выбор или ручное отказание узела приведет к неучительному выбору или невыполнению других узлов. Этот некомедический отбор или не выявление этого неважно-ручного отбора или невыполнения не будет применяться к вышеуказанным правилам.
Исходный код CheckboxtreeNode реализован в соответствии с вышеуказанными правилами, выглядит следующим образом:
Демонстрация упаковки; импортировать javax.swing.tree.defaultmutabletreenode; Public Class CheckBoxtreeNode Extends defaultMutableTreeNode {Protected Boolean Isselected; public faceboxtreeNode () {this (null); } public fackboxtreeNode (Object userObject, true, false); } public fackboxTreeNode (Object userObject, Boolean AlsChildren, Boolean Isselected) {super (userObject, разрешение детей); это. } public boolean isselected () {return isselected; } public void setSelected (boolean _isseled) {this.isselected = _isseled; if (_isselected) {// Если выбрано, выберите все его дочерние узлы, если (дети! = null) {for (Object obj: дети) {checkboxtreenode node = (fackboxtreeNode) obj; if (_isseled! }} // Проверьте, если выбираются все дочерние узлы родительского узла, то выберите Parent Parent Parent Parent; // Начните проверять, выбираются ли все дочерние узлы PNODE IF (pnode! = Null) {int index = 0; for (; index <pnode.children.size (); ++ index) {faceboxtreeNode pchildNode = (fackboxTreeNode) pnode.children.get (index); if (! pChildNode.isselected ()) разрыв; } / * * Указывает, что все дочерние узлы PNODE были выбраны, был выбран родительский узел. * Этот метод является рекурсивным методом, поэтому здесь нет необходимости итерации, потому что * Когда выбран родительский узел, сам родительный узел проверит вверх. */ if (index == pnode.children.size ()) {if (pnode.isselected ()! = _isselected) pnode.setselected (_isselected); }}} else { / * * Если аннулирование родительского узла приводит к отмене узела дочернего узела, то в это время следует выбрать все узлы дочерних узлов; * В противном случае отмена детского узла приведет к аннулированию родительского узла, а затем отмена родительского узла приведет к отмене узела дочернего узела, но * не требуется отменить детский узел в это время. */ if (дети! = null) {int index = 0; for (; index <kinds.size (); ++ index) {fackboxtreeNode childnode = (fackboxtreeNode) kids.get (index); if (! Childnode.isselected ()) разрыв; } // При отмене сверху вниз if (index == wards.size ()) {for (int i = 0; i <kings.size (); ++ i) {checkboxTreeNode node = (checkboxtreeNode) kids.get (i); if (node.isselected ()! = _isseled) node.setselected (_isselected); }}} // Отменить, если есть дочерний узел, который не выбран, родительский узел не должен быть выбран. CHACEBOXTREENODE PNODE = (CHACEBOXTERODE) Parent; if (pnode! = null && pnode.isselected ()! = _isseled) pnode.setselected (_isselected); }}} Первое различие решается путем унаследования контрольного флекса определения по умолчанию по умолчанию, и второе отличие должно быть разрешено дальше. Второе отличие - разница в внешности, и каждый узел jtree отображается через Treecellrenderer. Чтобы разрешить второе различие, мы определяем новый Class Beckboxtreecellrenderer, который реализует интерфейс TreeCellRenderer. Исходный код Checkboxtreerenderer заключается в следующем:
Демонстрация упаковки; импортировать java.awt.color; импортировать java.awt.component; Импорт java.awt.dimension; импортировать javax.swing.jcheckbox; импортировать javax.swing.jpanel; импортировать javax.swing.jtree; Импорт javax.swing.uimanager; импортировать javax.swing.plaf.coloruiresource; Импорт javax.swing.tree.treecellrenderer; Public Class CheckboxTeeCellRenderer Extens JPanel реализует TreeCellRenderer {Protected JCHECKBOX SHECK; Защищенная флажковая метка; public FaceboxTreeCellRenderer () {setLayout (null); добавить (check = new jcheckbox ()); add (label = new Checkboxtreelabel ()); check.setbackground (uimanager.getcolor ("tree.textbackground")); label.setforeground (uimanager.getcolor ("tree.textforeground")); }/*** Возвращает объект <code> jPanel </code>, который содержит объект <code> jCheckbox </code> и объект <code> jlabel </code>. И решите, выбран ли <code> jcheckbox </code> * на основе того, выбран ли каждый узел. */ @Override public Component getTreeCellRendererComponent (дерево Jtree, значение объекта, выбранное логическое, логическое расширение, логический лист, int row, boolean hasfocus) {String Stringvalue = tree.convertvaluetotext (значение, выбранное, расширенное, листье, ряд, hasfocus); setEnabled (tree.iseSabled ()); check.setelected (((faceboxtreenode) значение) .siselected ()); label.setfont (tree.getFont ()); label.settext (StringValue); метка label.setfocus (hasfocus); if (leaf) label.seticon (uimanager.geticon ("tree.leaficon")); иначе if (расширен) label.seceton (uimanager.geticon ("tree.openicon")); else label.seticon (uimanager.geticon ("tree.closedicon")); вернуть это; } @Override public Dimension getPreferRedSize () {Dimension dcheck = check.getPreferredSize (); Размер dlabel = label.getPreferredSize (); вернуть новое измерение (dcheck.width + dlabel.width, dcheck.height <dlabel.height? dlabel.height: dcheck.height); } @Override public void dolayout () {dimension dcheck = check.getPreferredSize (); Размер dlabel = label.getPreferredSize (); int ycheck = 0; int ylabel = 0; if (dcheck.height <dlabel.height) ycheck = (dlabel.height - dcheck.height) / 2; else 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 setbackground (color) {if (цветовой экземпляр Coloruiresource) color = null; super.setbackground (цвет); }} В реализации CheckboxTreeCellrenderer метод getTreeCellRendererComponent возвращает JPanel, вместо того, чтобы возвращать Jlabel, как DefaultTreeCellrenderer. Следовательно, Jlabel в JPanel не может отреагировать на выбор. Поэтому мы переопределили подкласс Jlabel Faceboxboblexelabel, который может реагировать на выбор, а его исходный код заключается в следующем:
Демонстрация упаковки; импортировать java.awt.color; Импорт java.awt.dimension; импортировать java.awt.graphics; импортировать javax.swing.icon; импортировать javax.swing.jlabel; Импорт javax.swing.uimanager; импортировать javax.swing.plaf.coloruiresource; Public Class Checkboxtelebel Extends Jlabel {Private Boolean Isselected; Частный логический hasfocus; public faceboxteleabel () {} @Override public void sTeckbackground (цвет) {if (Color Encement of Coloruiresource) color = null; super.setbackground (цвет); } @Override public void Paint (Graphics G) {String Str; if ((str = getText ())! = null) {if (0 <str.length ()) {if (isselected) g.setcolor (uimanager.getcolor ("tree.selectionbackground")); иначе g.setcolor (uimanager.getcolor ("tree.textbackground")); Размер d = getPreferredSize (); int ImageOffset = 0; Icon currenticon = geticon (); if (currenticon! = null) imageOffset = custryicon.geticonWidth () + math.max (0, getIcontextGap () - 1); G.FillRect (ImageOffset, 0, D.Width - 1 - ImageOffset, D.Height); if (hasfocus) {g.setcolor (uimanager.getcolor ("tree.selectionbordercolor")); G.DrawRect (ImageOffset, 0, D.Width - 1 - ImageOffset, D.Height - 1); }}} super.paint (g); } @Override public Dimension getPreferredSize () {Dimension retdimension = super.getPreferredSize (); if (retdimension! = null) retdimension = новое измерение (retdimension.width + 3, retdimension.height); вернуть retdimension; } public void setSelected (boolean isselected) {this.isselected = isselected; } public void setFocus (boolean hasfocus) {this.hasfocus = hasfocus; }} Определяя CheckBoxTreeNode и Checkboxtreecellrenderer. Мы решили два фундаментальных различия между Checkboxtree и Jtree, но все еще существует подробная проблема, которую необходимо решить, то есть Checkboxtree может решить, следует ли выбрать определенный узел в ответ на события пользователей. Для этого мы добавляем слушателя Checkboxtree, который отвечает на события пользователей мыши. Исходный код этого класса заключается в следующем:
Демонстрация упаковки; импортировать java.awt.event.mouseadapter; Импорт java.awt.event.mouseeVent; импортировать javax.swing.jtree; Импорт javax.swing.tree.treepath; импортировать javax.swing.tree.defaulttreemodel; Public Class CheckboxtreeNodeselectionListener Extends 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 (ряд); if (path! = null) {fackboxtreeNode node = (fackboxtreenode) path.getlastpathcomponent (); if (node! = null) {boolean isselected =! node.isselected (); node.setelected (isseleted); ((DefaultTreeModel) tree.getModel ()). NodestructureChanged (узлы); }}}}} До сих пор все компоненты, необходимые для Checkboxtree, были завершены, и следующим шагом является то, как их использовать. Исходный код для использования этих компонентов приведен ниже:
Демонстрация упаковки; импортировать javax.swing.jframe; Импорт javax.swing.jscrollpane; импортировать javax.swing.jtree; импортировать javax.swing.tree.defaulttreemodel; открытый класс Demomain {public static void main (string [] args) {jframe frame = new jframe ("checkboxtreedemo"); Frame.SetBounds (200, 200, 400, 400); Jtree tree = new jtree (); CHACEBOXTREENODE ROOTNODE = NEW CHACEBOXTERODE ("ROOT"); CHACEBOXTREENODE NODE1 = NEW CHACEBOXTERODE ("NODE_1"); CHACEBOXTREENODE NODE1_1 = NEW CHACEBOXTERODE ("NODE_1_1"); CHACEBOXTERODE NODE1_2 = NEW CHACEBOXTERODE ("NODE_1_2"); CHACEBOXTERODE NODE1_3 = NEW CHACEBOXTERODE ("NODE_1_3"); node1.add (node1_1); node1.add (node1_2); node1.add (node1_3); CHACEBOXTREENODE NODE2 = NEW CHACEBOXTERODE ("NODE_2"); CHACEBOXTERODE NODE2_1 = NEW CHACEBOXTERODE ("NODE_2_1"); CHACEBOXTERODE NODE2_2 = NEW CHACEBOXTERODE ("NODE_2_2"); node2.add (node2_1); node2.add (node2_2); rootnode.add (node1); rootnode.add (node2); DefaultTreeModel model = new DefaultTreeModel (rootNode); Tree.AddMouseListener (новый CheckBoxTreeNodeSelectionListener ()); tree.setmodel (модель); Tree.SetCellRenderer (новый CheckBoxTreeCellRenderer ()); JScrollpane Scroll = new jscrollpane (дерево); scroll.setbounds (0, 0, 300, 320); Frame.getContentPane (). Add (Scroll); frame.setDefaultCloseoPeration (jframe.exit_on_close); Frame.SetVisible (true); }}Результаты выполнения показаны на рисунке ниже:
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.