使用一個JTree可以簡單地像下面這樣表示:
add(new JTree(
new Object[] {"this", "that", "other"}));
這個程序顯示了一個原始的樹狀物。樹狀物的API是非常巨大的,可是——當然是在Swing中的巨大。它表明我們可以做有關樹狀物的任何事,但更復雜的任務可能需要不少的研究和試驗。幸運的是,在庫中提供了一個妥協:“默認的”樹狀物組件,通常那是我們所需要的。因此大多數的時間我們可以利用這些組件,並且只在特殊的情況下我們需要更深入的研究和理解。
下面的例子使用了“默認”的樹狀物組件在一個程序片中顯示一個樹狀物。當我們按下按鈕時,一個新的子樹就被增加到當前選中的結點下(如果沒有結點被選中,就用根結節):
//: Trees.java // Simple Swing tree example. Trees can be made // vastly more complex than this. package c13.swing; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.tree.*; // Takes an array of Strings and makes the first // element a node and the rest leaves: class Branch { DefaultMutableTreeNode r; public Branch(String[] data) { r = new DefaultMutableTreeNode(data[0]); for(int i = 1; i < data.length; i++) r.add(new DefaultMutableTreeNode(data[i])); } public DefaultMutableTreeNode node() { return r; } } public class Trees extends JPanel { String[][] data = { { "Colors", "Red", "Blue", "Green" }, { "Flavors", "Tart", "Sweet", "Bland" }, { "Length", "Short", "Medium", "Long" }, { "Volume", "High", "Medium", "Low" }, { "Temperature", "High", "Medium", "Low" }, { "Intensity", "High", "Medium", "Low" }, }; static int i = 0; DefaultMutableTreeNode root, child, chosen; JTree tree; DefaultTreeModel model; public Trees() { setLayout(new BorderLayout()); root = new DefaultMutableTreeNode("root"); tree = new JTree(root); // Add it and make it take care of scrolling: add(new JScrollPane(tree), BorderLayout.CENTER); // Capture the tree's model: model =(DefaultTreeModel)tree.getModel(); JButton test = new JButton("Press me"); test.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ if(i < data.length) { child = new Branch(data[i++]).node(); // What's the last one you clicked? chosen = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); if(chosen == null) chosen = root; // The model will create the // appropriate event. In response, the // tree will update itself: model.insertNodeInto(child, chosen, 0); // This puts the new node on the // currently chosen node. } } }); // Change the button's colors: test.setBackground(Color.blue); test.setForeground(Color.white); JPanel p = new JPanel(); p.add(test); add(p, BorderLayout.SOUTH); } public static void main(String args[]) { Show.inFrame(new Trees(),200,500); } } ///:~
最重要的類就是分支,它是一個工具,用來獲取一個字符串數組並為第一個字符串建立一個DefaultMutableTreeNode作為根,其余在數組中的字符串作為葉。然後node()方法被調用以產生“分支”的根。樹狀物類包括一個來自被制造的分支的二維字符串數組,以及用來統計數組的一個靜態中斷i。DefaultMutableTreeNode對象控制這個結節,但在屏幕上表示的是被JTree和它的相關(DefaultTreeModel)模式所控制。注意當JTree被增加到程序片時,它被封裝到JScrollPane中——這就是它全部提供的自動滾動。
JTree通過它自己的模型來控制。當我們修改這個模型時,模型產生一個事件,導致JTree對可以看見的樹狀物完成任何必要的升級。在init()中,模型由調用getModel()方法所捕捉。當按鈕被按下時,一個新的分支被創建了。然後,當前選擇的組件被找到(如果沒有選擇就是根)並且模型的insertNodeInto()方法做所有的改變樹狀物和導致它升級的工作。
大多數的時候,就像上面的例子一樣,程序將給我們在樹狀物中所需要的一切。不過,樹狀物擁有力量去做我們能夠想像到的任何事——在上面的例子中我們到處都可看到“default(默認)”字樣,我們可以取代我們自己的類來獲取不同的動作。但請注意:幾乎所有這些類都有一個具大的接口,因此我們可以花一些時間努力去理解這些錯綜復雜的樹狀物。