简体   繁体   English

把JTable放在JTree中

[英]Put JTable in the JTree

in connection with thread Jtable as a Jtree Node I put JTable to JTree, but JTree View isn't rendered correctly on start_up, how can I setPreferredSize for JTable , because PreferredScrollableViewportSize shrinked JTable with rendering TableHeader + one Row , one Row remain hidden, but after expanding Node(s) TreeRenderer change and repaint the setPreferredSize to the expected Dimension 与螺纹连接为一个JTree节点的JTable我把JTable中JTree的,但JTree观点是不正确呈现在START_UP,我怎么能setPreferredSizeJTable ,因为PreferredScrollableViewportSize收缩JTable与渲染TableHeader +一个Row ,一个Row仍然隐藏,但在扩展Node之后,TreeRenderer会更改并将setPreferredSize重新绘制到预期的Dimension

在此输入图像描述在此输入图像描述

import java.awt.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.*;

public class TreeWithTableRenderer extends JFrame {

    private static final long serialVersionUID = 1L;
    private JTree tree;

    public TreeWithTableRenderer() {
        DefaultMutableTreeNode AA1 = new DefaultMutableTreeNode("AA1");
        DefaultMutableTreeNode AA2 = new DefaultMutableTreeNode("AA2");
        DefaultMutableTreeNode A = new DefaultMutableTreeNode("A");
        A.add(AA1);
        A.add(AA2);
        DefaultMutableTreeNode BB1 = new DefaultMutableTreeNode("BB1");
        DefaultMutableTreeNode BB2 = new DefaultMutableTreeNode("BB2");
        DefaultMutableTreeNode B = new DefaultMutableTreeNode("B");
        B.add(BB1);
        B.add(BB2);
        DefaultMutableTreeNode CC1 = new DefaultMutableTreeNode("CC1");
        DefaultMutableTreeNode CC2 = new DefaultMutableTreeNode("CC2");
        DefaultMutableTreeNode C = new DefaultMutableTreeNode("C");
        C.add(CC1);
        C.add(CC2);
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
        root.add(A);
        root.add(B);
        root.add(C);
        tree = new JTree(root);
        tree.setCellRenderer(new MyTableInTreeCellRenderer());
        tree.setRowHeight(0);
        JScrollPane jsp = new JScrollPane(tree);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(jsp, BorderLayout.CENTER);
        pack();
        setLocationRelativeTo(null);
    }

    class MyTableInTreeCellRenderer extends JPanel implements TreeCellRenderer {

        private static final long serialVersionUID = 1L;
        private JTable table;

        public MyTableInTreeCellRenderer() {
            super(new BorderLayout());
            table = new JTable();
            JScrollPane scrollPane = new JScrollPane(table);
            add(scrollPane);
        }

        public Component getTreeCellRendererComponent(JTree tree, Object value,
                boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            final String v = (String) ((DefaultMutableTreeNode) value).getUserObject();
            table.setModel(new DefaultTableModel() {

                private static final long serialVersionUID = 1L;

                @Override
                public int getRowCount() {
                    return 2;
                }

                @Override
                public int getColumnCount() {
                    return 2;
                }

                @Override
                public Object getValueAt(int row, int column) {
                    return v + ":" + row + ":" + column;
                }
            });
            table.setPreferredScrollableViewportSize(table.getPreferredSize());
            return this;
        }
    }

    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                new TreeWithTableRenderer().setVisible(true);
            }
        });
    }
}

Get rid of the scrollPane, it's dysfunctional anyway (so far I agree with Russell :-) and add the table and its header to the panel, using an appropriate LayoutManager: 摆脱scrollPane,它无论如何都是功能失调的(到目前为止我同意Russell :-)并使用适当的LayoutManager将表及其标题添加到面板:

public MyTableInTreeCellRenderer() {
    super();
    setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    table = new JTable();
    add(table.getTableHeader());
    add(table);
}

you'll probably need to tweak the visuals a bit, the left and top border lines are missing - not entirely sure which component paints them normally, could be the scrollPane 你可能需要稍微调整视觉效果,左边和上边框线丢失 - 不完全确定哪个组件正常绘制它们,可能是scrollPane

Edit 编辑

Forgot: the reason querying the scrollPane's prefSize in calculating the required size (done in the ui delegate, namely the VariableHeightLayoutCache) of the rendering component is that the scrollPane not yet configured with the header. 忘记:在计算渲染组件所需的大小(在ui委托中完成,即VariableHeightLayoutCache)时查询scrollPane的prefSize的原因是scrollPane尚未配置标题。 The query happens before the panel is added to the rendererPane, the complete configuration is done in the table's addNotify which happens only after adding the panel to the hierarchy 在将面板添加到rendererPane之前进行查询,完成配置在表的addNotify中完成,只有在将面板添加到层次结构后才会发生

You might just get rid of the ScrollPane and lay out the header and table in the panel directly (with a null LayoutManager so you can control everything yourself): 您可能只是摆脱ScrollPane并直接在面板中布置标题和表格(使用null LayoutManager,这样您就可以自己控制所有内容):

static class TableTreeCellRenderer extends JPanel implements TreeCellRenderer {
    private final JTable table;

    TableTreeCellRenderer() {
        table = new JTable();
        setLayout(null);
        add(table.getTableHeader());
        add(table);
    }

    public Dimension getPreferredSize() {
        Dimension headerSize = table.getTableHeader().getPreferredSize();
        Dimension tableSize = table.getPreferredSize();

        return new Dimension(Math.max(headerSize.width, tableSize.width),
                headerSize.height + tableSize.height);
    }

    public void setBounds(int x, int y, int width, int height) {
        super.setBounds(x, y, width, height);
        int headerHeight = table.getTableHeader().getPreferredSize().height;
        table.getTableHeader().setBounds(0, 0, width, headerHeight);
        table.setBounds(0, headerHeight, width, height - headerHeight);
    }

    public Component getTreeCellRendererComponent(JTree tree, Object value,
            boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
        final String v = (String) ((DefaultMutableTreeNode) value).getUserObject();
        table.setModel(new DefaultTableModel(new Object[][] { 
                { v + "0", "1" },
                { v + "2", "3" }
        }, new Object[] { "id", "value" } ));
        invalidate();
        return this;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM