<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<!-- -*- xhtml -*- --> | |
<title>Quick Search Integration Tutorial for NetBeans Platform 7.2</title> | |
<link rel="stylesheet" type="text/css" href="https://netbeans.org/netbeans.css"/> | |
<meta name="AUDIENCE" content="NBUSER"/> | |
<meta name="TYPE" content="ARTICLE"/> | |
<meta name="EXPIRES" content="N"/> | |
<meta name="developer" content="gwielenga@netbeans.org"/> | |
<meta name="indexed" content="y"/> | |
<meta name="description" | |
content="A short guide to using the Quick Search API."/> | |
<!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. --> | |
<!-- Use is subject to license terms.--> | |
</head> | |
<body> | |
<h1>Quick Search Integration Tutorial</h1> | |
<p>This tutorial shows you how to write a module that plugs | |
custom items into the NetBeans Quick Search feature. </p> | |
<p><strong class="notes">Note: </strong>This document uses NetBeans Platform 7.2 and | |
NetBeans IDE 7.2. If you | |
are using an earlier version, see <a href="71/nbm-quick-search.html">the previous version | |
of this document</a>.</p> | |
<p><b>Contents</b></p> | |
<p><img src="../images/articles/72/netbeans-stamp.gif" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 7.2" title="Content on this page applies to NetBeans IDE 7.2"/></p> | |
<ul class="toc"> | |
<li><a href="#intro">Introduction to Quick Search Integration</a></li> | |
<li><a href="#creating">Creating the Module Project</a></li> | |
<li><a href="#use">Using the Quick Search Provider Wizard</a></li> | |
<li><a href="#third">Integrating an External HTML DOM Parser</a></li> | |
<li><a href="#code">Coding the Quick Search Integration</a></li> | |
<li><a href="#install">Installing and Trying Out the Functionality</a></li> | |
<li><a href="#platform">Using the Quick Search Feature on the NetBeans Platform</a></li> | |
</ul> | |
<p><b>To follow this tutorial, you need the software and resources listed in the following | |
table.</b></p> | |
<table> | |
<tbody> | |
<tr> | |
<th class="tblheader" scope="col">Software or Resource</th> | |
<th class="tblheader" scope="col">Version Required</th> | |
</tr> | |
<tr> | |
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td> | |
<td class="tbltd1">version 7.2 or above</td> | |
</tr> | |
<tr> | |
<td class="tbltd1"><a href="http://java.sun.com/javase/downloads/index.jsp">Java Developer Kit (JDK)</a></td> | |
<td class="tbltd1">version 6 or above</td> | |
</tr> | |
</tbody> | |
</table> | |
<h2 class="tutorial"><a name="intro"></a>Introduction to Quick Search Integration</h2> | |
<p>The Quick Search feature, introduced in NetBeans Platform 6.5, consists of | |
a text field in the top right corner of applications on the NetBeans Platform. As a search string is typed in | |
the field, a drop-down list appears, showing matching items. By default, the items | |
come from the names of actions registered in the IDE, as well as help topics | |
in the IDE's Java Help. When an action item is selected, the action is invoked; when | |
a help item is selected, the topic opens in JavaHelp.</p> | |
<p>In addition, however, the <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-spi-quicksearch/overview-summary.html">Quick Search API</a> | |
is exposed. You can use it to integrate your own search items into the | |
Quick Search feature. You can use the feature either within the IDE or | |
as part of your own application on top of the NetBeans Platform.</p> | |
<p>In this tutorial, you create a module that integrates items | |
from <a href="http://netbeans.dzone.com">NetBeans Zone</a> with the | |
Quick Search feature:</p> | |
<p><img style="border:1px solid black" src="../images/tutorials/qsearch/72/result-2.png" alt="Deployed result"/></p> | |
<!-- ===================================================================================== --> | |
<h2 class="tutorial"><a name="creating"></a>Creating the Module Project</h2> | |
<p>In this section, we use a wizard to create the source structure that every NetBeans module requires. The | |
source structure consists of certain folders in specific places and a set of files that are | |
always needed. For example, every NetBeans module requires a <tt>nbproject</tt> folder, which holds | |
the project's metadata.</p> | |
<div class="indent"> | |
<ol> | |
<li>Choose File > New Project (Ctrl-Shift-N). Under Categories, select NetBeans Modules. Under Projects, | |
select Module. Click Next.</li> | |
<li>In the Name and Location panel, type <tt>NetBeansZoneSearch</tt> in Project Name. | |
Change the | |
Project Location to any directory on your computer. Click Next.</li> | |
<li>In the Basic Module Configuration panel, type <tt>org.netbeans.modules.nbzone</tt> | |
as the Code Name Base. Click Finish.</li> | |
</ol> | |
</div> | |
<p> The IDE creates the <tt>NetBeansZoneSearch</tt> | |
project. The project contains all of your sources and | |
project metadata, such as the project's Ant build script. The project | |
opens in the IDE. You can view its logical structure in the Projects window (Ctrl-1) and its | |
file structure in the Files window (Ctrl-2). </p> | |
<!-- ===================================================================================== --> | |
<h2><a name="use"></a>Using the Quick Search Provider Wizard</h2> | |
<p>In this section, we use a wizard to create a stub Java class and | |
layer entries necessary for beginning our integration with the | |
Quick Search feature.</p> | |
<div class="indent"> | |
<ol> | |
<li>Right-click the "NetBeansZoneSearch" project node and | |
choose New > Other. In the New File dialog, | |
choose Module Development > Quick Search Provider: | |
<br/> | |
<br/> | |
<p><img src="../images/tutorials/qsearch/72/newfilewizard.png" alt="Quick search template"/></p> | |
</li> | |
<li>In the Quick Search Provider panel, set the following: | |
<br/> | |
<br/> | |
<ul> | |
<li><b>Provider Class Name.</b> Specifies the class | |
name of the stub that the wizard will generate. Type "NBZoneSearchProvider" | |
in this field.</li> | |
<li><b>Package.</b> Specifies the package where the stub class | |
will be generated. Select "org.netbeans.modules.nbzone" from the drop-down.</li> | |
<li><b>Category Display Name.</b> Specifies the display name of | |
the category that the stub will create. Type "NetBeans Zone" in this field.</li> | |
<li><b>Command Prefix.</b> Specifies prefix for narrowing the | |
search to the category that the stub will create. Type "nb" in this field.</li> | |
<li><b>Position in Popup.</b> Specifies the position of the new | |
category in within the Quick Search feature. Leave "0", so that the category | |
will be first in the popup.</li> | |
</ul> | |
<p>You should now see the following:</p> | |
<br/> | |
<p><img src="../images/tutorials/qsearch/72/newfilewizard2.png" alt="Quick search template"/></p> | |
</li> | |
<li><p>Click Finish. The Projects window should now look as follows:</p> | |
<br/> | |
<p><img src="../images/tutorials/qsearch/72/newproject.png" alt="Final Projects window."/></p></li> | |
</ol> | |
</div> | |
<p>The Java stub that has been created is as follows:</p> | |
<pre class="examplecode">package org.netbeans.modules.nbzone; | |
import org.netbeans.spi.quicksearch.SearchProvider; | |
import org.netbeans.spi.quicksearch.SearchRequest; | |
import org.netbeans.spi.quicksearch.SearchResponse; | |
public class NBZoneSearchProvider implements SearchProvider { | |
public void evaluate(SearchRequest request, SearchResponse response) { | |
//sample code | |
//for (SearchedItem item : getAllItemsToSearchIn()) { | |
// if (isConditionSatisfied(item, request)) { | |
// if (!response.addResult(item.getRunnable(), item.getDisplayName(), | |
// item.getShortcut(), item.getDisplayHint())) { | |
// break; | |
// } | |
// } | |
//} | |
} | |
}</pre> | |
<p>In the <tt>layer.xml</tt> file, you should see the following:</p> | |
<pre class="examplecode"><folder name="QuickSearch"> | |
<folder name="NetBeansZone"> | |
<attr name="command" stringvalue="nb"/> | |
<attr name="position" intvalue="0"/> | |
<file name="org-netbeans-modules-nbzone-NBZoneSearchProvider.instance"> | |
<attr name="displayName" bundlevalue="org.netbeans.modules.nbzone.Bundle#QuickSearch/NetBeansZone/org-netbeans-modules-nbzone-NBZoneSearchProvider.instance"/> | |
</file> | |
</folder> | |
</folder></pre> | |
<!-- ======================================================================================= --> | |
<h2><a name="third"></a>Integrating an External HTML DOM Parser</h2> | |
<p>In the next section, we will need an HTML DOM Parser so that we can parse | |
NetBeans Zone. You can use any appropriate parser of your choice. For purposes | |
of this tutorial, we will use <a href="http://sourceforge.net/project/showfiles.php?group_id=13153">JTidy</a>.</p> | |
<p>There are two ways of making an external JAR file available | |
to a module:</p> | |
<ul> | |
<li>The first way is to put the JAR into a separate | |
module, called a "library wrapper module", and have the | |
functionality module <i>depend on</i> the library wrapper | |
module, after putting both into a module suite. The advantage | |
of having two separate modules is that, when a new version of | |
the external JAR is released, you will only need to redistribute | |
a small module containing only the external JAR, rather than | |
a larger one that also contains the functionality code.</li> | |
<li>The | |
second way is to add the JAR to the functionality module, which | |
is what is done below. The advantage of this approach is that | |
it is more convenient in the short term only, | |
since you only have one module to distribute, while the disadvantage | |
is that you are mixing your external library with the | |
functionality code, which is not a strictly modular approach.</li></ul> | |
<div class="indent"> | |
<ol> | |
<li>Download <a href="http://sourceforge.net/project/showfiles.php?group_id=13153">JTidy</a> | |
and find the <tt>jtidy-xxx.jar</tt> that is within the download.</li> | |
<li><p>Right-click the project, choose Properties, and wrap the JAR as shown below:</p> | |
<br/> | |
<p><img src="../images/tutorials/qsearch/72/wrapjar.png" alt="Final Projects window."/></p> | |
</li> | |
<li><p>Look in the Files window and notice that you have your | |
<tt>Tidy.jar</tt> in a new folder, named <tt>release/modules/ext</tt> folder: | |
</p> | |
<br/> | |
<p><img src="../images/tutorials/qsearch/72/wrapjar2.png" alt="Final Projects window."/></p> | |
<p>In addition, towards the end of the <tt>project.xml</tt> file, which is in the <tt>nbproject</tt> | |
folder, notice the XML elements below, i.e., right near the end of the file:</p> | |
<pre class="examplecode"> | |
... | |
... | |
... | |
<b><class-path-extension> | |
<runtime-relative-path>ext/jtidy-r938.jar</runtime-relative-path> | |
<binary-origin>release/modules/ext/jtidy-r938.jar</binary-origin> | |
</class-path-extension></b> | |
</data> | |
</configuration> | |
</project></pre></li> | |
</ol> | |
</div> | |
<p>The external HTML DOM Parser is now on your module's | |
classpath. Now you can use the classes within the JAR, | |
as you will need to do in the next section.</p> | |
<!-- ======================================================================================= --> | |
<h2><a name="code"></a>Coding the Quick Search Integration</h2> | |
<p>Next, we will implement the API. The API's classes are as follows:</p> | |
<table> | |
<tbody> | |
<tr> | |
<th class="tblheader" scope="col">Class</th> | |
<th class="tblheader" scope="col">Description</th> | |
</tr> | |
<tr> | |
<td class="tbltd1"><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-spi-quicksearch/org/netbeans/spi/quicksearch/SearchProvider.html">SearchProvider</a></td> | |
<td class="tbltd1">The main interface of the Quick Search API. | |
Implement this interface to provide a new group of results for | |
your quick search.</td> | |
</tr> | |
<tr> | |
<td class="tbltd1"><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-spi-quicksearch/org/netbeans/spi/quicksearch/SearchRequest.html">SearchRequest</a></td> | |
<td class="tbltd1">The description of the quick search request.</td> | |
</tr> | |
<tr> | |
<td class="tbltd1"><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-spi-quicksearch/org/netbeans/spi/quicksearch/SearchResponse.html">SearchResponse</a></td> | |
<td class="tbltd1">The response object for collecting the | |
results of the SearchRequest.</td> | |
</tr> | |
</tbody> | |
</table> | |
<p>Below, we set dependencies on the required modules and then implement them in | |
our own module.</p> | |
<div class="indent"> | |
<ol> | |
<li><p>Right-click the Libraries node, choose Add Module Dependency, | |
and set dependencies on the UI Utilities API and the Utilities API.</li> | |
<li>Code the "NBZoneSearchProvider" class as follows: | |
<pre class="examplecode">public class NBZoneSearchProvider implements SearchProvider { | |
@Override | |
public void evaluate(SearchRequest request, SearchResponse response) { | |
try { | |
//The URL that we are providing a search for: | |
URL url = new URL("http://netbeans.dzone.com"); | |
//Stuff needed by Tidy: | |
Tidy tidy = new Tidy(); | |
tidy.setXHTML(true); | |
tidy.setTidyMark(false); | |
tidy.setShowWarnings(false); | |
tidy.setQuiet(true); | |
//Get the org.w3c.dom.Document from Tidy, | |
//or use a different parser of your choice: | |
Document doc = tidy.parseDOM(url.openStream(), null); | |
//Get all "a" elements: | |
NodeList list = doc.getElementsByTagName("a"); | |
//Get the number of elements: | |
int length = list.getLength(); | |
//Loop through all the "a" elements: | |
for (int i = 0; i < length; i++) { | |
String href = null; | |
if (null != list.item(i).getAttributes().getNamedItem("href")) { | |
//Get the "href" attribute from the current "a" element: | |
href = list.item(i).getAttributes().getNamedItem("href").getNodeValue(); | |
} | |
//Get the "title" attribute from the current "a" element: | |
if (null != list.item(i).getAttributes().getNamedItem("title")) { | |
String title = list.item(i).getAttributes().getNamedItem("title").getNodeValue(); | |
//If the title matches the requested text: | |
if (title.toLowerCase().indexOf(request.getText().toLowerCase()) != -1) { | |
//Add the runnable and the title to the response | |
//and return if nothing is added: | |
if (!response.addResult(new OpenFoundArticle(href), title)) { | |
return; | |
} | |
} | |
} | |
} | |
} catch (IOException ex) { | |
Exceptions.printStackTrace(ex); | |
} | |
} | |
private static class OpenFoundArticle implements Runnable { | |
private String article; | |
public OpenFoundArticle(String article) { | |
this.article = article; | |
} | |
@Override | |
public void run() { | |
try { | |
URL url = new URL("http://netbeans.dzone.com" + article); | |
StatusDisplayer.getDefault().setStatusText(url.toString()); | |
URLDisplayer.getDefault().showURL(url); | |
} catch (MalformedURLException ex) { | |
Logger.getLogger(NBZoneSearchProvider.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
} | |
} | |
}</pre></li> | |
<li>Make sure the following import statements are declared at the top of the class: | |
<pre class="examplecode">import java.io.IOException; | |
import java.net.MalformedURLException; | |
import java.net.URL; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
import org.netbeans.spi.quicksearch.SearchProvider; | |
import org.netbeans.spi.quicksearch.SearchRequest; | |
import org.netbeans.spi.quicksearch.SearchResponse; | |
import org.openide.awt.HtmlBrowser.URLDisplayer; | |
import org.openide.awt.StatusDisplayer; | |
import org.openide.util.Exceptions; | |
import org.w3c.dom.Document; | |
import org.w3c.dom.NodeList; | |
import org.w3c.tidy.Tidy;</pre> | |
</li> | |
</ol> | |
</div> | |
<!-- ======================================================================================= --> | |
<h2><a name="install"></a>Installing and Trying Out the Functionality</h2> | |
<p>Let's now install the module and then use the quick search feature | |
integration. | |
The IDE uses an Ant build script to build and install your module. The build | |
script is created for you | |
when you create the project.</p> | |
<div class="indent"> | |
<ol> | |
<li>In the Projects window, right-click the project and choose Run. | |
A new instance of the IDE starts up | |
and installs the Quick Search integration module. In the top-right of | |
the IDE, you will find your Quick Search feature:</p> | |
<br/> | |
<br/> | |
<p><img border="1" src="../images/tutorials/qsearch/72/result-1.png" alt="Deployed result"/></p> | |
</li> | |
<li><p>Type a string in the Quick Search feature and, if the string | |
matches the title of something on NetBeans Zone, the item from | |
NetBeans Zone is included in the result:</p> | |
<br/> | |
<p><img border="1" src="../images/tutorials/qsearch/72/result-2.png" alt="Deployed result"/></p> | |
<br/> | |
<p>If you type the command prefix that you defined in the <tt>layer.xml</tt>, followed by | |
a space, then only the related category is searched:</p> | |
<br/> | |
<p><img border="1" src="../images/tutorials/qsearch/72/result-3.png" alt="Command prefix"/></p></li> | |
<li>Click an item and, if you have set a browser in the IDE, | |
it opens, displaying the selected article.</li> | |
</ol> | |
</div> | |
<!-- ======================================================================================= --> | |
<h2><a name="platform"></a>Using the Quick Search Feature on the NetBeans Platform</h2> | |
<p>The previous sections assumed that you were creating a module for NetBeans IDE. | |
The two topics that follow are applicable if, instead of creating | |
a module for NetBeans IDE, you are creating your own application on top of the NetBeans Platform. | |
In that case, you will need to take steps to include the Quick Search feature in your own application, as | |
described below.</p> | |
<div class="indent"> | |
<ol> | |
<li>Add the following tags to the <tt>layer.xml</tt> | |
file: | |
<pre class="examplecode"><folder name="Toolbars"> | |
<folder name="QuickSearch"> | |
<file name="org-netbeans-modules-quicksearch-QuickSearchAction.shadow"> | |
<attr name="originalFile" stringvalue="Actions/Edit/org-netbeans-modules-quicksearch-QuickSearchAction.instance"/> | |
</file> | |
</folder> | |
</folder></pre> </li> | |
<li><p>Run the NetBeans Platform application | |
and you should see that the Quick Search | |
feature is now available and functioning:</p> | |
<br/> | |
<p><img src="../images/tutorials/qsearch/72/app-result-1.png" alt="NetBeans Platform with Quick Search feature"/></p> | |
</li> | |
<li>Alternatively, you can show the Quick Search feature right-aligned in the | |
menu bar: | |
<pre class="examplecode"><folder name="Menu"> | |
<file name="Spacer.instance"> | |
<attr name="instanceCreate" methodvalue="javax.swing.Box.createHorizontalGlue"/> | |
<attr name="position" intvalue="9005"/> | |
</file> | |
<file name="org-netbeans-modules-quicksearch-QuickSearchAction.shadow"> | |
<attr name="originalFile" stringvalue="Actions/Edit/org-netbeans-modules-quicksearch-QuickSearchAction.instance"/> | |
<attr name="position" intvalue="9010"/> | |
</file> | |
</folder></pre> </li> | |
<li><p>Run the NetBeans Platform application | |
and you should see that the Quick Search | |
feature is now in the menu bar:</p> | |
<br/> | |
<p><img src="../images/tutorials/qsearch/72/app-result-2.png" alt="NetBeans Platform with Quick Search feature"/></p> | |
</li> | |
</ol> | |
</div> | |
<!-- ======================================================================================= --> | |
<div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&subject=Feedback:%20Quick%20Search%20Integration%20Tutorial%207.2">Send Us Your Feedback</a></div> | |
<!-- ======================================================================================== --> | |
<h2><a name="nextsteps"></a>Next Steps</h2> | |
<p>For more information about creating and developing NetBeans modules, see the following resources:</p> | |
<ul> | |
<li><a href="https://platform.netbeans.org/index.html">NetBeans Platform Homepage</a></li> | |
<li><a href="http://bits.netbeans.org/dev/javadoc/index.html">NetBeans API List (Current Development Version)</a></li> | |
<li><a href="https://netbeans.org/kb/trails/platform.html">Other Related Tutorials</a></li></ul> | |
<!-- ======================================================================================== --> | |
<!-- | |
<h2><a name="version"></a>Versioning </h2> | |
<p> | |
<table width="76%" border="1"> | |
<tbody> | |
<tr> | |
<td> | |
<div><b>Version</b></div> | |
</td> | |
<td> | |
<div><b>Date</b></div> | |
</td> | |
<td> | |
<div><b>Changes</b></div> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
1 | |
</td> | |
<td> | |
19 July 2008 | |
</td> | |
<td> | |
Initial version. | |
</td> | |
</tr> | |
<tr> | |
<td> | |
2 | |
</td> | |
<td> | |
6 September 2010 | |
</td> | |
<td> | |
Fixed formatting problems. | |
</td> | |
</tr> | |
<tr> | |
<td> | |
3 | |
</td> | |
<td> | |
18 November 2010 | |
</td> | |
<td> | |
Updated for 7.1. | |
</td> | |
</tr> | |
<tr> | |
<td> | |
4 | |
</td> | |
<td> | |
23 July 2012 | |
</td> | |
<td> | |
Updated for 7.2. Added explanation of showing quick search in menu bar. | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
--> | |
</body> | |
</html> |