Tuesday, May 8, 2007

Combos as Contribution Itens on rcp

Okay! Maintaining the post rate for more then 1 day. My current record so far.
This time I will focus on a problem I had last week while implementing Archimedes' layer combo. Using combos in SWT is quite simple, you just create it linking it to its parent and add the texts. In an RCP application things are a bit more complicated since the widgets are positioned in the parent composite only when needed. This basically means that the ContributionItem abstraction is a closure to insert those widgets when needed.

I've implemented about 3 or 4 times this class because I had several problems and couldn't understand why since I got no exception message and the widget just wasn't being shown. I created this implementation thanks to an example posted in this mailing list (http://dev.eclipse.org/newslists/news.eclipse.platform.rcp/msg00952.html) by Jean-Michel Lemieux (author of "Eclipse Rich Client Platform: Designing, Coding, And Packaging Java Applications", one of the best books about eRCP I found). You can find a more complete implementation of this in Archimedes (br.org.archimedes.gui.rca.LayerComboContributionItem) but here goes a simplified version.


public class ComboContributionItem extends ContributionItem implements
  IContributionItem {
  private Combo layersCombo;
  private CoolItem coolItem;
  private List texts;
  public ComboContributionItem(List texts) {
    this.texts = texts;
  }
  public void fill (ToolBar parent, int index) {
    ToolItem item = new ToolItem(parent, SWT.SEPARATOR);
    Control box = createLayersCombo(parent);
    item.setControl(box);
    item.setWidth(500);
  }
  public void fill (CoolBar coolBar, int index) {
    Control box = createLayersCombo(coolBar);
    int flags = SWT.DROP_DOWN;
    if (index >= 0) {
      coolItem = new CoolItem(coolBar, flags, index);
    }
    else {
      coolItem = new CoolItem(coolBar, flags);
    }
    coolItem.setData(this);
    coolItem.setControl(box);
    Point toolBarSize = box.computeSize(SWT.DEFAULT, SWT.DEFAULT);
    coolItem.setMinimumSize(toolBarSize);
    coolItem.setPreferredSize(toolBarSize);
    coolItem.setSize(toolBarSize);
  }
  private Control createLayersCombo (Composite parent) {
    Composite top = new Composite(parent, SWT.NONE);
    GridLayout layout = new GridLayout();
    layout.marginHeight = 0;
    layout.marginWidth = 0;
    layout.verticalSpacing = 0;
    layout.horizontalSpacing = 0;
    layout.numColumns = 1;
    top.setLayout(layout);
    layersCombo = new Combo(top, SWT.READ_ONLY);
    for (String text : texts) {
      layersCombo.add(text);
    }
    layersCombo.setLayoutData(new GridData(GridData.FILL,
      GridData.BEGINNING, true, false));
    return top;
  }
  public void fill (Composite parent) {
    createLayersCombo(parent);
  }
  public void setText (String text) {
    if (layersCombo != null) {
      layersCombo.setText(text);
    }
  }
}


I've cut the package and imports info but this should not be hard to add. I suggest you just copy this code and alter it to match your needs slowly so you see the result. If you have any problem with this code or need help because things are not rendering, please contact me.

With some minor changes on this code, I managed to enable the layer combo once again. Which means Archimedes is now back with Layers. The layer editor is still a bit buggy since the last refactoring but it should be solved very soon. I hope I have some nice screenshots by the week end with everything solved out.

See you later guys.

No comments: