Oracle Fusion Middleware Java API Reference for Oracle Extension SDK Reference
11g Release 1 (11.1.1.6.0)

E13403-07

Package oracle.javatools.ui.search

Provides a general purpose search or filter component.

See:
          Description

Interface Summary
SearchListener A listener for events on the SearchField.
 

Class Summary
MiniSearchDialog A floating search dialog.
PromptedTextField A text field that displays an inline prompt.
SearchCategory A search category.
SearchEvent An event fired by the SearchField.
SearchField A custom text component that can be used as an immediate search control.
SearchFieldBorder A custom border used for a search field.
SearchMatcher Provides standard implementations of basic search and filter matching.
SearchProgress Callback mechanism used by a SearchListener to notify the SearchField of search progress.
TextComponentSearchSupport Add the ability to do a find within a text component.
 

Enum Summary
MiniSearchDialog.Location  
SearchEvent.Direction  
SearchField.Style The style of search supported by an instance of SearchField.
SearchField.TypingDelay When the style of a SearchField is SearchField.Style.FILTER, searching is triggered on a delay after the user stops typing.
 

Package oracle.javatools.ui.search Description

Provides a general purpose search or filter component. You should use the SearchField when you want to provide filter, search, or find capability.

Filter Style

Use the Filter style if you have an existing data set that you want to reduce as the user types filter text.

Configure an instance of SearchField to use the filter style using the SearchField.setStyle(oracle.javatools.ui.search.SearchField.Style) method:

 SearchField sc = new SearchField();
 sc.setStyle( SearchField.Style.FILTER );
 
Filtering must be fast; if you cannot apply a filter in under one second, use search instead.

The filter is triggered on a small delay timer from when the user stops typing. By default, the interval of this timer is very short, which makes filtering seem quick and responsive. However, if the filtering implementation is slow, then the short timer will cause pauses while the user is typing. In this case, you may want to configure the component to use a longer typing delay. You can do this using the SearchField.setTypingDelay(SearchField.TypingDelay) method:

 sc.setTypingDelay( SearchField.TypingDelay.SLOW );
 
To implement the filter, attach a SearchListener to an instance of the SearchField. Respond to the searchPerformed event by altering the model of your component to remove items that do not match the search text. You can obtain the search text from the SearchEvent.

 {
   sc.addSearchListener( new SearchListener() {
     public void searchPerformed( SearchEvent event ) {
       String searchText = event.getSearchText();
       filterItems( searchText );
     }
   } );
 }
 
 private void filterItems( String searchText ) {
   // TODO: modify the model of your component to remove items
   // that don't match the search text.
 }
 
You should take care to do a case insensitive match when filtering (and indeed when performing other types of search). See the last section of this document for information about SearchMatcher, an API you can use to implement basic text prefix searching consistently.

 private void filterItems( String searchText ) {
   // See the last section in ths document for more information about SearchMatcher.
   SearchMatcher matcher = SearchMatcher.getPrefixMatcher( searchText, true, true );
   Collection<String> itemsToRemove = new HashSet<String>();
   for ( int i=0; i < _myListModel.getSize(); i++; ) {
     String item = (String) _myListModel.getElementAt( i );
     if ( !matcher.matches( item ) ) itemsToRemove.add( item );
   }
   _myListModel.removeItems( itemsToRemove );
 }
 

Search Style

Use the Search style if you want to allow the user to create a new data set by entering search terms, or if filtering will take more than 1 second.

Configure an instance of SearchField to use the search style like so:

 SearchField sc = new SearchField();
 sc.setStyle( SearchField.Style.SEARCH );
 
To implement the search, attach a SearchListener to an instance of the SearchField. Respond to the searchPerformed event by populating the model of your UI component on a background thread.

 sc.addSearchListener( new SearchListener() {
   public void searchPerformed( SearchEvent event ) {
     final Runnable runnable = new SearchRunnable( event.getSearchProgress(),
       event.getSearchCategory(), event.getSearchText() );
     final Thread thread = new Thread( runnable, "Searching" );
     thread.start();
   }
 } );
 
You should use the SearchProgress object to communicate the progress of your search operation to the SearchField. You can safely call any of the methods on the SearchProgress object from a background thread. You must call SearchProgress.finish() when your search is complete, whether or not it found any results. This resets the field back to its initial state.

You should periodically check SearchProgress.isStopped() to see if the user canceled the search.

 private class SearchRunnable implements Runnable {
   private final SearchProgress _progress;
   private final SearchCategory _category;
   private final String _text;
   private final int BATCH_COUNT = 5;
   
   private SearchRunnable( SearchProgress progress, SearchCategory category, String text ) {
     _progress = progress;
     _category = category;
     _text = text;
   }
   
   public void run() {
     try {
       _progress.setDeterminate( getNumberOfThingsToSearch() );
       final List<Thing> foundThings = new ArrayList<Thing>( BATCH_COUNT );
       for ( int i=0; i < getNumberOfThingsToSearch(); i++ ) {
         final Thing theThing = getThing( i );
         if ( isMatch( theThing, _category, _text ) ) {
           foundThings.add( theThing );
         }
         
         if ( i % BATCH_COUNT == 0 ) {
           if ( _progress.isStopped() ) return;
           addToModel( new ArrayList<Thing>( foundThings ) ); // defensive copy
           foundThings.clear();
         }
         _progress.setProgress( i+1 );
       }
       addToModel( new ArrayList<Thing>( foundThings ) ); // defensive copy
     }
     finally {
       _progress.finish();
     }
   }
   
   // Implementation specific:
   private int getNumberOfThingsToSearch() { }
   private boolean isMatch( Thing thing, SearchCategory category, String text ) {}
   private void addToModel( final Collection<Thing> things ) {
     EventQueue.invokeLater( new Runnable() { public void run() {
       // Do stuff to swing model.
     }});
   }
 }
 

Find Style

Use the find style if you want to navigate an existing data set item by item.

Configure an instance of SearchField to use the find style like so:

 SearchField sc = new SearchField();
 sc.setStyle( SearchField.Style.FIND );
 
To implement the find, attach a SearchListener to an instance of the SearchField. Respond to the searchPerformed event by selecting the next or previous item that matches the search terms. You can determine whether the search was forward or backward using the SearchEvent.getDirection().

It's recommended (though not required) that you highlight all potential matches in addition to selecting the next or previous match when a search is performed. This is implemented in a control specific way, for example by configuring the ListCellRenderer on a JList.

Common Features

The SearchField supports some features that are common to all three styles.

Search Categories

You can add one or more SearchCategories to the SearchField using SearchField.addCategory(SearchCategory). As soon as one or more category is associated with the field, it will make a drop down list available.

When you receive a searchPeformed event, the SearchEvent.getSearchCategory() method returns the currently selected SearchCategory instance.

Custom Menu Items

You can also add custom menu items to the categories drop down (even if you have not added any categories). You do this using the SearchField.addCategoryMenuItem(JMenuItem) method.

Implementing Search Consistently

For general text searches, it's recommended that you use one of the SearchMatcher implementations to actually test the search pattern against some target text. The prefix matcher is particularly recommended, since this behaves the same way that searches work in Mac OS X and Windows Vista, i.e. by matching the words in the search term as prefixes of words in the target text.

For example, if you obtain a case insensitive, exclusive prefix matcher (the recommended default for all general text searches) like so:

 SearchMatcher matcher = SearchMatcher.getPrefixMatcher( "Some words", true, true );
 
Then SearchMatcher.matches(CharSequence) will return true for the following strings (amongst others):

 "Some words"
 "some"
 "words"
 "something"
 "something randomly wordsworthy"
 "wordsmith something"
 
But not for these:

 "Winsome"
 "passwords"
 

Since:
11.1.1.0.0

Oracle Fusion Middleware Java API Reference for Oracle Extension SDK Reference
11g Release 1 (11.1.1.6.0)

E13403-07

Copyright © 1997, 2011, Oracle. All rights reserved.