Eclipse Search

Loading

Oct 20, 2008

Extending FilteredItemsSelectionDialog

In a previous tip, you have seen various Selection Dialogs in Eclipse. One thing which was not explained in it was FilteredItemsSelectionDialog, as it deserves a tip on its own. In this tip, I'll explain how to extend that class.

The Open Resource Dialog and Open Type Dialog are the ones you might be using very frequently. They are subclasses of FilteredItemsSelectionDialog. The dialog looks like this:

image  

Lets see what does it makes to create a simple dialog like this which allows us to select some Persons. First step is to extend the FilteredItemsSelectionDialog:

 


   1: public class FilteredPersonsSelectionDialog extends FilteredItemsSelectionDialog {
   2:  
   3:     private final List<Person> persons;
   4:  
   5:     public FilteredPersonsSelectionDialog(Shell shell, List<Person> persons) {
   6:         super(shell);
   7:         this.persons = persons;
   8:         setListLabelProvider(getListLabelProvider());
   9:         setDetailsLabelProvider(getDetailsLabelProvider());
  10:         setSelectionHistory(new PersonHistory());
  11:     }
  12:  
  13:     @Override
  14:     protected void fillContentProvider(AbstractContentProvider contentProvider,
  15:             ItemsFilter itemsFilter, IProgressMonitor progressMonitor)
  16:             throws CoreException {
  17:  
  18:         progressMonitor.beginTask("Looking for persons...", persons.size());
  19:         for (Person person : persons) {
  20:             contentProvider.add(person, itemsFilter);
  21:             progressMonitor.worked(1);
  22:         }
  23:  
  24:     }
  25:     private static final String SETTINGS = FilteredPersonsSelectionDialog.class.getCanonicalName();
  26:  
  27:     @Override
  28:     protected IDialogSettings getDialogSettings() {
  29:         IDialogSettings settings = Activator.getDefault().getDialogSettings().getSection(SETTINGS);
  30:  
  31:         if (settings == null) {
  32:             settings = Activator.getDefault().getDialogSettings().addNewSection(SETTINGS);
  33:         }
  34:  
  35:         return settings;
  36:     }
  37:  
  38:     @Override
  39:     protected ItemsFilter createFilter() {
  40:         return new PersonFilter();
  41:     }
  42:     
  43:     // other members
  44:  



When you have hundreds of thousands of items, adding it to the list up front is a huge task. So ideally, what happens is the dialog is displayed first and then the fillContentProvider is called when the user starts typing. (Or if you have specified the initial pattern, then its called as soon as the dialog is displayed to the user). For the sake of simplicity, I'm passing in all the items in the constructor and adding them to the contentProvider in the loop. This can't happen if the number of items is huge. Ideally you can specify the place where to search for thru the constructor and in the fillContentProvider, you start searching for all the items and add them. The progress will be shown below the search text box.


Apart from this FilteredPersonsSelectionDialog class, you would need few helper classes. The first one is the filter class, which should extend ItemFilter. This decides how to filter the items with the query provided in the search text box. You can decide on the wildcard strings, whether CamelCase searching is allowed etc. 


The next one is related to the history. The FilteredItemsSelectionDialog can remember the selection from the previous searches. To enable that, you need to extend the SelectionHistory and set it as we have did it in the line number 10. You need to override the abstract methods in the SelectionHistory to store & restore the item from the memento. The location where the memento saved into is dictated by the getDialogSettings().


The last set of classes are the LabelProviders. You need two of them. One for displaying in the list and the other for displaying in the details area, which should ideally provide more information than the first one.


image


Now the last bit of info. Invoking this dialog:




   1: FilteredPersonsSelectionDialog dialog = new FilteredPersonsSelectionDialog(window.getShell(), persons);
   2: dialog.setTitle("Select Person");
   3: dialog.setInitialPattern("?");   
   4: dialog.open();

10 comments:

  1. Hi Prakash G.R,
    this is a very good blog and your article seems to be exactly what i need. So i writed my own class (a dialog to filter persons too) and i got a
    "The type FilteredItemsSelectionDialog.ItemsFilter is not visible" when trying to implements my own PersonnFilter extending FilteredItemsSelectionDialog.ItemsFilter. In fact this class is protected so can you say me how to work with that. It seems we don't use the same version (i work with Eclipse ganymede).

    best regards,
    marc

    ReplyDelete
  2. Marc,
    If you haven't noticed the ItemsFilter is an inner class of FilteredItemsSelectionDialog. So if you subclass ItemsFilter, it also has to be an inner class, whose outer class should be a subclass of FilteredItemsSelectionDialog (Hope its clear :-). Are you trying to have the ItemsFilter subclass in a separate file?

    ReplyDelete
  3. hi,

    thanks for your response. i found my solution just after my message on your blog. But i definitively need your help because i wrote a very simple class to test it and the content of the list is never displayed. With debug i can see that filtering is ok but the refresh() method of the component is never called ! i try since 3 days comparing with FilteredTypesSelectionDialog from Eclipse code but i can't see why mine doesn't work :-(

    have you a complete working sample to help me ? i follow all your instructions but ...

    thanks for your help.

    marc (noob inside)

    ReplyDelete
  4. hi,

    thanks for your response. i found my solution just after my message on your blog. But i definitively need your help because i wrote a very simple class to test it and the content of the list is never displayed. With debug i can see that filtering is ok but the refresh() method of the component is never called ! i try since 3 days comparing with FilteredTypesSelectionDialog from Eclipse code but i can't see why mine doesn't work :-(

    have you a complete working sample to help me ? i follow all your instructions but ...

    thanks for your help.

    marc (noob inside)

    ReplyDelete
  5. I should say you are lucky :-)
    The project I had for this tip was not deleted from my workspace. I've uploaded to My Google Pages. Download it from here: http://grprakash.googlepages.com/SelectionDialogTip.zip

    ReplyDelete
  6. Hi,

    Thanks for this very useful tip. I have a small problem with, I don't find FilteredItemsSelectionDialog class in my RCP projet, which pluging should I add to reference this class ? I'm working on Eclipse 3.2

    Thanks in advance.

    Sam.

    ReplyDelete
  7. @Sam,
    This class is in org.eclipse.ui.dialogs package in workbench plugin. The API was introduced in 3.3, so it won't work in 3.2

    ReplyDelete
  8. Thanks fro your quick answer ;-)

    Yes you are right. Instead I use this class : ElementListSelectionDialog

    Sam

    ReplyDelete
  9. "The name of the person is: Hitesh and the age is 23" -- do I really look like a 23 year old ;-).

    Nice tips on the blog :). Read the one on custom marker views too.

    ReplyDelete
  10. @Hitesh

    Sorry for underestimating your age. Will correct it next time :-P

    ReplyDelete