2012-01-12 14 views
7

in connessione con filo Jtable as a Jtree Node ho messo JTable a Jtree, ma JTree View non è reso correttamente su START_UP, come posso setPreferredSize per JTable, perché PreferredScrollableViewportSize rimpiccioliti JTable del rendering TableHeader + uno , uno rimanere nascosto, ma dopo l'espansione del nodo (s) cambio TreeRenderer e riverniciare la setPreferredSize per l'atteso DimensionMettere JTable nel JTree

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

risposta

4

Sbarazzarsi della ScrollPane, è disfunzionale in ogni caso (finora sono d'accordo con Russell :-) e aggiungere la tabella e il suo colpo di testa al pannello, utilizzando un LayoutManager appropriato:

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

avrete probabilmente bisogno di modificare le immagini un po ', il bordo sinistro e superiore mancano le linee - non del tutto sicuro di quale componente le dipinga normalmente, potrebbe essere th e ScrollPane

Modifica

dimenticato: la ragione interrogazione prefSize del ScrollPane nel calcolo del formato richiesto (fatto nel delegato ui, vale a dire la VariableHeightLayoutCache) del componente rendering è che la ScrollPane non ancora configurata con il intestazione. La query avviene prima che il pannello venga aggiunto al rendererPane, la configurazione completa viene eseguita nella tabella addNotify che avviene solo dopo l'aggiunta del pannello alla gerarchia

+0

non avevo bisogno di JScrollPane per impostazione predefinita, hmmm rimuovi JScrollPane, penso che questo sia un suggerimento sbagliato, perché questo JTable può avere una stessa riga come 5T Rows, non importa ho dimenticato per http://stackoverflow.com/questions/7369814/why-does-the-jtable-header-not-appear-in-the-image, grazie – mKorbel

3

Si potrebbe semplicemente sbarazzarsi di ScrollPane e lay out l'intestazione e la tabella nel pannello direttamente (con un null LayoutManager in modo da poter controllare tutto da soli):

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

-1 per layout nullManager – kleopatra

+0

concordato con @kleopatra ma grazie per (resto is) table.getTableHeader(). getPreferredSize(); +1 – mKorbel

+0

@kleopatra: Normalmente un 'LayoutManager' nullo sarebbe un hack, ma dato che questo è un" timbro di gomma "piuttosto che un componente reale che vive nella gerarchia, penso che non ci siano danni. –