不繼承JComboBox的TreeComboBox

來源:互聯網
上載者:User

之前寫過一個繼承了JComboBox的TreeComboBox控制項,這樣會導致結構上的一些問題,比如說setModel(ComboBoxModel cbm)這個方法就失去意義了,後來重新寫了一個,UI難看點,可以自己改進,結構上就好多了,不說了,貼代碼:

import java.awt.BorderLayout;<br />import java.awt.Color;<br />import java.awt.Component;<br />import java.awt.Dimension;<br />import java.awt.event.ActionEvent;<br />import java.awt.event.ActionListener;<br />import java.awt.event.MouseAdapter;<br />import java.awt.event.MouseEvent;<br />import java.awt.event.MouseListener;<br />import javax.swing.BorderFactory;<br />import javax.swing.JFrame;<br />import javax.swing.JOptionPane;<br />import javax.swing.JPanel;<br />import javax.swing.JPopupMenu;<br />import javax.swing.JScrollPane;<br />import javax.swing.JTable;<br />import javax.swing.JTree;<br />import javax.swing.MenuSelectionManager;<br />import javax.swing.SwingConstants;<br />import javax.swing.event.ChangeEvent;<br />import javax.swing.event.ChangeListener;<br />import javax.swing.event.EventListenerList;<br />import javax.swing.plaf.basic.BasicArrowButton;<br />import javax.swing.table.DefaultTableCellRenderer;<br />import javax.swing.table.DefaultTableModel;<br />import javax.swing.table.TableCellRenderer;<br />import javax.swing.tree.DefaultMutableTreeNode;<br />import javax.swing.tree.DefaultTreeModel;<br />import javax.swing.tree.TreeNode;<br />import javax.swing.tree.TreePath;</p><p>/**<br /> * TreeComboBox,改進型的JComboBox,下拉的部分不再是一個JList,而是一個JTree<br /> * @author richer<br /> * */<br />public class TreeComboBox extends JPanel {<br />protected JTree tree;<br />// richer:顯示值用的table<br />protected JTable contentTable;<br />// 類比JComboBox的觸發按鈕<br />private BasicArrowButton arrowButton;<br />// 快顯功能表<br />private TreePopup treePopup;<br />private JScrollPane scrollPane;<br />protected EventListenerList changeList = new EventListenerList();<br />public TreeComboBox() {<br />this(new JTree());<br />}<br />public TreeComboBox(JTree tree) {<br />this(tree, false);<br />}<br />public TreeComboBox(JTree tree, boolean showRoot) {<br />this.setTree(tree);<br />if (!showRoot) {<br />tree.expandPath(new TreePath(tree.getModel().getRoot()));<br />tree.setRootVisible(false);<br />}<br />this.init();<br />}<br />private void init() {<br />this.setLayout(new BorderLayout());<br />DefaultTableModel tableModel = new ContentTableModel(1, 1);<br />contentTable = new JTable(tableModel);<br />contentTable.setRowHeight(24);<br />this.add(contentTable, BorderLayout.CENTER);<br />contentTable.addMouseListener(this.arrowButtonAction);<br />this.arrowButton = new BasicArrowButton(SwingConstants.SOUTH);<br />this.add(arrowButton, BorderLayout.EAST);<br />this.arrowButton.addMouseListener(this.arrowButtonAction);<br />this.scrollPane = new JScrollPane(this.tree);<br />this.setPreferredSize(new Dimension(this.scrollPane.getPreferredSize().width, getPreferredSize().height));<br />this.treePopup = new TreePopup(this);<br />}<br />public JTree getTree() {<br />return this.tree;<br />}<br />public void setTree(JTree tree) {<br />this.tree = tree;<br />}<br />/*<br /> * richer:獲得顯示用的table的渲染器<br /> */<br />public TableCellRenderer getCellRenderer() {<br />return this.contentTable.getColumnModel().getColumn(0).getCellRenderer();<br />}<br />/*<br /> * richer:設定table的渲染器<br /> */<br />public void setCellRenderer(TableCellRenderer cellRenderer) {<br />this.contentTable.getColumnModel().getColumn(0).setCellRenderer(cellRenderer);<br />}<br />/*<br /> * richer:返回選中的節點上包含的元素<br /> */<br />public Object getSelectedItem() {<br />Object selectedObj = null;<br />if (this.getSelectedTreeNode() != null) {<br />selectedObj = ((DefaultMutableTreeNode) this.getSelectedTreeNode()).getUserObject();<br />}<br />return selectedObj;<br />}<br />/*<br /> * richer:設定tree選中的節點元素<br /> */<br />public void setSelectedItem(Object object) {<br />DefaultTreeModel model = (DefaultTreeModel) this.tree.getModel();<br />DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();<br />DefaultMutableTreeNode leaf = root.getFirstLeaf();<br />do {<br />if (object.equals(leaf.getUserObject())) {<br />TreePath path = new TreePath(model.getPathToRoot(leaf));<br />this.tree.setSelectionPath(path);<br />this.contentTable.setValueAt(leaf.getUserObject(), 0, 0);<br />break;<br />}<br />} while ((leaf = leaf.getNextLeaf()) != null);<br />}<br />private TreeNode getSelectedTreeNode() {<br />TreePath treePath = this.tree.getSelectionPath();<br />if (treePath == null) {<br />return null;<br />} else {<br />return (TreeNode) treePath.getLastPathComponent();<br />}<br />}<br />private void setSelectedTreeNode(TreePath treePath) {<br />this.tree.setSelectionPath(treePath);<br />}</p><p>public void addChangeListener(ChangeListener aListener) {<br />changeList.add(ChangeListener.class, aListener);<br />}<br />public void removeChangeListener(ChangeListener aListener) {<br />changeList.remove(ChangeListener.class, aListener);<br />}<br />private void fireStateChanged() {<br />Object[] listeners = changeList.getListenerList();<br />ChangeEvent e = null;<br />for (int i = listeners.length - 2; i >= 0; i -= 2) {<br />if (listeners[i] == ChangeListener.class) {<br />if (e == null) {<br />e = new ChangeEvent(this);<br />}<br />((ChangeListener) listeners[i + 1]).stateChanged(e);<br />}<br />}<br />}<br />/*<br /> * richer:顯示用的table的model,讓table不可編輯<br /> */<br />class ContentTableModel extends DefaultTableModel {<br />public ContentTableModel(int rowCount, int columnCount) {<br />super(rowCount, columnCount);<br />}<br />public boolean isCellEditable(int row, int column) {<br />return false;<br />}<br />}<br />/*<br /> * richer:快顯功能表<br /> */<br />class TreePopup extends JPopupMenu {<br />protected TreeComboBox treeComboBox;<br />protected JScrollPane scrollPane;<br />private MouseListener treeSelectListener = new MouseAdapter() {<br />public void mouseReleased(MouseEvent e) {<br />JTree tree = (JTree) e.getSource();<br />TreePath treePath = tree.getPathForLocation(e.getPoint().x, e.getPoint().y);<br />if (treePath == null) {<br />return;<br />}<br />DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath.getLastPathComponent();<br />// richer:只有是樹葉才選中這個節點<br />if (node.isLeaf()) {<br />treeComboBox.setSelectedTreeNode(treePath);<br />contentTable.setValueAt(treeComboBox.getSelectedItem(), 0, 0);<br />togglePopup();<br />MenuSelectionManager.defaultManager().clearSelectedPath();<br />treeComboBox.fireStateChanged();<br />}<br />}<br />};<br />public TreePopup(TreeComboBox treeComboBox) {<br />this.treeComboBox = treeComboBox;<br />this.setBorder(BorderFactory.createLineBorder(Color.black));<br />this.setLayout(new BorderLayout());<br />this.setLightWeightPopupEnabled(JPopupMenu.getDefaultLightWeightPopupEnabled());<br />JTree tree = this.treeComboBox.getTree();<br />if (tree != null) {<br />this.scrollPane = new JScrollPane(tree);<br />this.scrollPane.setBorder(null);<br />this.add(this.scrollPane, BorderLayout.CENTER);<br />tree.addMouseListener(this.treeSelectListener);<br />}<br />}<br />private void showPopup() {<br />this.updatePopup();<br />this.show(treeComboBox, 0, treeComboBox.getHeight());<br />}<br />private void hidePopup() {<br />this.setVisible(false);<br />this.treeComboBox.firePropertyChange("popupVisible", true, false);<br />}<br />public void togglePopup() {<br />if (this.isVisible()) {<br />this.hidePopup();<br />} else {<br />this.showPopup();<br />}<br />}<br />protected void updatePopup() {<br />this.setPreferredSize(new Dimension(this.treeComboBox.getSize().width, 140));<br />TreeNode selectedObj = this.treeComboBox.getSelectedTreeNode();<br />if (selectedObj != null) {<br />TreePath path = new TreePath(((DefaultTreeModel) this.treeComboBox.getTree().getModel()).getPathToRoot(selectedObj));<br />this.treeComboBox.getTree().setSelectionPath(path);<br />}<br />}<br />}<br />MouseListener arrowButtonAction = new MouseAdapter() {<br />public void mouseClicked(MouseEvent e) {<br />treePopup.togglePopup();<br />}<br />};<br />public static void main(String args[]) {<br />final JFrame frame = new JFrame("TreeComboBox Demo");<br />frame.getContentPane().setLayout(new BorderLayout());<br />BasicArrowButton arrowButton = new BasicArrowButton(SwingConstants.SOUTH);<br />//frame.getContentPane().add(arrowButton, BorderLayout.SOUTH);<br />TreeComboBox tcb = new TreeComboBox();<br />frame.getContentPane().add(tcb, BorderLayout.SOUTH);<br />final FRTreeComboBox frtcb = new FRTreeComboBox(new JTree());<br />frtcb.addChangeListener(new ChangeListener(){<br />public void stateChanged(ChangeEvent e) {<br />JOptionPane.showConfirmDialog(frame, frtcb.getSelectedItem());<br />}<br />});<br />TableCellRenderer cellRenderer = new DefaultTableCellRenderer() {<br />public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {<br />Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);<br />if ("soccer".equals(value)) {<br />table.setValueAt("haha", row, column);<br />}<br />return cell;<br />}<br />};<br />frtcb.setCellRenderer(cellRenderer);<br />frame.getContentPane().add(frtcb, BorderLayout.NORTH);<br />arrowButton.addActionListener(new ActionListener() {<br />public void actionPerformed(ActionEvent e) {<br />JOptionPane.showConfirmDialog(frame, frtcb.getSelectedItem());<br />}<br />});<br />frame.setSize(300, 300);<br />frame.setVisible(true);<br />}<br />}<br />

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.