7

JtreeノードとしてのスレッドJtableに関連して、 JTableをJTreeに配置しましたが、JTreeビューがstart_upで正しくレンダリングされません。レンダリングで縮小されたsetPreferredSizeためJTable、1つは非表示のままですが、ノードを展開した後、TreeRendererが変更されます。期待どおりに塗り直しますPreferredScrollableViewportSizeJTableTableHeaderRowRowsetPreferredSizeDimension

ここに画像の説明を入力してください ここに画像の説明を入力してください

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);
            }
        });
    }
}
4

2 に答える 2

4

scrollPane を取り除きます。とにかく機能不全です (これまでのところ私は Russell に同意します :-) 適切な LayoutManager を使用して、テーブルとそのヘッダーをパネルに追加します。

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

おそらく、ビジュアルを少し調整する必要があります。左と上の境界線がありません。どのコンポーネントがそれらを正常に描画するのか完全にはわかりません。scrollPane である可能性があります。

編集

忘れました: レンダリング コンポーネントの必要なサイズ (UI デリゲート、つまり VariableHeightLayoutCache で実行) を計算する際に scrollPane の prefSize を照会する理由は、scrollPane がまだヘッダーで構成されていないためです。クエリは、パネルが rendererPane に追加される前に発生します。完全な構成は、パネルを階層に追加した後にのみ発生するテーブルの addNotify で行われます。

于 2012-01-13T12:03:32.430 に答える
3

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;
    }
}
于 2012-01-13T01:55:16.643 に答える