当我们在进行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();
}
}
}
因篇幅问题不能全部显示,请点此查看更多更全内容