返回顶部
首页 > 资讯 > 精选 >Java怎么实现带复选框的树
  • 525
分享到

Java怎么实现带复选框的树

javacheckboxtree 2023-05-30 20:05:51 525人浏览 安东尼
摘要

小编给大家分享一下Java怎么实现带复选框的树,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在使用Java Swing开发UI程序时,很有可能会遇到使用带复选框的

小编给大家分享一下Java怎么实现带复选框的树,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

在使用Java Swing开发UI程序时,很有可能会遇到使用带复选框的树的需求,但是Java Swing并没有提供这个组件,因此如果你有这个需求,你就得自己动手实现带复选框的树。

CheckBoxTree与JTree在两个层面上存在差异:

在模型层上,CheckBoxTree的每个结点需要一个成员来保存其是否被选中,但是JTree的结点则不需要。
2.在视图层上,CheckBoxTree的每个结点比JTree的结点多显示一个复选框。

既然存在两个差异,那么只要我们把这两个差异部分通过自己的实现填补上,那么带复选框的树也就实现了。
现在开始解决第一个差异。为了解决第一个差异,需要定义一个新的结点类CheckBoxTreenode,该类继承DefaultMutableTreeNode,并增加新的成员isSelected来表示该结点是否被选中。对于一颗CheckBoxTree,如果某一个结点被选中的话,其复选框会勾选上,并且使用CheckBoxTree的动机在于可以一次性地选中一颗子树。那么,在选中或取消一个结点时,其祖先结点和子孙结点应该做出某种变化。在此,我们应用如下递归规则:

如果某个结点被手动选中,那么它的所有子孙结点都应该被选中;如果选中该结点使其父节点的所有子结点都被选中,则选中其父结点。
2.如果某个结点被手动取消选中,那么它的所有子孙结点都应该被取消选中;如果该结点的父结点处于选中状态,则取消选中其父结点。

注意:上面的两条规则是递归规则,当某个结点发生变化,导致另外的结点发生变化时,另外的结点也会导致其他的结点发生变化。在上面两条规则中,强调手动,是因为手动选中或者手动取消选中一个结点,会导致其他结点发生非手动的选中或者取消选中,这种非手动导致的选中或者非取消选中则不适用于上述规则。

按照上述规则实现的CheckBoxTreeNode源代码如下:

package demo;  import javax.swing.tree.DefaultMutableTreeNode;  public class CheckBoxTreeNode extends DefaultMutableTreeNode {  protected boolean isSelected;    public CheckBoxTreeNode()  {   this(null);  }    public CheckBoxTreeNode(Object userObject)  {   this(userObject, true, false);  }    public CheckBoxTreeNode(Object userObject, boolean allowsChildren, boolean isSelected)  {   super(userObject, allowsChildren);   this.isSelected = isSelected;  }   public boolean isSelected()  {   return isSelected;  }    public void setSelected(boolean _isSelected)  {   this.isSelected = _isSelected;      if(_isSelected)   {    // 如果选中,则将其所有的子结点都选中    if(children != null)    {     for(Object obj : children)     {      CheckBoxTreeNode node = (CheckBoxTreeNode)obj;      if(_isSelected != node.isSelected())       node.setSelected(_isSelected);     }    }    // 向上检查,如果父结点的所有子结点都被选中,那么将父结点也选中    CheckBoxTreeNode pNode = (CheckBoxTreeNode)parent;    // 开始检查pNode的所有子节点是否都被选中    if(pNode != null)    {     int index = 0;     for(; index < pNode.children.size(); ++ index)     {      CheckBoxTreeNode pChildNode = (CheckBoxTreeNode)pNode.children.get(index);      if(!pChildNode.isSelected())       break;     }          if(index == pNode.children.size())     {      if(pNode.isSelected() != _isSelected)       pNode.setSelected(_isSelected);     }    }   }   else   {        if(children != null)    {     int index = 0;     for(; index < children.size(); ++ index)     {      CheckBoxTreeNode childNode = (CheckBoxTreeNode)children.get(index);      if(!childNode.isSelected())       break;     }     // 从上向下取消的时候     if(index == children.size())     {      for(int i = 0; i < children.size(); ++ i)      {       CheckBoxTreeNode node = (CheckBoxTreeNode)children.get(i);       if(node.isSelected() != _isSelected)        node.setSelected(_isSelected);      }     }    }        // 向上取消,只要存在一个子节点不是选上的,那么父节点就不应该被选上。    CheckBoxTreeNode pNode = (CheckBoxTreeNode)parent;    if(pNode != null && pNode.isSelected() != _isSelected)     pNode.setSelected(_isSelected);   }  } }

第一个差异通过继承DefaultMutableTreeNode定义CheckBoxTreeNode解决了,接下来需要解决第二个差异。第二个差异是外观上的差异,JTree的每个结点是通过TreeCellRenderer进行显示的。为了解决第二个差异,我们定义一个新的类CheckBoxTreeCellRenderer,该类实现了TreeCellRenderer接口。CheckBoxTreeRenderer的源代码如下:

package demo;  import java.awt.Color; import java.awt.Component; import java.awt.Dimension;  import 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 extends JPanel implements TreeCellRenderer {  protected JCheckBox check;  protected CheckBoxTreeLabel label;    public CheckBoxTreeCellRenderer()  {   setLayout(null);   add(check = new JCheckBox());   add(label = new CheckBoxTreeLabel());   check.setBackground(UIManager.getColor("Tree.textBackground"));   label.setForeground(UIManager.getColor("Tree.textForeground"));  }      @Override  public Component getTreeCellRendererComponent(JTree tree, Object value,    boolean selected, boolean expanded, boolean leaf, int row,    boolean hasFocus)  {   String stringValue = tree.convertValueToText(value, selected, expanded, leaf, row, hasFocus);   setEnabled(tree.isEnabled());   check.setSelected(((CheckBoxTreeNode)value).isSelected());   label.setFont(tree.getFont());   label.setText(stringValue);   label.setSelected(selected);   label.setFocus(hasFocus);   if(leaf)    label.setIcon(UIManager.getIcon("Tree.leafIcon"));   else if(expanded)    label.setIcon(UIManager.getIcon("Tree.openIcon"));   else    label.setIcon(UIManager.getIcon("Tree.closedIcon"));       return this;  }   @Override  public Dimension getPreferredSize()  {   Dimension dCheck = check.getPreferredSize();   Dimension dLabel = label.getPreferredSize();   return new Dimension(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;   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 color)  {   if(color instanceof ColorUIResource)    color = null;   super.setBackground(color);  } }

在CheckBoxTreeCellRenderer的实现中,getTreeCellRendererComponent方法返回的是JPanel,而不是像DefaultTreeCellRenderer那样返回JLabel,因此JPanel中的JLabel无法对选中做出反应,因此我们重新实现了一个JLabel的子类CheckBoxTreeLabel,它可以对选中做出反应,其源代码如下:

package demo;  import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics;  import javax.swing.Icon; import javax.swing.JLabel; import javax.swing.UIManager; import javax.swing.plaf.ColorUIResource;  public class CheckBoxTreeLabel extends JLabel {  private boolean isSelected;  private boolean hasFocus;    public CheckBoxTreeLabel()  {  }    @Override  public void setBackground(Color color)  {   if(color instanceof ColorUIResource)    color = null;   super.setBackground(color);  }    @Override  public void paint(Graphics g)  {   String str;   if((str = getText()) != null)   {    if(0 < str.length())    {     if(isSelected)      g.setColor(UIManager.getColor("Tree.selectionBackground"));     else      g.setColor(UIManager.getColor("Tree.textBackground"));     Dimension d = getPreferredSize();     int imageOffset = 0;     Icon currentIcon = getIcon();     if(currentIcon != null)      imageOffset = currentIcon.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 = new Dimension(retDimension.width + 3, retDimension.height);   return retDimension;  }    public void setSelected(boolean isSelected)  {   this.isSelected = isSelected;  }    public void setFocus(boolean hasFocus)  {   this.hasFocus = hasFocus;  } }

通过定义CheckBoxTreeNode和CheckBoxTreeCellRenderer。我们解决了CheckBoxTree和JTree的两个根本差异,但是还有一个细节问题需要解决,就是CheckBoxTree可以响应用户事件决定是否选中某个结点。为此,我们为CheckBoxTree添加一个响应用户鼠标事件的监听器CheckBoxTreeNodeSelectionListener,该类的源代码如下:

package demo;  import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent;  import javax.swing.JTree; import javax.swing.tree.TreePath; import 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(row);   if(path != null)   {    CheckBoxTreeNode node = (CheckBoxTreeNode)path.getLastPathComponent();    if(node != null)    {     boolean isSelected = !node.isSelected();     node.setSelected(isSelected);     ((DefaultTreeModel)tree.getModel()).nodeStructureChanged(node);    }   }  } }

到此为止,CheckBoxTree所需要的所有组件都已经完成了,接下来就是如何使用这些组件。下面给出了使用这些组件的源代码:

package demo;  import javax.swing.JFrame; import javax.swing.jscrollPane; import javax.swing.JTree; import javax.swing.tree.DefaultTreeModel;  public class DemoMain {  public static void main(String[] args)  {   JFrame frame = new JFrame("CheckBoxTreeDemo");   frame.setBounds(200, 200, 400, 400);   JTree tree = new JTree();   CheckBoxTreeNode rootNode = new CheckBoxTreeNode("root");   CheckBoxTreeNode node1 = new CheckBoxTreeNode("node_1");   CheckBoxTreeNode node1_1 = new CheckBoxTreeNode("node_1_1");   CheckBoxTreeNode node1_2 = new CheckBoxTreeNode("node_1_2");   CheckBoxTreeNode node1_3 = new CheckBoxTreeNode("node_1_3");   node1.add(node1_1);   node1.add(node1_2);   node1.add(node1_3);   CheckBoxTreeNode node2 = new CheckBoxTreeNode("node_2");   CheckBoxTreeNode node2_1 = new CheckBoxTreeNode("node_2_1");   CheckBoxTreeNode node2_2 = new CheckBoxTreeNode("node_2_2");   node2.add(node2_1);   node2.add(node2_2);   rootNode.add(node1);   rootNode.add(node2);   DefaultTreeModel model = new DefaultTreeModel(rootNode);   tree.addMouseListener(new CheckBoxTreeNodeSelectionListener());   tree.setModel(model);   tree.setCellRenderer(new CheckBoxTreeCellRenderer());   JScrollPane scroll = new JScrollPane(tree);   scroll.setBounds(0, 0, 300, 320);   frame.getContentPane().add(scroll);      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   frame.setVisible(true);  } }

其执行结果如下图所示:

Java怎么实现带复选框的树

以上是“Java怎么实现带复选框的树”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: Java怎么实现带复选框的树

本文链接: https://lsjlt.com/news/221107.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java怎么实现带复选框的树
    小编给大家分享一下Java怎么实现带复选框的树,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在使用Java Swing开发UI程序时,很有可能会遇到使用带复选框的...
    99+
    2023-05-30
    java checkbox tree
  • java JTree JCheckBox树复选框详解
    本文实例为大家分享了java JTree JCheckBox树复选框展示的具体代码,供大家参考,具体内容如下CheckTreeManager.javapublic class CheckTreeManager extends MouseAd...
    99+
    2023-05-30
    java jtree jcheckbox
  • Java如何做带复选框的菜单实例代码
    说明:         上面是我用Java做的扫雷游戏,其中就用到了带复选框式的菜单,原来也是用JCheckBoxMenuItem做的,但发现实在是问题多多,后干脆就用普通的JMe...
    99+
    2024-04-02
  • Java是如何做带复选框的菜单
    本篇文章为大家展示了Java是如何做带复选框的菜单,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。说明:        ...
    99+
    2023-06-22
  • JavaScript怎么实现复选框全选功能
    这篇文章主要介绍了JavaScript怎么实现复选框全选功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体内容如下代码:<!DOCTYPE html>...
    99+
    2023-06-14
  • 怎么用css3实现checkbox复选框和radio单选框
    这篇文章主要介绍“怎么用css3实现checkbox复选框和radio单选框”,在日常操作中,相信很多人在怎么用css3实现checkbox复选框和radio单选框问题上存在疑惑,小编查阅了各式资料,整理出...
    99+
    2024-04-02
  • 纯css3怎么实现简单的checkbox复选框和radio单选框
    这篇文章主要介绍“纯css3怎么实现简单的checkbox复选框和radio单选框”,在日常操作中,相信很多人在纯css3怎么实现简单的checkbox复选框和radio单选框问题上存在疑惑,小编查阅了各式...
    99+
    2024-04-02
  • 怎么实现jQuert复选框的一个勾选效果
    本篇内容主要讲解“怎么实现jQuert复选框的一个勾选效果”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么实现jQuert复选框的一个勾选效果”吧!   方...
    99+
    2024-04-02
  • 使用CSS怎么实现一个单选框和复选框功能
    使用CSS怎么实现一个单选框和复选框功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。在html中,<label>标签通常和<input>标签一起使...
    99+
    2023-06-08
  • JavaScript实现复选框全选功能
    本文实例为大家分享了JavaScript实现复选框全选的具体代码,供大家参考,具体内容如下 代码: <!DOCTYPE html> <html lang="e...
    99+
    2024-04-02
  • CSS3中怎么实现复选框动画特效
    CSS3中怎么实现复选框动画特效,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。实例代码代码如下:<!DOCTYPE ht...
    99+
    2024-04-02
  • CSS中怎么实现一个页面复选框
    本篇文章给大家分享的是有关CSS中怎么实现一个页面复选框,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。第一步 分拆选中/未选中<inpu...
    99+
    2024-04-02
  • jQuery如何实现复选框的全选和反选
    这篇文章主要为大家展示了“jQuery如何实现复选框的全选和反选”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“jQuery如何实现复选框的全选和反选”这篇文章吧...
    99+
    2024-04-02
  • 带你用Java方法轻松实现树的同构
    目录树的同构总结树的同构 举例 树的构造 树可以由数组或链表来构造: 举例:上图左上角的树通过数组可表示为 0 ...
    99+
    2024-04-02
  • JS怎么实现复选框的全选和批量删除功能
    这篇文章将为大家详细讲解有关JS怎么实现复选框的全选和批量删除功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。如图示:功能描述:在勾选了全选时,所有的商品都会勾选,在取...
    99+
    2024-04-02
  • Angular如何实现多选复选框的弹出框指令
    这篇文章将为大家详细讲解有关Angular如何实现多选复选框的弹出框指令,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。要实现一个包含多个复选框的下拉框该如何做呢?先上个效...
    99+
    2024-04-02
  • 怎么在Vue.js中实现一个带下拉选项的输入框
    这篇文章将为大家详细讲解有关怎么在Vue.js中实现一个带下拉选项的输入框,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。注册组件通过将封装好的组件代码复制粘贴来注册全局组件。设计的时候有考虑...
    99+
    2023-06-14
  • HTML+CSS如何实现单选框、复选框美观的样式
    小编给大家分享一下HTML+CSS如何实现单选框、复选框美观的样式,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1.背景图html<div cla...
    99+
    2023-06-08
  • 基于Vue怎么实现树形穿梭框
    这篇文章主要介绍了基于Vue怎么实现树形穿梭框的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇基于Vue怎么实现树形穿梭框文章都会有所收获,下面我们一起来看看吧。树形穿梭框插件el-tree-transfer这个...
    99+
    2023-06-30
  • 怎么获取单选框和复选框的value值
    这篇文章主要讲解了“怎么获取单选框和复选框的value值”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么获取单选框和复选框的value值”吧!在开发过程中,为了提高代码维护性,一般使用fo...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作