Rich Clients met Eclipse RCP (deel 2)

4 February 2008 17:25 Rob Schellhorn IDE, Java

In een eerder blog artikel heb ik laten zien hoe je makkelijk rich client applicaties kan bouwen op basis van Eclipse RCP. De gebouwde demo applicatie had de mogelijkheid om de inhoud van een bibliotheek te bekijken in een tree view. Er ontbrak echter de mogelijkheid om nieuwe boeken toe te voegen, of bestaande boeken te bewerken. In dit deel zal ik laten zien hoe je een formulier geörienteerde editor kan implementeren, die instaat is om je data op een makkelijke manier te bewerken.

Editor voor de Book objectenDe editor voor ‘Book’ objecten.

Ook de broncode is weer beschikbaar.

Interactie: Commands en Handlers

Op een aantal plekken kan de Eclipse gebruikers interface uitgebreid worden. Een plug-in kan bijvoorbeeld nieuwe knoppen aan het menu toevoegen. Dit gebeurt op een bijzonder elegante manier. Een command definieert een specifieke gebruikers actie, bijvoorbeeld het openen van een editor voor het huidige geselecteerde item. Of de selectie nu een bestand is, of een stukje Java code maakt voor het command niet uit. Context gevoelige informatie definieer je in een handler. Voor een command kunnen een heleboel verschillende handlers gedefinieerd worden. Er mag er echter maar één tegelijk actief zijn.

<!-- Definieer een command -->
<extension point="org.eclipse.ui.commands">
   <command id="com.finalist.rcp.commands.open" name="Open" />
</extension>
 
<!-- Definieer een handler voor het command -->
<extension point="org.eclipse.ui.handlers">
   <handler class="com.finalist.rcp.internal.handlers.OpenBookHandler"
         commandId="com.finalist.rcp.commands.open">
      <activeWhen><!-- Conditie uniek voor dit command --></activeWhen>
   </handler>
</extension>
 
<!-- Voeg tenslotte het command aan het Explorer contextmenu toe -->
<extension point="org.eclipse.ui.menus">
   <menuContribution
         locationURI="popup:com.finalist.rcp.views.explorer?before=additions">
      <command commandId="com.finalist.rcp.commands.open" />
   </menuContribution>
</extension>

De gehele declaratie bestaat dus uit metadata. Er komt geen regel Java code aan te pas. Op deze manier wordt voorkomen dat plug-ins die aan de GUI bijdragen het opstarten vertragen. Een plug-in wordt namelijk pas geactiveerd zodra Equinox de eerste klasse laadt. Als programmeur gebruik je bijvoorbeeld lang niet altijd de debugger, dus waarom zou je hem laden?

Soms wil je een command activeren vanuit code. Het is bijvoorbeeld niet mogelijk om een command te activeren als een bepaald event getriggered wordt. In zo’n geval kan je handmatig het command starten:

viewer.addOpenListener(new IOpenListener() {
   public void open(OpenEvent event) {
      try {
         IWorkbenchSite site = getSite();
         IHandlerService service = (IHandlerService) site.getService(IHandlerService.class);
         service.executeCommand("com.finalist.rcp.commands.open", null);
      } catch (Exception e) { /* Exceptie afhandelen */ }
   }
});

Meer over het command framework van Eclipse kan je hier lezen.

Form Editors

Een gebruikers interface bouwen om data te bewerken kan lastig zijn. De onderliggende data is vaak dermate complex dat er heel veel velden nodig zijn. Als datastructuur wordt in Java vaak gebruik gemaakt van POJOs met properties en relaties naar andere POJOs. Een formulier is een natuurlijke manier om gegevens in te vullen. Web pagina’s profiteren bijvoorbeeld van de mogelijkheid om op een makkelijke manier formulieren te bouwen. In Eclipse neemt het manipuleren van data ook een centraal positie. Dit hoeft lang niet altijd tekst geörienteerd te zijn, zoals programma code. In het vorige deel werd bijvoorbeeld meerdere malen de plug-in editor gebruikt. Deze editor is ook formulier geörienteerd, te vergelijken met HTML formulieren.

Zulke editors zijn makkelijk zelf te bouwen door gebruik te maken van het org.eclipse.ui.forms framework. De daadwerkelijke editor maak je door middel van een sub klasse van FormEditor. In deze sub klasse zal je onder andere de save methode moeten implementeren. De inhoud van het formulier bestaat uit één of meerdere pagina’s; oftewel sub klassen van FormPage. Per pagina ben je in principe vrij om controls toe te voegen. Onderstaand voorbeeld illustreert de koppeling tussen model en formulier:

class BookEditor extends FormEditor {
   protected void addPages() {
      try {
         addPage(new OverviewFormPage(this));
      } catch(PartInitException e) { /* Exceptie afhandelen */ }
   }
 
   public void doSave(IProgressMonitor monitor) {
      commitPages(true /* getriggered door opslaan */);      
      editorDirtyStateChanged();
   }
}
 
class OverviewFormPage extends FormPage {
   protected void createFormContent(IManagedForm managedForm) {
      managedForm.addPart(new GeneralInformationSectionPart(...));
   }
}
 
class GeneralInformationSectionPart extends SectionPart {
   private Text publisher, title;
   // ...
 
   public void commit(boolean onSave) {
      if (onSave) {
         Book book = getEditorInput().getBook();
         book.setPublisher(publisher.getText());
         book.setTitle(title.getText());
      }
      super.commit(onSave);
   }
 
   public void refresh() {
      Book book = getEditorInput().getBook();
      publisher.setText(book.getPublisher());
      title.setText(book.getTitle());
      super.refresh();
   }
 
   public void initialize(IManagedForm form) {
      // Maak het formulier, o.a. het invoerveld voor de titel:
      title = toolkit.createText(client, null /* Initieel leeg */);
      title.addModifyListener(new ModifyListener() {
         public void modifyText(ModifyEvent e) {
            if (isValid(title)) manager.removeMessage("title", title);
            else manager.addMessage("title", melding, ..., ERROR, title);
 
            markDirty(); // De invoer is veranderd
         }
      });
   }
}

Voor meer voorbeeld code, zie het Eclipse Forms: New in 3.3 artikel op de eclipse site.

Conclusie

Dankzij het command framework is het erg makkelijk om knoppen aan de diverse menu’s toe te voegen. Het maakt hierbij niet uit of het menu gedefinieerd is in je eigen plug-in of er buiten. Omdat de declaratie niet in Java maar er buiten gebeurt, kunnen de knoppen aan de gebruikers interface worden toegevoegd zonder iedere plug-in te activeren.

Ook het form editor framework maakt het programmeren wel heel makkelijk. Dankzij de model-view-control aanpak, en transparante afhandeling van validatie kan je heel snel een formulier maken. Ook voor complexere modellen, met veel relaties tussen objecten volstaat een editor. Dat is voor de gebruiker zeker een voordeel ten opzichte van web applicaties, die voor dit soort modellen vaak terug vallen op meerdere formulieren met veel pagina transities tot gevolg.

In het laatste deel zullen internationalisatie, de help functie en het uitbrengen van updates aan bod komen.

———————————————————————————–
Meer weten over Java-specialist Finalist IT Group?

Reageer

RSS feed for comments on this post · TrackBack URI