Swing开发下拉树

案例:详细描述

当我们在进行swing绘制界面时,查询条件可能会需要用到下拉树,而非下拉列表,下拉树可以更好的展示数据的层级关系(如图所示),之前有发过多选树,可以结合做下拉多选树。

效果图片

在这里插入图片描述

实现代码

DownTheTree.java

package xny.tool;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;

import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.MenuSelectionManager;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ComboBoxUI;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.plaf.metal.MetalComboBoxUI;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

/**
 * 下拉树工具类
 * 2019年9月16日15:20:18
 * @author Administrator
 *
 */
@SuppressWarnings("serial")
public class DownTheTree extends JComboBox{
	/**
	 * 显示用的树
	 */
	private JTree tree;

	public DownTheTree() {
		this(new JTree());
	}

	public DownTheTree(JTree tree) {
		this.setTree(tree);
	}

	/**
	 * 设置树
	 * 
	 * @param tree
	 *            JTree
	 */
	public void setTree(JTree tree) {
		this.tree = tree;
		if (tree != null) {
			this.setSelectedItem(tree.getSelectionPath());
			this.setRenderer(new JTreeComboBoxRenderer());
		}
		this.updateUI();
	}

	/**
	 * 取得树
	 * 
	 * @return JTree
	 */
	public JTree getTree() {
		return tree;
	}

	/**
	 * 设置当前选择的树路径
	 * 
	 * @param o
	 *            Object
	 */
	public void setSelectedItem(Object o) {
		tree.setSelectionPath((TreePath) o);
		getModel().setSelectedItem(o);
	}

	public void updateUI() {
		ComboBoxUI cui = (ComboBoxUI) UIManager.getUI(this);
		if (cui instanceof MetalComboBoxUI) {
			cui = new MetalJTreeComboBoxUI();
		} 
		setUI(cui);
	}

	// UI Inner classes -- one for each supported Look and Feel
	class MetalJTreeComboBoxUI extends MetalComboBoxUI {
		protected ComboPopup createPopup() {
			return new TreePopup(comboBox);
		}
	}


	/**
	 * 
	 * Description: 树形结构而来的DefaultListCellRenderer
	 */
	class JTreeComboBoxRenderer extends DefaultListCellRenderer {
		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {
			if (value != null) {
				TreePath path = (TreePath) value;
				TreeNode node = (TreeNode) path.getLastPathComponent();
				value = node;
				TreeCellRenderer r = tree.getCellRenderer();
				JLabel lb = (JLabel) r.getTreeCellRendererComponent(tree,
						value, isSelected, false, node.isLeaf(), index,
						cellHasFocus);
				return lb;
			}
			return super.getListCellRendererComponent(list, value, index,
					isSelected, cellHasFocus);
		}
	}

	/**
	 * 测试
	 */
	public static void main(String args[]) {
		JFrame frame = new JFrame("JTreeComboBox 例子");
		frame.setSize(400, 320);
		Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
		frame.setLocation((d.width - frame.getSize().width) / 2,
				(d.height - frame.getSize().height) / 2);
		frame.getContentPane().setLayout(new FlowLayout());
		final DownTheTree box = new DownTheTree(new JTree());
		box.setPreferredSize(new Dimension(300, 21));
		frame.getContentPane().add(box);
		frame.setVisible(true);
	}
}

/**
 * <p>
 * Description: TreePopup
 * </p>
 */
@SuppressWarnings("serial")
class TreePopup extends JPopupMenu implements ComboPopup {
	protected DownTheTree comboBox;
	protected JScrollPane scrollPane;

	protected MouseMotionListener mouseMotionListener;
	protected MouseListener mouseListener;
	private MouseListener treeSelectListener = new MouseAdapter() {
		public void mouseReleased(MouseEvent e) {
			JTree tree = (JTree) e.getSource();
			TreePath tp = tree.getPathForLocation(e.getPoint().x,
					e.getPoint().y);
			if (tp == null) {
				return;
			}
			comboBox.setSelectedItem(tp);
			togglePopup();
			MenuSelectionManager.defaultManager().clearSelectedPath();
		}
	};

	public TreePopup(JComboBox comboBox) {
		this.comboBox = (DownTheTree) comboBox;
		setBorder(BorderFactory.createLineBorder(Color.black));
		setLayout(new BorderLayout());
		setLightWeightPopupEnabled(comboBox.isLightWeightPopupEnabled());
		JTree tree = this.comboBox.getTree();
		if (tree != null) {
			scrollPane = new JScrollPane(tree);
			scrollPane.setBorder(null);
			add(scrollPane, BorderLayout.CENTER);
			tree.addMouseListener(treeSelectListener);
		}
	}

	public void show() {
		updatePopup();
		show(comboBox, 0, comboBox.getHeight());
		comboBox.getTree().requestFocus();
	}

	public void hide() {
		setVisible(false);
		comboBox.firePropertyChange("popupVisible", true, false);
	}

	protected JList list = new JList();

	public JList getList() {
		return list;
	}

	public MouseMotionListener getMouseMotionListener() {
		if (mouseMotionListener == null) {
			mouseMotionListener = new MouseMotionAdapter() {
			};
		}
		return mouseMotionListener;
	}

	public KeyListener getKeyListener() {
		return null;
	}

	public void uninstallingUI() {
	}

	/**
	 * Implementation of ComboPopup.getMouseListener().
	 * 
	 * @return a <code>MouseListener</code> or null
	 * @see ComboPopup#getMouseListener
	 */
	public MouseListener getMouseListener() {
		if (mouseListener == null) {
			mouseListener = new InvocationMouseHandler();
		}
		return mouseListener;
	}

	protected void togglePopup() {
		if (isVisible()) {
			hide();
		} else {
			show();
		}
	}

	protected void updatePopup() {
		setPreferredSize(new Dimension(comboBox.getSize().width, 200));
		Object selectedObj = comboBox.getSelectedItem();
		if (selectedObj != null) {
			TreePath tp = (TreePath) selectedObj;
			((DownTheTree) comboBox).getTree().setSelectionPath(tp);
		}
	}

	protected class InvocationMouseHandler extends MouseAdapter {
		public void mousePressed(MouseEvent e) {
			if (!SwingUtilities.isLeftMouseButton(e) || !comboBox.isEnabled()) {
				return;
			}
			if (comboBox.isEditable()) {
				Component comp = comboBox.getEditor().getEditorComponent();
				if ((!(comp instanceof JComponent))
						|| ((JComponent) comp).isRequestFocusEnabled()) {
					comp.requestFocus();
				}
			} else if (comboBox.isRequestFocusEnabled()) {
				comboBox.requestFocus();
			}
			togglePopup();
		}
	}
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值