View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.xnap.gui.pkg;
21  
22  import java.util.Hashtable;
23  import java.util.Iterator;
24  import java.util.StringTokenizer;
25  
26  import javax.swing.JTree;
27  import javax.swing.tree.DefaultMutableTreeNode;
28  import javax.swing.tree.DefaultTreeModel;
29  import javax.swing.tree.TreeNode;
30  import javax.swing.tree.TreePath;
31  
32  import org.xnap.XNap;
33  import org.xnap.pkg.PackageInfo;
34  import org.xnap.util.StringHelper;
35  
36  public class PackageInfoTree extends JTree {
37      
38      //--- Data field(s) ---
39  
40  	private DefaultMutableTreeNode root;
41  	private DefaultTreeModel tmPackages;
42  	private Hashtable nodeBySectionName = new Hashtable();
43  
44      //--- Constructor(s) ---
45  
46      public PackageInfoTree(String rootLabel)
47      {
48  		root = new DefaultMutableTreeNode(rootLabel);
49  		tmPackages = new DefaultTreeModel(root);
50  		setModel(tmPackages);
51      }
52  
53  	public PackageInfoTree()
54  	{
55  		this(XNap.tr("Packages"));
56  	}
57  
58  	//--- Method(s) ---
59  
60  	public void createPackageNode(DefaultMutableTreeNode parent,
61  								  PackageInfo info)
62  	{
63  		String section = "/" + info.getSection() + "/" + info.getName();
64  		DefaultMutableTreeNode node 
65  			= (DefaultMutableTreeNode)nodeBySectionName.get(section);
66  		if (node == null) {
67  			ContainerPackageSection container
68  				= new ContainerPackageSection(info.getName());
69  			container.setPackageInfo(info);
70  
71  			node = new DefaultMutableTreeNode(container);
72  			nodeBySectionName.put(section, node);
73  			parent.add(node);
74  		}
75  		else if (node.getUserObject() instanceof ContainerPackageSection) {
76  			ContainerPackageSection container
77  				= (ContainerPackageSection)node.getUserObject();
78  			container.setPackageInfo(info);
79  			// info has a higher version but is not yet installed
80  			container.setUpdateAvailable(!info.isInstalled());
81  		}
82  
83  		// sort higher versions first
84  		node.insert(new DefaultMutableTreeNode(info), 0);
85  	}
86  
87  	/***
88  	 * Creates a section node and returns it.
89  	 */
90  	public DefaultMutableTreeNode createSectionNodes(String sectionName)
91  	{
92  		DefaultMutableTreeNode parent = root;
93  
94  		StringBuffer totalSection = new StringBuffer(sectionName.length());
95  		StringTokenizer t = new StringTokenizer(sectionName, "/");
96  		while (t.hasMoreTokens()) {
97  			totalSection.append("/");
98  			totalSection.append(t.nextToken());
99  
100 			DefaultMutableTreeNode node
101 				= getNodeBySection(parent, totalSection.toString());
102 			parent = node;
103 		}
104 		return parent;
105 	}
106 
107 	private DefaultMutableTreeNode getNodeBySection
108 		(DefaultMutableTreeNode parent, String section)
109 	{
110 		DefaultMutableTreeNode node 
111 			= (DefaultMutableTreeNode)nodeBySectionName.get(section);
112 		if (node == null) {
113 			node = new DefaultMutableTreeNode
114 				(StringHelper.lastToken(section, "/"));
115 			nodeBySectionName.put(section, node);
116 			parent.add(node);
117 		}
118 		return node;
119 	}
120 	
121 	public PackageInfo getSelectedInfo()
122 	{
123 		if (getSelectionPath() != null) {
124 			DefaultMutableTreeNode node = (DefaultMutableTreeNode)
125 				getSelectionPath().getLastPathComponent();
126 	
127 			if (node.getUserObject() instanceof ContainerPackageSection) {
128 				return ((ContainerPackageSection)node.getUserObject())
129 					.getPackageInfo();
130 			}
131 			if (node.getUserObject() instanceof PackageInfo) {
132 				return (PackageInfo)node.getUserObject();
133 			}
134 		}
135 		return null;
136 	}
137 
138 	public void pathChanged(TreePath path)
139 	{
140 		tmPackages.nodeChanged((TreeNode)path.getLastPathComponent());
141 	}
142 
143 	public void reload()
144 	{
145 		tmPackages.reload();
146 
147 		// expand important nodes
148 		expandRow(0);
149 		expandNodes(root.getChildAt(0));
150 	}
151 
152 	public void selectedNodeChanged()
153 	{
154 		tmPackages.nodeChanged
155 			((TreeNode)getSelectionPath().getLastPathComponent());
156 	}
157 
158 	public void updatePackages(Iterator it)
159 	{
160 		root.removeAllChildren();
161 		nodeBySectionName.clear();
162 
163 		// create a few default sections
164 		createSectionNodes("plugin");
165 
166 		while (it.hasNext()) {
167 			PackageInfo info = (PackageInfo)it.next();
168 			DefaultMutableTreeNode parent
169 				= createSectionNodes(info.getSection());
170 			createPackageNode(parent, info);
171 		}
172 
173 		// update tree
174 		reload();
175 	}
176 
177 	private void expandNodes(TreeNode child)
178 	{
179 		expandPath(new TreePath(new Object[] { root, child }));
180 		for (int i = child.getChildCount() - 1; i >= 0; i--) {
181 			Object[] path 
182 				= new Object[] { root, child, child.getChildAt(i) };
183 			expandPath(new TreePath(path));
184 		}
185 	}
186 
187 }