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  
21  package org.xnap.gui;
22  
23  import java.awt.BorderLayout;
24  
25  import javax.swing.JScrollPane;
26  import javax.swing.JSplitPane;
27  import javax.swing.JTree;
28  import javax.swing.event.TreeSelectionEvent;
29  import javax.swing.event.TreeSelectionListener;
30  import javax.swing.tree.DefaultTreeModel;
31  
32  import org.apache.log4j.Logger;
33  import org.xnap.gui.event.SwingListListener;
34  import org.xnap.gui.tree.FileCellRenderer;
35  import org.xnap.gui.tree.SearchPathNode;
36  import org.xnap.gui.util.*;
37  import org.xnap.search.Search;
38  import org.xnap.search.SearchFilter;
39  import org.xnap.search.SearchResult;
40  
41  public class SearchResultTreePanel extends SearchResultPanel 
42      implements SwingListListener, TreeSelectionListener {
43  
44      //--- Constant(s) ---
45  
46      //--- Data field(s) ---
47  
48      private static Logger logger 
49  		= Logger.getLogger(SearchResultTreePanel.class);
50  
51      protected JSplitPane jsp;
52      protected JTree jtPath;
53      protected DefaultTreeModel dtmPath;
54      protected SearchPathNode spnRoot;
55      private SwingSynchronizedCache cache;
56  
57      //--- Constructor(s) ---
58  
59      public SearchResultTreePanel(SearchPanel parent, Search search)
60      {
61  		super(parent, search, "browse", false);
62  
63  		initialize();
64  
65  		SwingSynchronizedCache cache = new SwingSynchronizedCache(this);
66  		getController().addListListener(cache);
67  
68  		getController().start();
69  		setStatus(getController().getStatus());
70      }
71      
72      //--- Method(s) ---
73  
74      protected void initialize()
75      {
76  		// tree
77  		spnRoot = new SearchPathNode("All Files");
78  		dtmPath = new DefaultTreeModel(spnRoot);
79  		jtPath = new JTree(dtmPath);
80  		jtPath.addTreeSelectionListener(this);
81  		jtPath.setCellRenderer(new FileCellRenderer());
82  		jtPath.putClientProperty("JTree.lineStyle", "Angled");
83  
84  		JScrollPane jspPath = new JScrollPane(jtPath);
85  
86  		// split pane
87  		jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
88  		jsp.setOneTouchExpandable(true);
89  		jsp.setBorder(GUIHelper.createEmptyBorder());
90  		//jsp.setDividerLocation(200);
91  
92  		jsp.add(jspPath, JSplitPane.LEFT);
93  		jsp.add(getSearchPanel(), JSplitPane.RIGHT);
94  
95  		// content
96  		add(jsp, BorderLayout.CENTER);
97      }
98  
99      /***
100      * Invoked when search results have been received.
101      */
102     public void itemsAdded(Object[] items)
103     {
104 		for (int i = 0; i < items.length; i++) {
105 			addToTree((SearchResult)items[i]);
106 			updateTitle();
107 		}
108     }
109 
110     public void itemsRemoved(Object[] items)
111     {
112 		// is never invoked
113     }
114 
115     public void addToTree(SearchResult sr)
116     {
117 		String[] path = sr.getPath();
118 		if (path != null) {
119 			SearchPathNode node = spnRoot;
120 			SearchPathNode nextNode;
121 			// iterate through path and create new directories as needed
122 			for (int i = 0; i < path.length; i++) {
123 				nextNode = null;
124 
125 				// go through children
126 				int index = 0;
127 				for (;index < node.getChildCount(); index++) {
128 					SearchPathNode n = (SearchPathNode)node.getChildAt(index);
129 					int result = n.getName().compareToIgnoreCase(path[i]);
130 					if (result == 0) {
131 						nextNode = n;
132 						break;
133 					}
134 					else if (result > 0) {
135 						index = node.getIndex(n);
136 						break;
137 					}
138 				}
139 
140 				if (nextNode == null) {
141 					//logger.debug("SearchSubTree: adding " + path[i]);
142 		    
143 					// add new child
144 					nextNode = new SearchPathNode(path[i]);
145 		    
146 					//logger.debug("adding new node at index " + index);
147 					dtmPath.insertNodeInto(nextNode, node, index);
148 
149 					if (i == 0) {
150 						// we want to see the first depth level
151 						jtPath.expandRow(0);
152 					}
153 				}
154 				node = nextNode;
155 			}
156 			node.incResultCount();
157 		}
158     }
159 
160     public void valueChanged(TreeSelectionEvent e)
161     {
162 		Object target = e.getPath().getLastPathComponent();
163 	
164 		if (target instanceof SearchPathNode) {
165 			SearchPathNode s = (SearchPathNode)target;
166 
167 			SearchFilter filter = getFilter();
168 			filter.put(SearchFilter.PATH, s.getSearchPath());
169 			tmResults.setFilter(filter);
170 		}
171     }
172     
173 }
174