群組控制項TreeComboBox,下拉框的選項為一棵樹!

來源:互聯網
上載者:User

在項目中需要使用下拉一棵樹來選擇的空間,參考了下別人的自己改進了不少,使用方法就是:

TreeComboBox tcb = new TreeComboBox();就可以建立一個最簡單的下拉樹了,下拉的tree就是最原始的tree。

 

TreeComboBox的原始碼如下:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.IllegalComponentStateException;
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.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.DefaultMutableTreeNode;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import com.sun.java.swing.plaf.motif.MotifComboBoxUI;
import com.sun.java.swing.plaf.windows.WindowsComboBoxUI;

public class TreeComboBox extends JComboBox {
    /**
     * 顯示用的樹
     */
    private JTree tree;

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

    public TreeComboBox(JTree tree) {
        this(tree, null);
    }
   
    public TreeComboBox(JTree tree, TreeCellRenderer treeCellRenderer){
        this(tree, treeCellRenderer, false);
    }
   
    /**
     * 不顯示根節點的TreeComboBox
     * @param tree
     * @param treeCellRenderer
     * @param showRoot
     */
    public TreeComboBox(JTree tree, TreeCellRenderer treeCellRenderer, boolean showRoot){
        this.setTree(tree);
        tree.setCellRenderer(treeCellRenderer);
        if (!showRoot){
            tree.expandPath(new TreePath(tree.getModel().getRoot()));
            tree.setRootVisible(false);
        }
    }
    /**
     * 設定樹
     * @param tree JTree
     */
    public void setTree(JTree tree) {
        this.tree = tree;
        if (tree != null) {       
            this.setSelectedItem(tree.getSelectionPath());           
            this.setRenderer(new TreeComboBoxRenderer());
        }
        this.updateUI();
    }

    /**
     * 取得樹
     * @return JTree
     */
    public JTree getTree() {
        return tree;
    }
  
    /**
     * 設定當前選擇的樹路徑
     * @param o Object
     */
    public void setSelectedItem(Object o) {
        this.tree.setSelectionPath((TreePath) o);
        this.getModel().setSelectedItem(o);
    }
   
    /**
     * 獲得當前選中的節點的值
     * @return o Object
     */
    public Object getSelectedObject(){
        TreePath treePath = (TreePath)this.getSelectedItem();
        if (treePath == null){
            return null;
        }
        DefaultMutableTreeNode node = (DefaultMutableTreeNode)treePath.getLastPathComponent();
        return node.getUserObject();
    }

   
    public void updateUI() {
        ComboBoxUI cui = (ComboBoxUI) UIManager.getUI(this);
        if (cui instanceof MetalComboBoxUI) {
            cui = new MetalTreeComboBoxUI();
        } else if (cui instanceof MotifComboBoxUI) {
            cui = new MotifTreeComboBoxUI();
        } else if (cui instanceof WindowsComboBoxUI) {
            cui = new WindowsTreeComboBoxUI();
        } else {
            cui = new FRTreeComboBoxUI();
        }
        setUI(cui);
    }

    // richer:皮膚

    class FRTreeComboBoxUI extends TinyComboBoxUI {
        protected ComboPopup createPopup() {           
            return new TreePopup(comboBox);
        }
    }

    class MetalTreeComboBoxUI extends MetalComboBoxUI {
        protected ComboPopup createPopup() {
            return new TreePopup(comboBox);
        }
    }

    class WindowsTreeComboBoxUI extends WindowsComboBoxUI {
        protected ComboPopup createPopup() {
            return new TreePopup(comboBox);
        }
    }

    class MotifTreeComboBoxUI extends MotifComboBoxUI {
        protected ComboPopup createPopup() {
            return new TreePopup(comboBox);
        }
    }

    private class TreeComboBoxRenderer 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 treeCellRenderer = tree.getCellRenderer();
                JLabel lb = (JLabel) treeCellRenderer.getTreeCellRendererComponent(tree, value, isSelected, false, node.isLeaf(), index, cellHasFocus);
                return lb;
            }
            return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        }
    }   
}

/*
 * richer:彈出部分
 */
class TreePopup extends JPopupMenu implements ComboPopup {
    protected TreeComboBox 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 treePath = tree.getPathForLocation(e.getPoint().x, e.getPoint().y);
            if (treePath == null){
                return;
            }
            DefaultMutableTreeNode node = (DefaultMutableTreeNode)treePath.getLastPathComponent();
            // richer:只有是樹葉才選中這個節點,這裡可以根據需要自己定義
            if (node.isLeaf()){
                comboBox.setSelectedItem(treePath);
                togglePopup();
                MenuSelectionManager.defaultManager().clearSelectedPath();
            }
        }
    };

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

    public void show() {
        this.updatePopup();
        try {
            this.show(comboBox, 0, comboBox.getHeight());
        } catch (IllegalComponentStateException e) {
            //richer:這裡有可能會拋出一個異常,可以不用處理
        }
        this.comboBox.getTree().requestFocus();
    }

    public void hide() {
        this.setVisible(false);
        this.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 (this.isVisible()) {
            this.hide();
        } else {
            this.show();
        }
    }

    protected void updatePopup() {
        this.setPreferredSize(new Dimension(this.comboBox.getSize().width, 120));
        Object selectedObj = this.comboBox.getSelectedItem();
        if (selectedObj != null) {
            TreePath tp = (TreePath) selectedObj;
            ((TreeComboBox) this.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();
        }
    }
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.