JTree带有选项卡式面板作为树节点

时间:2014-02-13 06:09:06

标签: java swing jtree

我有一个JTree。树节点应包含带选项卡的面板。选项卡应包含带滚动窗格的textarea。问题是我能够在树节点中添加带有选项卡的面板,但问题是我无法从一个选项卡转到另一个选项卡。面板似乎已禁用。任何帮助或建议表示赞赏。提前致谢。以下是我的代码:

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import java.util.Random;

import javax.swing.AbstractCellEditor;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;

public class ModifiedTreePanel  
{  
    Random seed;  

    public ModifiedTreePanel()  
    {  
        seed = new Random();  

        // south section  
        final JLabel colorLabel = new JLabel();  
        colorLabel.setHorizontalAlignment(JLabel.CENTER);  
        Dimension d = colorLabel.getPreferredSize();  
        d.height = 25;  
        colorLabel.setPreferredSize(d);  

        // center section  
        JTree tree = createTree();  
        tree.setCellRenderer(new CustomRenderer(tree));
        tree.getSelectionModel().addTreeSelectionListener(  
                                         new TreeSelectionListener()  
        {  
            public void valueChanged(TreeSelectionEvent e)  
            {  

            }  
        });  

        JFrame f = new JFrame();  
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
        f.add(new JScrollPane(tree));  
        f.add(colorLabel, "South");  
        f.setSize(400,400);  
        f.setLocation(200,200);  
        f.setVisible(true);  
    }  

    protected JComponent createTabbedPanel (String text) {
        JPanel panel = new JPanel(new GridLayout(1, 1));

        JTabbedPane tabbedPane = new JTabbedPane();

        JComponent panel1 = makeTextPanel("Panel #1");
        tabbedPane.addTab("Tab 1", panel1);
        panel1.setPreferredSize(new Dimension(200, 100));

        JComponent panel2 = makeTextPanel("Panel #2");
        tabbedPane.addTab("Tab 2", panel2);

        JComponent panel3 = makeTextPanel("Panel #3");
        tabbedPane.addTab("Tab 3", panel3);

        panel.add(tabbedPane);
        tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);

        panel.setEnabled(true);
        return panel;
    }

    protected JComponent makeTextPanel (String text) {
            JPanel panel = new JPanel(false);
            JLabel filler = new JLabel(text);
            filler.setHorizontalAlignment(JLabel.CENTER);
            panel.setLayout (new GridLayout(1,1));
            panel.add(filler);
            return panel;
    }

    private JTree createTree()  
    {  
        int children = 4;  
        int grandChildren = 1;  

        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
        DefaultMutableTreeNode node;  
        for(int j = 0; j < children; j++)  
        {  
            node = new DefaultMutableTreeNode("Child-"+String.valueOf(j));

            root.add(node);  
                for(int k = 0; k < grandChildren; k++)  
                    node.add(new DefaultMutableTreeNode(createTabbedPanel("Grand-" + String.valueOf(k))));  
        }  
        DefaultTreeModel model = new DefaultTreeModel(root);  
        return new JTree(model);  
    }  

    public static void main(String[] args)  
    {  
        new ModifiedTreePanel();  
    }  
}  

class CustomRenderer extends AbstractCellEditor 
    implements TreeCellRenderer, TreeCellEditor  
{     

    final JTree tree;

    public CustomRenderer (JTree tree) {
        this.tree = tree;
    }


    public Component getTreeCellRendererComponent(JTree tree,  
                                                  Object value,  
                                                  boolean selected,  
                                                  boolean expanded,  
                                                  boolean leaf,  
                                                  int row,  
                                                  boolean hasFocus)  
    {  
        Object nodeObject = ((DefaultMutableTreeNode)value).getUserObject();
        if (nodeObject instanceof JPanel){
            JPanel panel = (JPanel) nodeObject;    
            panel.setPreferredSize(new Dimension(200, 100)); 
            return panel;
        } else{
            return new JLabel(nodeObject.toString());
        }

    }

    public Component getTreeCellEditorComponent(
            JTree tree, Object value, boolean selected,
            boolean expanded, boolean leaf, int row) {
        return getTreeCellRendererComponent(
                tree, value, true, expanded, leaf, row, true);
    }

    public boolean isCellEditable(final EventObject event) {
        if (!(event instanceof MouseEvent)) {
            return false;
        }

        final MouseEvent mouseEvent = (MouseEvent) event;
        final TreePath path = tree.getPathForLocation(
                mouseEvent.getX(), mouseEvent.getY());
        if (path == null) {
            return false;
        }

        Object node = path.getLastPathComponent();
        if (node == null || (!(node instanceof DefaultMutableTreeNode))) {
            return false;
        }

        DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
        Object userObject = treeNode.getUserObject();

        return (userObject instanceof JPanel);
    }


    @Override
    public Object getCellEditorValue() {
        return null;
    }

}

1 个答案:

答案 0 :(得分:2)

单元格渲染器是“快照”并且不是真实的实时组件

请参阅Concepts: Editors and Renderers

每次根据原始节点的内容激活编辑器时,您必须为节点提供自定义编辑器并构建其内容。

您不应该使用组件作为节点的userObject属性,而是将信息传递给节点,渲染器和编辑器都可以使用它来构建各自的视图。

看看:

举个例子......