2009-09-17 18 views
4

我有一種不尋常的情況,我需要有一個JTree,每個節點包含2個複選框和一個標籤(可以添加一個偵聽器來告知何時可以選中任何複選框) 。我還需要根節點具有相同的佈局(我假設這意味着創建一個帶有2個JCheckBox和JLabel的JPanel),並且可以選中樹中所有複選框(如果選中了根目錄中的複選框)。使用JCheckBox幫助製作JTree

任何指導或示例?我已經檢查過關於這裏以及相關示例的以前的問題......其中一些允許我開始讓樹「看起來」,但沒有給我一個實現其背後動作的方向。

謝謝!

回答

5

這可能是看看老JTreeTable代碼,這將給你在第一列渲染樹的好時機,並渲染每一列單元格中的自由您希望的樹節點的權利,在您的情況下放入複選框和標籤,並允許您像以前一樣讓TableCellEditor與您的JTable一起工作。一個警告是,雖然該鏈接中的代碼有效,但它有點複雜。

還有一個選擇。我已經演示了NetBeans提供的應該更好的樹形表實現(稱爲Outline)(儘管您不需要使用NetBeans IDE進行開發,只需要該jar)即可。​​表示啓動起來有多容易。

我能夠在大約30分鐘(我打字速度很慢)的情況下模擬Eclipse中的Outline樹表的一個快速示例(將org-netbeans-swing-outline.jar導入到我的項目中):

private void buildFrame() { 
    frame = new JFrame("Demo"); 
    frame.setSize(300, 300); 
    addStuffToFrame(); 
    frame.setVisible(true); 

} 


private void addStuffToFrame() { 
    MyTreeNode top = new MyTreeNode("top"); 
    createNodes(top); 
    DefaultTreeModel model = new DefaultTreeModel(top);  
    //here are the netBeans tree table classes 
    OutlineModel outlineModel = 
      DefaultOutlineModel.createOutlineModel(model, new MyRowModel()); 
    Outline outline = new Outline(); 
    outline.setRootVisible(true); 
    outline.setModel(outlineModel); 
    frame.getContentPane().add(new JScrollPane(outline)); 
} 

private void createNodes(MyTreeNode top) { 
    MyTreeNode child = new MyTreeNode("child 2"); 
    top.add(new MyTreeNode("child 1")); 
    child.add(new MyTreeNode("g-child1")); 
    child.add(new MyTreeNode("g-child2")); 
    child.add(new MyTreeNode("g-child3")); 
    top.add(child); 
    top.add(new MyTreeNode("child3")); 
    top.add(new MyTreeNode("child4")); 

} 

我創建了一個樹節點來保存Boolean原來決心與JTable的內置複選框渲染mechnanism以及互操作。

public class MyTreeNode extends DefaultMutableTreeNode { 
    Boolean data1 = null; 
    Boolean data2 = null; 
    String name = null; 
    MyTreeNode (String name) { 
     this.name=name; 
    } 

    void setData1(Boolean val) {data1=val;} 
    void setData2(Boolean val) {data2=val;} 
    Boolean getData1() {return data1;} 
    Boolean getData2() {return data2;} 
    String getName() {return name;} 

} 

在NetBeans RowModel的關鍵是製作的,而不是一個簡單的JTree這樣的表:

public class MyRowModel implements RowModel { 

    public Class getColumnClass(int col) { 
     switch (col) { 
     case 0: return String.class; 
     case 1: return Boolean.class; //these return class definitions will 
     case 2: return Boolean.class; //trigger the checkbox rendering 
     default:return null;  
     } 
    } 

    public int getColumnCount() { 
     return 3; 
    } 

    public String getColumnName(int col) { 
     return ""; 
    } 

    public Object getValueFor(Object node, int col) { 
     MyTreeNode n = (MyTreeNode)node; 
     switch (col) { 
     case 0: return n.getName(); 
     case 1: return n.getData1(); 
     case 2: return n.getData2(); 
     default:return null; 
     } 
    } 

    public boolean isCellEditable(Object node, int col) { 
     return col > 0; 
    } 

    public void setValueFor(Object node, int col, Object val) { 
     MyTreeNode n = (MyTreeNode)node; 
     if (col == 1)  {n.setData1((Boolean)val);} 
     else if (col == 2) {n.setData2((Boolean)val);} 
     //EDIT: here is a recursive method to set all children 
     //  selected for one of the two checkboxes as it is 
     //  checked by the parent 
     for (Enumeration children = n.children(); 
         children.hasMoreElements();) { 
      MyTreeNode child = (MyTreeNode) children.nextElement(); 
      setValueFor(child, col, val); 
     } 


    } 

} 

這裏是成品,雖然簡單,產品:

alt text http://img17.imageshack.us/img17/6643/picture1hz.png

我更新了setValueFor方法來遍歷節點的子節點,並且在父節點被修改時將複選框設置爲選定或取消選擇d。

0

不清楚buildFrame(),addStuffToFrame()和createNodes()方法在哪裏。我將它們全部放入我創建的擴展JFrame的OutlineJFrame類中,並刪除了「框架」。前言在哪裏出現過。然後在我的項目的main()方法中,它只創建了一個OutlineJFrame對象並將其可見設置爲true。當它跑了,我有一個可調整大小但空的窗口。行在哪裏?節點在哪裏?

然後我問NetBeans專家Geertjan,我做錯了什麼,他給我重寫了一個。但它有相同的行爲。

但我知道我的java很好,因爲我做的另一個演示項目(FileTreeJFrame)顯示outline.java對象就好了。

+0

你仍然需要調用'addStuffToFrame()'方法。這是設置「Outline」並添加到「JFrame」中進行顯示的東西。請注意,我放在那裏的方法只是爲了我的演示應用程序的目的。 – akf 2010-01-15 17:00:47