swing实现多选树

案例:详细描述

要求能够对树进行多选

效果图片

在这里插入图片描述

实现代码

CheckBoxTreeCellRenderer.java

package xny.hyd.tool.choosetree;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;

import javax.swing.ImageIcon;
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;
 
@SuppressWarnings("serial")
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"));
		check.setOpaque(false);
		label.setForeground(UIManager.getColor("Tree.textForeground"));
	}
	
	/**
	 * 返回的是一个<code>JPanel</code>对象,该对象中包含一个<code>JCheckBox</code>对象
	 * 和一个<code>JLabel</code>对象。并且根据每个结点是否被选中来决定<code>JCheckBox</code>
	 * 是否被选中。
	 */
	@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"));*/
		try{
			if (tree.getModel().getRoot().equals(value)) {//根节点
				label.setIcon(new ImageIcon(this.getClass().getResource(
				"")));
			} else if (leaf) {//无子节点的叶子节点
				label.setIcon(new ImageIcon(this.getClass().getResource(
				"")));
			} else {
				if(expanded) {
					/*label.setIcon(new ImageIcon(this.getClass().getResource(
							"/xny/hyd/images/isnode.png")));*/
				}else {
					/*label.setIcon(new ImageIcon(this.getClass().getResource(
							"/xny/hyd/images/node.png")));*/
				}
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		label.setForeground(Color.decode("#339FBE"));// 设置文字的颜色
		label.setOpaque(false);
		label.setBackground(Color.decode("#66B6FF"));
//		label.setBackgroundSelectionColor(Color.decode("#135E73"));// 设置选中时的背景色
//		label.setBackgroundNonSelectionColor(Color.decode("#0A3D4C"));// 设置没选中时的背景色
		this.setOpaque(false);
		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);
	}
}

CheckBoxTreeLabel.java

package xny.hyd.tool.choosetree;
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;
 
@SuppressWarnings("serial")
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(Color.decode("#135E73"));
				else
					g.setColor(Color.decode("#122931"));
				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.java

package xny.hyd.tool.choosetree;
import java.util.ArrayList;
import java.util.List;

import javax.swing.tree.DefaultMutableTreeNode;

@SuppressWarnings("serial")
public class CheckBoxTreeNode extends DefaultMutableTreeNode
{
	protected boolean isSelected;
	private List<String> nodeList = new ArrayList<String>();
	
	public List<String> getNodeList() {
		return nodeList;
	}

	public void setNodeList(List<String> nodeList) {
		this.nodeList = nodeList;
	}

	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;
	}
	/**
	 * 获取树所有选中的节点
	 * @param trees
	 * @return
	 */
	public List<String> getCheckNode(){
		nodeList = new ArrayList<String>();
		if(children != null)
		{
			for(Object obj : children)
			{
				CheckBoxTreeNode node = (CheckBoxTreeNode)obj;
				List<String> nods = node.getCheckNode();
				if(node.isSelected()) {
					nods.add(node.toString());
				}
				nodeList.addAll(nods);
			}
		}
		
		return nodeList;
	}
	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;
				}
				 
				  /*表明pNode所有子结点都已经选中,则选中父结点,
				  该方法是一个递归方法,因此在此不需要进行迭代,因为
				  当选中父结点后,父结点本身会向上检查的。*/
				 
				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);
		}
	}
}

CheckBoxTreeNodeSelectionListener.java

package xny.hyd.tool.choosetree;

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);
			}
		}
	}
}

DemoMain.java测试类

package xny.hyd.tool.choosetree;

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("大渡河流域");
		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("嘉陵江流域");
		CheckBoxTreeNode node2_1 = new CheckBoxTreeNode("多诺");
		CheckBoxTreeNode node2_2 = new CheckBoxTreeNode("宝珠寺");
		CheckBoxTreeNode node2_3 = new CheckBoxTreeNode("亭子口");
		CheckBoxTreeNode node2_4 = new CheckBoxTreeNode("水牛家");
		CheckBoxTreeNode node2_5 = new CheckBoxTreeNode("卖团");
		CheckBoxTreeNode node2_6 = new CheckBoxTreeNode("自一里");
		CheckBoxTreeNode node2_7 = new CheckBoxTreeNode("木坐");
		CheckBoxTreeNode node2_8 = new CheckBoxTreeNode("明台");
		CheckBoxTreeNode node2_9 = new CheckBoxTreeNode("七星");
		CheckBoxTreeNode node2_10 = new CheckBoxTreeNode("龙安");
		CheckBoxTreeNode node2_11 = new CheckBoxTreeNode("青居");
		CheckBoxTreeNode node2_12 = new CheckBoxTreeNode("东西关");
		node2.add(node2_1);
		node2.add(node2_2);
		node2.add(node2_3);
		node2.add(node2_4);
		node2.add(node2_5);
		node2.add(node2_6);
		node2.add(node2_7);
		node2.add(node2_8);
		node2.add(node2_9);
		node2.add(node2_10);
		node2.add(node2_11);
		node2.add(node2_12);
		rootNode.add(node1);
		rootNode.add(node2);
		DefaultTreeModel model = new DefaultTreeModel(rootNode);
		tree.addMouseListener(new CheckBoxTreeNodeSelectionListener());
		tree.setModel(model);
		tree.setCellRenderer(new CheckBoxTreeCellRenderer());
		//隐藏根节点
		tree.setRootVisible(false);
		tree.setShowsRootHandles(true);
		
		JScrollPane scroll = new JScrollPane(tree);
		scroll.setBounds(0, 0, 300, 320);
		frame.getContentPane().add(scroll);
		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作为 AI 助手,我并不会编写代码,但我可以提供一些帮助,希望对你有所帮助。 要使用 Swing 实现二叉排序,你可以遵循以下步骤: 1. 创建一个类来表示二叉节点。节点应该包含一个值和左右子节点的引用。 ```java public class BinaryTreeNode { int value; BinaryTreeNode left; BinaryTreeNode right; public BinaryTreeNode(int value) { this.value = value; left = null; right = null; } } ``` 2. 创建一个类来表示二叉排序。该类应该包含一个根节点的引用。 ```java public class BinarySearchTree { BinaryTreeNode root; public BinarySearchTree() { root = null; } } ``` 3. 实现二叉排序的插入方法。该方法应该在中插入一个新的节点,并保证仍然是一个二叉排序。 ```java public void insert(int value) { BinaryTreeNode newNode = new BinaryTreeNode(value); if (root == null) { root = newNode; return; } BinaryTreeNode current = root; BinaryTreeNode parent = null; while (true) { parent = current; if (value < current.value) { current = current.left; if (current == null) { parent.left = newNode; return; } } else { current = current.right; if (current == null) { parent.right = newNode; return; } } } } ``` 4. 实现二叉排序的遍历方法。你可以实现中序遍历、先序遍历和后序遍历。 ```java public void inOrderTraversal(BinaryTreeNode node) { if (node != null) { inOrderTraversal(node.left); System.out.print(node.value + " "); inOrderTraversal(node.right); } } public void preOrderTraversal(BinaryTreeNode node) { if (node != null) { System.out.print(node.value + " "); preOrderTraversal(node.left); preOrderTraversal(node.right); } } public void postOrderTraversal(BinaryTreeNode node) { if (node != null) { postOrderTraversal(node.left); postOrderTraversal(node.right); System.out.print(node.value + " "); } } ``` 5. 创建一个 Swing 界面,让用户可以输入节点的值并将其插入到二叉排序中。你还可以添加按钮来执行遍历方法并在界面上显示结果。 这些步骤应该可以帮助你使用 Swing 实现二叉排序。如果你需要更详细的帮助,请参考相关文档或寻求其他开发者的帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值