PageRenderTime 125ms CodeModel.GetById 66ms app.highlight 43ms RepoModel.GetById 1ms app.codeStats 1ms

/jEdit/tags/jedit-4-3-pre5/org/gjt/sp/jedit/search/HyperSearchResults.java

#
Java | 771 lines | 590 code | 99 blank | 82 comment | 68 complexity | 09b41f92ad56264def1851e1948f3c32 MD5 | raw file
  1/*
  2 * HyperSearchResults.java - HyperSearch results
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 1998, 1999, 2000, 2001 Slava Pestov
  7 * Portions copyright (C) 2002 Peter Cox
  8 *
  9 * This program is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU General Public License
 11 * as published by the Free Software Foundation; either version 2
 12 * of the License, or any later version.
 13 *
 14 * This program is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17 * GNU General Public License for more details.
 18 *
 19 * You should have received a copy of the GNU General Public License
 20 * along with this program; if not, write to the Free Software
 21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 22 */
 23
 24package org.gjt.sp.jedit.search;
 25
 26//{{{ Imports
 27import javax.swing.*;
 28import javax.swing.tree.*;
 29
 30import java.awt.*;
 31import java.awt.event.*;
 32import java.util.*;
 33import org.gjt.sp.jedit.gui.DefaultFocusComponent;
 34import org.gjt.sp.jedit.gui.RolloverButton;
 35import org.gjt.sp.jedit.msg.*;
 36import org.gjt.sp.jedit.*;
 37//}}}
 38
 39/**
 40 * HyperSearch results window.
 41 * @author Slava Pestov
 42 * @version $Id: HyperSearchResults.java 5379 2006-05-05 09:01:40Z kpouer $
 43 */
 44public class HyperSearchResults extends JPanel implements EBComponent,
 45	DefaultFocusComponent
 46{
 47	public static final String NAME = "hypersearch-results";
 48
 49	//{{{ HyperSearchResults constructor
 50	public HyperSearchResults(View view)
 51	{
 52		super(new BorderLayout());
 53
 54		this.view = view;
 55
 56		caption = new JLabel();
 57
 58		Box toolBar = new Box(BoxLayout.X_AXIS);
 59		toolBar.add(caption);
 60		toolBar.add(Box.createGlue());
 61
 62		ActionHandler ah = new ActionHandler();
 63
 64		clear = new RolloverButton(GUIUtilities.loadIcon("Clear.png"));
 65		clear.setToolTipText(jEdit.getProperty(
 66			"hypersearch-results.clear.label"));
 67		clear.addActionListener(ah);
 68		toolBar.add(clear);
 69
 70		multi = new RolloverButton();
 71		multi.setToolTipText(jEdit.getProperty(
 72			"hypersearch-results.multi.label"));
 73		multi.addActionListener(ah);
 74		toolBar.add(multi);
 75
 76		add(BorderLayout.NORTH, toolBar);
 77
 78		resultTreeRoot = new DefaultMutableTreeNode();
 79		resultTreeModel = new DefaultTreeModel(resultTreeRoot);
 80		resultTree = new JTree(resultTreeModel);
 81		resultTree.setToolTipText("");
 82		resultTree.setCellRenderer(new ResultCellRenderer());
 83		resultTree.setVisibleRowCount(16);
 84		resultTree.setRootVisible(false);
 85		resultTree.setShowsRootHandles(true);
 86
 87		// looks bad with the OS X L&F, apparently...
 88		if(!OperatingSystem.isMacOSLF())
 89			resultTree.putClientProperty("JTree.lineStyle", "Angled");
 90
 91		resultTree.setEditable(false);
 92
 93		resultTree.addKeyListener(new KeyHandler());
 94		resultTree.addMouseListener(new MouseHandler());
 95
 96		JScrollPane scrollPane = new JScrollPane(resultTree);
 97		Dimension dim = scrollPane.getPreferredSize();
 98		dim.width = 400;
 99		scrollPane.setPreferredSize(dim);
100		add(BorderLayout.CENTER, scrollPane);
101	} //}}}
102
103	//{{{ focusOnDefaultComponent() method
104	public void focusOnDefaultComponent()
105	{
106		resultTree.requestFocus();
107	} //}}}
108
109	//{{{ addNotify() method
110	public void addNotify()
111	{
112		super.addNotify();
113		EditBus.addToBus(this);
114		multiStatus = jEdit.getBooleanProperty(
115			"hypersearch-results.multi");
116		updateMultiStatus();
117	} //}}}
118
119	//{{{ removeNotify() method
120	public void removeNotify()
121	{
122		super.removeNotify();
123		EditBus.removeFromBus(this);
124		jEdit.setBooleanProperty("hypersearch-results.multi",multiStatus);
125	} //}}}
126
127	//{{{ visitBuffers() method
128	private void visitBuffers(final ResultVisitor visitor, final Buffer buffer)
129	{
130		// impl note: since multi-level hierarchies now allowed,
131		// use traverseNodes to process HyperSearchResult nodes
132		traverseNodes(resultTreeRoot, new TreeNodeCallbackAdapter() {
133			public boolean processNode(DefaultMutableTreeNode node) {
134				Object userObject = node.getUserObject();
135				if (!(userObject instanceof HyperSearchResult))
136					return true;
137				HyperSearchResult result = (HyperSearchResult) userObject;
138				if (result.pathEquals(buffer.getSymlinkPath()))
139					visitor.visit(buffer, result);
140				return true;
141			}
142		});
143	} //}}}
144
145	//{{{ handleMessage() method
146	public void handleMessage(EBMessage msg)
147	{
148		if(msg instanceof BufferUpdate)
149		{
150			BufferUpdate bmsg = (BufferUpdate)msg;
151			Buffer buffer = bmsg.getBuffer();
152			Object what = bmsg.getWhat();
153			if(what == BufferUpdate.LOADED)
154				visitBuffers(new BufferLoadedVisitor(),buffer);
155			else if(what == BufferUpdate.CLOSED)
156				visitBuffers(new BufferClosedVisitor(),buffer);
157		}
158	} //}}}
159
160	//{{{ traverseNodes() method
161	public boolean traverseNodes(DefaultMutableTreeNode node, 
162			HyperSearchTreeNodeCallback callbackInterface)
163	{
164		if (!callbackInterface.processNode(node))
165			return false;
166		for (Enumeration e = node.children(); e.hasMoreElements();)
167		{
168			DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)e.nextElement();
169			if (!traverseNodes(childNode, callbackInterface))
170				return false;
171		}
172		return true;
173	} //}}}
174
175	//{{{ getTreeModel() method
176	public DefaultTreeModel getTreeModel()
177	{
178		return resultTreeModel;
179	} //}}}
180
181	//{{{ getTree() method
182	/**
183	 * Returns the result tree.
184	 * @since jEdit 4.1pre9
185	 */
186	public JTree getTree()
187	{
188		return resultTree;
189	} //}}}
190
191	//{{{ searchStarted() method
192	public void searchStarted()
193	{
194		caption.setText(jEdit.getProperty("hypersearch-results.searching"));
195	} //}}}
196
197	//{{{ setSearchStatus() method
198	public void setSearchStatus(String status)
199	{
200		caption.setText(status);
201	} //}}}
202
203	//{{{ searchFailed() method
204	public void searchFailed()
205	{
206		caption.setText(jEdit.getProperty("hypersearch-results.no-results"));
207
208		// collapse all nodes, as suggested on user mailing list...
209		for(int i = 0; i < resultTreeRoot.getChildCount(); i++)
210		{
211			DefaultMutableTreeNode node = (DefaultMutableTreeNode)
212				resultTreeRoot.getChildAt(i);
213			resultTree.collapsePath(new TreePath(new Object[] {
214				resultTreeRoot, node }));
215		}
216	} //}}}
217
218	//{{{ searchDone() method
219	public void searchDone(final DefaultMutableTreeNode searchNode)
220	{
221		final int nodeCount = searchNode.getChildCount();
222		if (nodeCount < 1)
223		{
224			searchFailed();
225			return;
226		}
227
228		caption.setText(jEdit.getProperty("hypersearch-results.done"));
229
230		SwingUtilities.invokeLater(new Runnable()
231		{
232			public void run()
233			{
234				if(!multiStatus)
235				{
236					for(int i = 0; i < resultTreeRoot.getChildCount(); i++)
237					{
238						resultTreeRoot.remove(0);
239					}
240				}
241
242				resultTreeRoot.add(searchNode);
243				resultTreeModel.reload(resultTreeRoot);
244
245				TreePath lastNode = null;
246
247				for(int i = 0; i < nodeCount; i++)
248				{
249					lastNode = new TreePath(
250						((DefaultMutableTreeNode)
251						searchNode.getChildAt(i))
252						.getPath());
253
254					resultTree.expandPath(lastNode);
255				}
256
257				resultTree.scrollPathToVisible(
258					new TreePath(new Object[] {
259					resultTreeRoot,searchNode }));
260			}
261		});
262	} //}}}
263
264	//{{{ Private members
265	private View view;
266
267	private JLabel caption;
268	private JTree resultTree;
269	private DefaultMutableTreeNode resultTreeRoot;
270	private DefaultTreeModel resultTreeModel;
271
272	private RolloverButton clear;
273	private RolloverButton multi;
274	private boolean multiStatus;
275
276	//{{{ updateMultiStatus() method
277	private void updateMultiStatus()
278	{
279		if(multiStatus)
280			multi.setIcon(GUIUtilities.loadIcon("MultipleResults.png"));
281		else
282			multi.setIcon(GUIUtilities.loadIcon("SingleResult.png"));
283	} //}}}
284	
285	//{{{ goToSelectedNode() method
286	public static final int M_OPEN = 0;
287	public static final int M_OPEN_NEW_VIEW = 1;
288	public static final int M_OPEN_NEW_PLAIN_VIEW = 2;
289	public static final int M_OPEN_NEW_SPLIT = 3;
290
291	private void goToSelectedNode(int mode)
292	{
293		TreePath path = resultTree.getSelectionPath();
294		if(path == null)
295			return;
296
297		DefaultMutableTreeNode node = (DefaultMutableTreeNode)path
298			.getLastPathComponent();
299		Object value = node.getUserObject();
300
301		// do nothing if clicked "foo (showing n occurrences in m files)"
302		if(node.getParent() != resultTreeRoot && value instanceof HyperSearchNode)
303		{
304			HyperSearchNode n = (HyperSearchNode)value;
305			Buffer buffer = n.getBuffer();
306			if(buffer == null)
307				return;
308
309			EditPane pane;
310
311			switch(mode)
312			{
313			case M_OPEN:
314				pane = view.goToBuffer(buffer);
315				break;
316			case M_OPEN_NEW_VIEW:
317				pane = jEdit.newView(view,buffer,false).getEditPane();
318				break;
319			case M_OPEN_NEW_PLAIN_VIEW:
320				pane = jEdit.newView(view,buffer,true).getEditPane();
321				break;
322			case M_OPEN_NEW_SPLIT:
323				pane = view.splitHorizontally();
324				break;
325			default:
326				throw new IllegalArgumentException("Bad mode: " + mode);
327			}
328
329			((HyperSearchNode)value).goTo(pane);
330		}
331	} //}}}
332
333	//}}}
334
335	//{{{ ActionHandler class
336	public class ActionHandler implements ActionListener
337	{
338		public void actionPerformed(ActionEvent evt)
339		{
340			Object source = evt.getSource();
341			if(source == clear)
342			{
343				resultTreeRoot.removeAllChildren();
344				resultTreeModel.reload(resultTreeRoot);
345			}
346			else if(source == multi)
347			{
348				multiStatus = !multiStatus;
349				updateMultiStatus();
350
351				if(!multiStatus)
352				{
353					for(int i = resultTreeRoot.getChildCount() - 2; i >= 0; i--)
354					{
355						resultTreeModel.removeNodeFromParent(
356							(MutableTreeNode)resultTreeRoot
357							.getChildAt(i));
358					}
359				}
360			}
361		}
362	} //}}}
363
364	//{{{ KeyHandler class
365	class KeyHandler extends KeyAdapter
366	{
367		public void keyPressed(KeyEvent evt)
368		{
369			if(evt.getKeyCode() == KeyEvent.VK_ENTER)
370			{
371				goToSelectedNode(M_OPEN);
372
373				// fuck me dead
374				SwingUtilities.invokeLater(new Runnable()
375				{
376					public void run()
377					{
378						resultTree.requestFocus();
379					}
380				});
381
382				evt.consume();
383			}
384		}
385	} //}}}
386
387	//{{{ MouseHandler class
388	class MouseHandler extends MouseAdapter
389	{
390		//{{{ mousePressed() method
391		public void mousePressed(MouseEvent evt)
392		{
393			if(evt.isConsumed())
394				return;
395
396			TreePath path1 = resultTree.getPathForLocation(
397				evt.getX(),evt.getY());
398			if(path1 == null)
399				return;
400
401			resultTree.setSelectionPath(path1);
402			if (GUIUtilities.isPopupTrigger(evt))
403				showPopupMenu(evt);
404			else
405			{
406				goToSelectedNode(M_OPEN);
407
408				view.toFront();
409				view.requestFocus();
410				view.getTextArea().requestFocus();
411			}
412		} //}}}
413
414		//{{{ Private members
415		private JPopupMenu popupMenu;
416
417		//{{{ showPopupMenu method
418		private void showPopupMenu(MouseEvent evt)
419		{
420			TreePath path = resultTree.getSelectionPath();
421			DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
422			
423			popupMenu = new JPopupMenu();
424			Object userObj = node.getUserObject();
425			if (userObj instanceof HyperSearchFileNode
426					|| userObj instanceof HyperSearchResult)
427			{
428				popupMenu.add(new GoToNodeAction(
429					"hypersearch-results.open",
430					M_OPEN));
431				popupMenu.add(new GoToNodeAction(
432					"hypersearch-results.open-view",
433					M_OPEN_NEW_VIEW));
434				popupMenu.add(new GoToNodeAction(
435					"hypersearch-results.open-plain-view",
436					M_OPEN_NEW_PLAIN_VIEW));
437				popupMenu.add(new GoToNodeAction(
438					"hypersearch-results.open-split",
439					M_OPEN_NEW_SPLIT));
440			}
441			if (!(userObj instanceof HyperSearchFolderNode))
442				popupMenu.add(new RemoveTreeNodeAction());
443			popupMenu.add(new ExpandChildTreeNodesAction());
444			if (userObj instanceof HyperSearchFolderNode
445					|| userObj instanceof HyperSearchOperationNode)
446			{
447				popupMenu.add(new CollapseChildTreeNodesAction());
448				if (userObj instanceof HyperSearchFolderNode)
449					popupMenu.add(new NewSearchAction());
450			}
451			if (userObj instanceof HyperSearchOperationNode)
452			{
453				popupMenu.add(new JPopupMenu.Separator());
454				HyperSearchOperationNode resultNode = (HyperSearchOperationNode)userObj;
455				JCheckBoxMenuItem chkItem = 
456					new JCheckBoxMenuItem(jEdit.getProperty("hypersearch-results.tree-view"),
457							resultNode.isTreeViewDisplayed());
458				chkItem.addActionListener(new TreeDisplayAction());
459				popupMenu.add(chkItem);
460			}
461
462			GUIUtilities.showPopupMenu(popupMenu,evt.getComponent(),
463				evt.getX(),evt.getY());
464			evt.consume();
465		} //}}}
466
467		//}}}
468	} //}}}
469
470	//{{{ RemoveTreeNodeAction class
471	class RemoveTreeNodeAction extends AbstractAction
472	{
473		public RemoveTreeNodeAction()
474		{
475			super(jEdit.getProperty("hypersearch-results.remove-node"));
476		}
477
478		public void actionPerformed(ActionEvent evt)
479		{
480			TreePath path = resultTree.getSelectionPath();
481			if(path == null)
482				return;
483
484			MutableTreeNode value = (MutableTreeNode)path
485				.getLastPathComponent();
486			HyperSearchOperationNode.removeNodeFromCache(value);
487			resultTreeModel.removeNodeFromParent(value);
488		}
489	}//}}}
490
491	//{{{ RemoveAllTreeNodesAction class
492	class RemoveAllTreeNodesAction extends AbstractAction
493	{
494		public RemoveAllTreeNodesAction()
495		{
496			super(jEdit.getProperty("hypersearch-results.remove-all-nodes"));
497		}
498
499		public void actionPerformed(ActionEvent evt)
500		{
501			resultTreeRoot = new DefaultMutableTreeNode();
502			resultTreeModel = new DefaultTreeModel(resultTreeRoot);
503			resultTree.setModel(resultTreeModel);
504		}
505	}//}}}
506	
507	//{{{ NewSearchAction class
508	class NewSearchAction extends AbstractAction
509	{
510		public NewSearchAction()
511		{
512			super(jEdit.getProperty("hypersearch-results.new-search"));
513		}
514
515		public void actionPerformed(ActionEvent evt)
516		{
517			TreePath path = resultTree.getSelectionPath();
518			DefaultMutableTreeNode operNode = (DefaultMutableTreeNode)path.getLastPathComponent();
519			HyperSearchFolderNode nodeObj = (HyperSearchFolderNode)operNode.getUserObject();
520			
521			String glob = "*";
522			SearchFileSet dirList = SearchAndReplace.getSearchFileSet();
523			if (dirList instanceof DirectoryListSet)
524				glob = ((DirectoryListSet)dirList).getFileFilter();
525			SearchAndReplace.setSearchFileSet(new DirectoryListSet(
526					nodeObj.getNodeFile().getAbsolutePath(),glob,true));
527			SearchDialog.showSearchDialog(view,null,SearchDialog.DIRECTORY);
528		}
529	}//}}}
530	
531
532	//{{{ ExpandChildTreeNodesAction class
533	class ExpandChildTreeNodesAction extends AbstractAction
534	{
535		public ExpandChildTreeNodesAction()
536		{
537			super(jEdit.getProperty("hypersearch-results.expand-child-nodes"));
538		}
539
540		public void actionPerformed(ActionEvent evt)
541		{
542			TreePath path = resultTree.getSelectionPath();
543			DefaultMutableTreeNode operNode = (DefaultMutableTreeNode)path.getLastPathComponent();
544			expandAllNodes(operNode);
545		}
546	}//}}}
547
548	//{{{ CollapseChildTreeNodesAction class
549	class CollapseChildTreeNodesAction extends AbstractAction
550	{
551		public CollapseChildTreeNodesAction()
552		{
553			super(jEdit.getProperty("hypersearch-results.collapse-child-nodes"));
554		}
555
556		public void actionPerformed(ActionEvent evt)
557		{
558			TreePath path = resultTree.getSelectionPath();
559			DefaultMutableTreeNode operNode = (DefaultMutableTreeNode)path.getLastPathComponent();
560			for (Enumeration e = operNode.children(); e.hasMoreElements();)
561			{
562				DefaultMutableTreeNode node = (DefaultMutableTreeNode)e.nextElement();
563				resultTree.collapsePath(new TreePath(node.getPath()));
564			}
565			resultTree.scrollPathToVisible(
566					new TreePath(operNode.getPath()));
567		}
568	}//}}}
569
570	//{{{ TreeDisplayAction class
571	class TreeDisplayAction extends AbstractAction
572	{
573		//{{{ actionPerformed method
574		public void actionPerformed(ActionEvent evt)
575		{
576			JCheckBoxMenuItem menuItem = (JCheckBoxMenuItem) evt.getSource();
577			boolean curState = menuItem.isSelected();
578			
579			TreePath path = resultTree.getSelectionPath();
580			DefaultMutableTreeNode operNode = (DefaultMutableTreeNode)path.getLastPathComponent();
581			
582			HyperSearchOperationNode operNodeObj = (HyperSearchOperationNode)operNode.getUserObject();
583			if (curState)
584				operNodeObj.cacheResultNodes(operNode);
585			operNode.removeAllChildren();
586			Exception excp = null;
587			if (curState)
588			{
589				try
590				{
591					operNodeObj.insertTreeNodes(resultTree, operNode);
592				} 
593				catch (Exception ex)
594				{
595					operNodeObj.restoreFlatNodes(resultTree, operNode);
596					menuItem.setSelected(false);
597					excp = ex;
598				}
599				finally
600				{
601					((DefaultTreeModel)resultTree.getModel()).nodeStructureChanged(operNode);
602					expandAllNodes(operNode);
603					resultTree.scrollPathToVisible(
604							new TreePath(operNode.getPath()));					
605				}
606				if (excp != null)
607					throw new RuntimeException(excp);
608			}
609			else
610				operNodeObj.restoreFlatNodes(resultTree, operNode);
611			
612			operNodeObj.setTreeViewDisplayed(menuItem.isSelected());
613		}
614	}//}}}
615	
616	public void expandAllNodes(DefaultMutableTreeNode node)
617	{
618		
619		traverseNodes(node, new TreeNodeCallbackAdapter()
620		{
621			public boolean processNode(DefaultMutableTreeNode node) {
622				resultTree.expandPath(new TreePath(node.getPath()));
623				return true;
624			}
625		});
626	}
627	
628	//{{{ GoToNodeAction class
629	class GoToNodeAction extends AbstractAction
630	{
631		private int mode;
632
633		public GoToNodeAction(String labelProp, int mode)
634		{
635			super(jEdit.getProperty(labelProp));
636			this.mode = mode;
637		}
638
639		public void actionPerformed(ActionEvent evt)
640		{
641			goToSelectedNode(mode);
642		}
643	}//}}}
644
645	//{{{ ResultCellRenderer class
646	class ResultCellRenderer extends DefaultTreeCellRenderer
647	{
648		Font plainFont, boldFont;
649
650		//{{{ ResultCellRenderer constructor
651		ResultCellRenderer()
652		{
653			plainFont = UIManager.getFont("Tree.font");
654			if(plainFont == null)
655				plainFont = jEdit.getFontProperty("metal.secondary.font");
656			boldFont = new Font(plainFont.getName(),Font.BOLD,
657				plainFont.getSize());
658		} //}}}
659
660		//{{{ getTreeCellRendererComponent() method
661		public Component getTreeCellRendererComponent(JTree tree,
662			Object value, boolean sel, boolean expanded,
663			boolean leaf, int row, boolean hasFocus)
664		{
665			super.getTreeCellRendererComponent(tree,value,sel,
666				expanded,leaf,row,hasFocus);
667			setIcon(null);
668			DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
669
670			if (node.getUserObject() instanceof HyperSearchOperationNode)
671			{
672				ResultCellRenderer.this.setFont(boldFont);
673	
674				class CountNodes implements HyperSearchTreeNodeCallback
675				{
676					int bufferCount = 0, resultCount = 0;
677					public boolean processNode(DefaultMutableTreeNode node) 
678					{
679						Object userObject = node.getUserObject();
680						if (userObject instanceof HyperSearchResult)
681							resultCount++;
682						else if (userObject instanceof HyperSearchFileNode)
683							bufferCount++;
684						return true;
685					}
686				}
687				CountNodes countNodes = new CountNodes();
688				traverseNodes(node, countNodes);
689
690				String property = "hypersearch-results.result-caption";
691				if (countNodes.bufferCount == 1)
692				{
693					property += countNodes.resultCount == 1 ? "1" : "2";
694				}
695				
696				Object[] pp = { node.toString(), new Integer(countNodes.resultCount), 
697						new Integer(countNodes.bufferCount) };
698				setText(jEdit.getProperty(property,pp));
699			}
700			else if(node.getUserObject() instanceof HyperSearchFolderNode)
701			{
702				ResultCellRenderer.this.setFont(plainFont);
703				setText(node.toString() + " (" + node.getChildCount() + " files/folders)");
704			}
705			else if(node.getUserObject() instanceof HyperSearchFileNode)
706			{
707				// file name
708				ResultCellRenderer.this.setFont(boldFont);
709				int count = node.getChildCount();
710				if(count == 1)
711				{
712					setText(jEdit.getProperty("hypersearch-results"
713						+ ".file-caption1",new Object[] {
714						node.getUserObject()
715						}));
716				}
717				else
718				{
719					setText(jEdit.getProperty("hypersearch-results"
720						+ ".file-caption",new Object[] {
721						node.getUserObject(),
722						new Integer(count)
723						}));
724				}
725			}
726			else
727			{
728				ResultCellRenderer.this.setFont(plainFont);
729			}
730
731			return this;
732		} //}}}
733	} //}}}
734
735	// these are used to eliminate code duplication. i don't normally use
736	// the visitor or "template method" pattern, but this code was contributed
737	// by Peter Cox and i don't feel like changing it around too much.
738
739	//{{{ ResultVisitor interface
740	interface ResultVisitor
741	{
742		public void visit(Buffer buffer, HyperSearchResult result);
743	} //}}}
744
745	//{{{ BufferLoadedVisitor class
746	class BufferLoadedVisitor implements ResultVisitor
747	{
748		public void visit(Buffer buffer, HyperSearchResult result)
749		{
750			result.bufferOpened(buffer);
751		}
752	} //}}}
753
754	//{{{ BufferClosedVisitor class
755	class BufferClosedVisitor implements ResultVisitor
756	{
757		public void visit(Buffer buffer, HyperSearchResult result)
758		{
759			result.bufferClosed();
760		}
761	} //}}}
762	
763	//{{{ TreeNodeCallbackAdapter class
764	class TreeNodeCallbackAdapter implements HyperSearchTreeNodeCallback
765	{
766		public boolean processNode(DefaultMutableTreeNode node) {
767			return false;
768		}
769		
770	} //}}}
771}