Wednesday Jun 25, 2008

Quick Search API

The 6.5 Milestone 1 New and Noteworthy document (which is a work in progress since 6.5 M1 has not yet been released and is scheduled for release during the coming weeks) talks, among many other things, about something called "Quick Search".

The description says: "Quickly search for action or type is now easy. Use Ctrl-I." The two related documents are in the Wiki and on NetBeans.org. So, wherever you are in the IDE, you're able to press Ctrl-I, then you find that the cursor is in the Quick Search, you type the letter of something you're interested in opening into the Quick Search, and the results are shown:

Select an item and the related action is invoked, in the case of the actions, or the type is opened in the editor, in the case of the types. That's all very nice. What's nicer is that there's a new API that lets you plug your own items into the Quick Search functionality. Even better is the fact that there's a new wizard to support this. Take the following steps (using a build from today or later):

  1. Create a new module.

  2. Click Ctrl-N to bring up the New File dialog and then choose Module Development | Quick Search Provider:

  3. Click Next and then fill out the last step of the template:

  4. Click Finish and then look in the layer.xml file and you should see this:

    <filesystem>
        <folder name="QuickSearch">
            <folder name="Beatles">
                <attr name="command" stringvalue="Beatles"/>
                <attr name="position" intvalue="0"/>
                <file name="org-nb-beatles-BeatleSearchProvider.instance">
                    <attr name="SystemFileSystem.localizingBundle" 
                          stringvalue="org.nb.beatles.Bundle"/>
                </file>
            </folder>
        </folder>
    </filesystem>

  5. Then look at the generated class and you should see this:

    package org.nb.beatles;
    
    import org.netbeans.spi.quicksearch.SearchProvider;
    import org.netbeans.spi.quicksearch.SearchRequest;
    import org.netbeans.spi.quicksearch.SearchResponse;
    
    public class BeatleSearchProvider implements SearchProvider {
    
        /\*\*
         \* Method is called by infrastructure when search operation was requested.
         \* Implementors should evaluate given request and fill response object with
         \* apropriate results
         \*
         \* @param request Search request object that contains information what to search for
         \* @param response Search response object that stores search results. Note that it's important to react to return value of SearchResponse.addResult(...) method and stop computation if false value is returned.
         \*/
        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;
            //	  }
            //    }
            //}
        }
    
    }

  6. Now begin working with the generated class so that it will do something useful. Begin by setting a dependency on UI Utilities API so that you can use the URLDisplayer class, which will open the browser with the URL to the Wikipedia entry of the selected Beatle, which is simply the little scenario we'll go through below. Then change the class above to the following:

    package org.nb.beatles;
    
    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;
    
    public class BeatleSearchProvider implements SearchProvider {
    
        public void evaluate(SearchRequest request, SearchResponse response) {
            String[] beatles = {"john", "paul", "ringo", "george"};
            for (String beatle : beatles) {
                if (beatle.toLowerCase().indexOf(request.getText().toLowerCase()) != -1) {
                    if (!response.addResult(new BeatleFoundResult(beatle), beatle)) {
                        return;
                    }
    
                }
            }
        }
    
        private static class BeatleFoundResult implements Runnable {
    
            private String beatle;
    
            public BeatleFoundResult(String beatle) {
                if (beatle.equals("john")) {
                    this.beatle =
                            "http://en.wikipedia.org/wiki/John_lennon";
                } else if (beatle.equals("paul")) {
                    this.beatle =
                            "http://en.wikipedia.org/wiki/Paul_McCartney";
                } else if (beatle.equals("ringo")) {
                    this.beatle =
                            "http://en.wikipedia.org/wiki/Ringo_Starr";
                } else if (beatle.equals("george")) {
                    this.beatle =
                            "http://en.wikipedia.org/wiki/George_Harrison";
                }
    
            }
    
            public void run() {
                try {
                    URLDisplayer.getDefault().showURL(new URL(beatle));
                } catch (MalformedURLException ex) {
                    Logger.getLogger(BeatleSearchProvider.class.
                         getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        
    }

  7. Install it (do a restart if installing into the development IDE) and then press Ctrl-I anywhere and you'll find the cursor in the Quick Search field where you can start typing. If the letter you type is anywhere in one of the items you added to the Quick Search, the item is shown. So here I typed "o", which is found in "john", "ringo", and "george", but not in "paul":

    Select the item, the browser opens, displaying the Wikipedia entry on the selected Beatle.

  8. Once you've selected an item, it is automatically stored in the "Recent Searches" category, so that it is easier to see next time you do a quick search.

How useful is it to be able to search for the Beatles inside NetBeans IDE? Not very. But this is just a simple example. Imagine that this was not NetBeans IDE, but your own application with its own domain-specific data. Being able to plug relevant parts of that data, or ui from the application itself, into the Quick Search feature could be a pretty powerful aid to your end users.

About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« June 2008 »
SunMonTueWedThuFriSat
1
6
13
19
26
28
29
     
       
Today