Ponga JTable en el JTree

en conexión con el subproceso Jtable como un nodo Jtree pongo JTable en JTree, pero JTree View no se representa correctamente en start_up, cómo puedo setPreferredSize para JTable , porque PreferredScrollableViewportSize encogió JTable con la representación TableHeader + una Row , una Row permanece oculta, pero después de expandir Nodo (s) TreeRenderer cambiar y setPreferredSize a pintar el setPreferredSize a la Dimension esperada

enter image description hereenter image description here

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

Deshazte del scrollPane, de todas maneras es disfuncional (hasta ahora estoy de acuerdo con Russell 🙂 y agrego la tabla y su encabezado al panel, usando un LayoutManager apropiado:

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

es probable que necesites modificar un poco las imágenes, faltan las líneas frontales izquierda y superior; no está del todo seguro qué componente las pinta normalmente, podría ser el scrollPane

Editar

Olvidó: el motivo por el que se consulta el prefSize de scrollPane al calcular el tamaño requerido (hecho en el delegado ui, concretamente el VariableHeightLayoutCache) del componente de representación es que el scrollPane aún no está configurado con el encabezado. La consulta ocurre antes de que el panel se agregue al rendererPane, la configuración completa se realiza en el addNotify de la tabla, lo que ocurre solo después de agregar el panel a la jerarquía.

Puede deshacerse del ScrollPane y disponer el encabezado y la tabla en el panel directamente (con un LayoutManager null para que pueda controlarlo todo):

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