2012-01-12 37 views
7

liên quan đến chủ đề Jtable as a Jtree Node tôi đặt JTable để JTree, nhưng JTree Xem không hiển thị đúng trên start_up, làm thế nào tôi có thể setPreferredSize cho JTable, vì PreferredScrollableViewportSize co JTable với rendering TableHeader + một , một vẫn ẩn, nhưng sau khi mở rộng Node (s) thay đổi TreeRenderer và sơn lại các setPreferredSize với dự kiến ​​DimensionĐặt JTable trong 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); 
      } 
     }); 
    } 
} 

Trả lời

4

Hãy loại bỏ ScrollPane, đó là rối loạn chức năng nào (cho đến nay tôi đồng ý với Russell :-) và thêm bảng và tiêu đề của nó vào bảng, sử dụng một LayoutManager thích hợp:

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

có thể bạn sẽ cần phải chỉnh hình ảnh một chút, biên giới trái và đỉnh dòng bị thiếu - không hoàn toàn chắc chắn thành phần nào vẽ chúng bình thường, có thể là thứ e ScrollPane

Sửa

Quên: lý do truy vấn prefSize của ScrollPane trong việc tính toán kích thước yêu cầu (thực hiện trong các đại biểu ui, cụ thể là VariableHeightLayoutCache) của các thành phần dựng hình là ScrollPane chưa được cấu hình với tiêu đề. Truy vấn xảy ra trước khi bảng điều khiển được thêm vào rendererPane, cấu hình hoàn chỉnh được thực hiện trong addNotify của bảng chỉ xảy ra sau khi thêm bảng vào cấu trúc phân cấp

+0

không tôi cần có JScrollPane theo mặc định, hmmm loại bỏ JScrollPane, tôi nghĩ rằng đây là đề nghị sai, bởi vì JTable này có thể có một Row cùng như hàng 5T, không quan trọng tôi đã quên http://stackoverflow.com/questions/7369814/why-does-the-jtable-header-not-appear-in-the-image, cảm ơn bạn – mKorbel

3

Bạn có thể chỉ thoát khỏi ScrollPane và đặt ra các tiêu đề và bảng trong bảng điều khiển trực tiếp (với một LayoutManager null vì vậy bạn có thể kiểm soát tất cả mọi thứ cho mình):

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 cho bố cục rỗngManager – kleopatra

+0

đồng ý với @kleopatra. là) table.getTableHeader(). getPreferredSize(); +1 – mKorbel

+0

@kleopatra: Thông thường, một 'LayoutManager' sẽ là một hack, nhưng cho rằng đây là" con dấu cao su "hơn là một thành phần thực sự sống trong hệ thống phân cấp, tôi nghĩ không có hại gì. –

Các vấn đề liên quan