图解应用集成开发环境设计GUI程序-4
要显示一个层次关系清晰的一组数据,用树状图表示能给用户一个直易用的感觉,JTree类如同Windows的资源管理器的左半边,通过单击可以“打开”、“关闭”文件夹,展开树状结构的图表数据。JTree也是依据M-V-C的思想来设计的,JTree的主要功能是吧数据按照树状进行显示,其数据来源于其他对象。如下图就是一棵包含多个分枝点的树的例子。
代码如下:
1 package com.javaapp.ch12; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 import javax.swing.tree.*; 7 import java.util.Enumeration; 8 9 @SuppressWarnings("serial") 10 public class FrameTreeDemo extends JPanel { 11 DefaultMutableTreeNode root,child,chosen; 12 JTree tree; 13 DefaultTreeModel model; 14 DefaultTreeCellRenderer treeRenderer = new DefaultTreeCellRenderer(); 15 ImageIcon image1 = new ImageIcon(getClass().getResource("6.jpg")); 16 ImageIcon image2 = new ImageIcon(getClass().getResource("4.jpg")); 17 ImageIcon image3 = new ImageIcon(getClass().getResource("5.jpg")); 18 String[][] data = { { "天峰","三丰","小峰","峰峰" },{ "爱好","劳动","钱财","剥削" }, 19 { "职位","平民","地主","官僚" },{ "工资","20","2000","200000" }, 20 { "地位","低下","高","无所不作" },{ "民意","高","低下","打倒" } }; 21 static int i = 0; // I用于统计当前树中结点的个数 22 public FrameTreeDemo() { 23 root = new DefaultMutableTreeNode("root"); // 根节点进行初始化 24 tree = new JTree(root); // 树进行初始化,其数据来源是root对象 25 treeRenderer.setClosedIcon(image1); 26 treeRenderer.setOpenIcon(image2); 27 treeRenderer.setLeafIcon(image3); 28 treeRenderer.setBorder(null); 29 treeRenderer.setToolTipText(""); 30 treeRenderer.setVerifyInputWhenFocusTarget(false); 31 treeRenderer.setDisplayedMnemonic('3'); 32 treeRenderer.setLabelFor(tree); 33 treeRenderer.setBorderSelectionColor(Color.green); 34 treeRenderer.setTextNonSelectionColor(Color.darkGray); 35 treeRenderer.setTextSelectionColor(Color.red); 36 tree.setCellRenderer(treeRenderer); 37 setLayout(new BorderLayout()); 38 add(new JScrollPane(tree)); // 把滚动面板添加到Trees中 39 model = (DefaultTreeModel) tree.getModel(); // 获得数据对象DefaultTreeModel 40 JButton test = new JButton("在当前结点下添加子结点"); // 按钮test进行初始化 41 JPanel p = new JPanel(); // 面板p初始化 42 p.add(test); // 把按钮添加到面板p中 43 add(p,BorderLayout.SOUTH); // 把面板p添加到Trees中 44 test.addActionListener(new ActionListener() { 45 // 按钮test注册监听器 46 public void actionPerformed(ActionEvent e) { 47 if (i < data.length) { 48 // 按钮test点击的次数小于data的长度 49 child = new Addnode(data[i++]).node(); 50 // 生成子节点 51 chosen = (DefaultMutableTreeNode) 52 // 选择child的父节点 53 tree.getLastSelectedPathComponent(); 54 if (chosen == null) { 55 chosen = root; 56 } 57 model.insertNodeInto(child,chosen,0); 58 // 把child添加到chosen 59 } 60 } 61 }); 62 expandAll(tree,true); 63 } 64 public void expandAll(JTree tree,boolean expand) { 65 TreeNode root = (TreeNode) tree.getModel().getRoot(); 66 // Traverse tree from root 67 expandAll(tree,new TreePath(root),expand); 68 } 69 private void expandAll(JTree tree,TreePath parent,boolean expand) { 70 // Traverse children 71 DefaultMutableTreeNode node = (DefaultMutableTreeNode) parent 72 .getLastPathComponent(); 73 if (node.getLevel() <= 1) { 74 if (node.getChildCount() >= 0) { 75 for (Enumeration e = node.children(); e.hasMoreElements();) { 76 TreeNode n = (TreeNode) e.nextElement(); 77 TreePath path = parent.pathByAddingChild(n); 78 expandAll(tree,path,expand); 79 } 80 } 81 } 82 // Expansion or collapse must be done bottom-up 83 if (expand) { 84 tree.expandPath(parent); 85 } else { 86 tree.collapsePath(parent); 87 } 88 } 89 public static void main(String args[]) { 90 JFrame jf = new JFrame("JTree demo"); 91 jf.getContentPane().add(new FrameTreeDemo(),BorderLayout.CENTER); 92 // 把Trees对象添加到JFrame对象的中央 93 jf.setSize(300,600); 94 jf.setVisible(true); 95 } 96 } 97 class Addnode { 98 DefaultMutableTreeNode r; 99 // DefaultMutableTreeNode是树的数据结构中的通用节点,节点也可以有多个子节点。 100 public Addnode(String[] data) { 101 r = new DefaultMutableTreeNode(data[0]); 102 for (int i = 1; i < data.length; i++) { 103 r.add(new DefaultMutableTreeNode(data[i])); 104 } 105 // 给节点r添加多个子节点 106 } 107 public DefaultMutableTreeNode node() { // 返回节点 108 return r; 109 } 110 }
程序分析:
在上面的程序中,首先应用DefaultMutableTreeNode类创建一个树的根节点,创建方法为:
1 DefaultMutableTreeNode root = new DefaultMutableTreeNode("root"); // 根节点进行初始化
然后用创建的根节点初始化一棵树,初始化的方法为:
1 JTree tree = new JTree(root); // 树进行初始化,其数据来源是root对象
可以通过DefaultTreeCellRenderer来创建节点渲染器,利用DefaultTreeCellRenderer对象设置树中各节点的图标,例如节点的展开、闭合、叶子图标等。具体设置方法如下:
1 ImageIcon image1 = new ImageIcon(getClass().getResource("6.jpg"));//创建图标 2 ImageIcon image2 = new ImageIcon(getClass().getResource("4.jpg")); 3 ImageIcon image3 = new ImageIcon(getClass().getResource("5.jpg")); 4 treeRenderer.setClosedIcon(image1);//设置节点闭合图标 5 treeRenderer.setOpenIcon(image2);//设置节点打开图标 6 treeRenderer.setLeafIcon(image3);//设置叶子节点图标
设置完DefaultTreeCellRenderer渲染器后,可以头通过JTree的setCellRenderer方法把渲染器添加到树中。最后需要把创建的树添加到JSrollpane面板中。
创建并设置完树后,可以利用DefaultTreeModel来操作树,例如在树中添加、删除节点。获得DefaultTreeModel的方法为:
1 DefaultTreeModel model = (DefaultTreeModel) tree.getModel(); // 获得数据对象DefaultTreeModel
然后可以利用DefaultTree的insertNodeInto方法在节点中插入一个节点,例如把节点child添加到节点chosen中的方法为:
1 model.insertNodeInto(child, chosen, 0);
如果要得到当前所选择的节点,可以利用JTree的getLastSelectPathComponent方法来获得:实现代码如下:
1 DefaultMutableTreeNode chosen=(DefaultMutableTreeNode)tree.getLastSelectedPathComponent();