It’s release time – QxWT 1.0.1.0 and GRaphael 1.3.1.0

QxWT 1.0.1.0

At the start of the year I promised to release Version 1.0.1.0 of QxWT at the end of Febuary and doing releases on time is one of the most important things so that people can start to trust into your project. You can download the released code from the project release website or directly through this link.

This release comes with the following major features:

  • Full support for Qooxdoo-Databinding
  • Advanced GWT-Features to e.g. Subclass JSNI-Wrappers and overload JavaScript methods in Java
  • Integration into the qooxdoo-Toolchain to create optimized JavaScript
  • Many bugfixes and not wrapped methods in 1.0.0.1
  • Integration of GRaphael to create advanced graphics, animations and charts ontop of SVG and VML using Raphael

The following features beside bugfixes are planned for the next release due in the end of April:

  • Wrapper:
    • Integrate into GWT-UI-Binder by allowing to adapt QxWT-Widgets
    • Integrate into GWT-RPC-Services
  • Eclipse-Tooling
    • Add Project Creation Support to easy setup a QxWT-Project
    • Add Support to control qooxdoo-Toolchain and create a deployable Application

GRaphael 1.3.1.0

To get support for advanced grapics and animation support I started writing a JSNI-Wrapper for Raphael. QxWT comes with an addon module which provides direct integration of GRaphael into QxWT-Applications. The wrapper is in it’s early stage and the API in the flow.

The current usage in QxWT looks like this:

QxRaphaelWidget widget = new QxRaphaelWidget(200, 200) {
  @Override
  protected void init(RPaper paper) {
    RElement el = paper.image("/image.png", 50, 50, 100, 100);
    el.attr( new RAttribute("opacity", "0"));
    el.animate(1000, new RAttribute("opacity", "1.0"));				
  }
};

Which creates an image whose opacity attribute is animated from 0 – 1.0 in 1 second, advanced transitions, gradients and much more are possible as well. You can download the released code from the project release website or or directly through this link.

A real world example

To show the potential of all this technologies I’m working on a real world example which simply allows a user to manage Photos, create Online-Presentations and in future also create printable PDF-Files (e.g. a calender, photo-album, …).

QxWT 1.0.1.0 – Realworld Demo

Tomorrow I’ll release QxWT 1.0.1.0 as I promised at the start of the year. To show people the power of QxWT and what can be achieved by using it, in conjunction with Eclipse-Tools like EMF and Teneo, I wrote an example application on the last 2 weekends.

First of all using all those OpenSource-Technologies together to create an application is simply fun. It’s been a long time since i worked with Hibernate but with Teneo, I really only needed know EMF and learn to use 2 or 3 JPA-APIs to query for stuff. This shows something I told many people already. EMF is not only useable in RCP-Application, it doesn’t even depend on OSGi. I used it at the backend for the Hibernate integration in an ordinary Jetty-Servlet-Container.

The application looks like this:

  • Open a Image-Album
  • Overview of images in the album
  • Editing meta data to images
  • Creating a custom Online-Presentation
  • Running Presentation

The whole application is not completely ready, I hoped to be further but you can try it out:

The application uses the following opensource libs:

  • Frontend
    • QxWT (EPL/LPGL)/qooxdoo (EPL/LPGL)
    • GRaphael (LGPL/EPL)/Rapael (MIT)
  • Backend:
    • EMF+Teneo (EPL)
    • Hibernate (LGPL)
    • PostgreSQL (MIT)

I have not tested this thoroughly (I only took a look on Firefox, Safari, Chrome and Opera on Mac OS X – Opera seems to have issues with images) so please don’t expect to run everything 100%. The code of the example-application is part of my SVN-Repository but NOT released under an OSS-License! Still you can take a look and learn how to use the QxWT-API.

Things I plan to add in the weeks to come:

  • Finish current features and fixing bugs
  • Adding more presentation features (Image-Transition, Drop-Shadows, Animation, …) using more Features of Raphael
  • Print support to create printable Versions for Calendars, Photo-Books, …

So stay tuned for the release announcement of QxWT 1.0.1.0 tomorrow where I’ll explain features coming with this release and features I plan to add in the next releases.

e4 – Dependency and Service Lookup Tooling

Today I extended my current implementation a bit so that I now extract the currently injected fields in a class and display them in the dialog one can open from within the JavaEditor. The following videos present shows this in action.

The next step is to add injected services through the Dialog. People asked in comments of the last post whether this support is isolated to e4 and it’s services and the answer is no. The current implementation simply registers a service in the OSGi-ServiceRegistry.

public interface IDIServiceRegistry {
  public void addServiceProvider(IDIServiceProvider descriptor);
  public void removeServiceProvider(IDIServiceProvider descriptor);
  public List<IDIServiceProvider> getProviders();
}

Potential Tool implementors can use and provide informations about available services who are probably available at runtime. As an example implementation I’ve implemented 2 example bundles who contribute providers for e4-core services using DS (you see in the screencast that no available services are there until the tooling bundles are started).

The contribution of the Logger-Service is done looks like this:

public class LoggerProvider extends DIServiceProvider implements IDIServiceProvider {
  public LoggerProvider() {
    System.err.println("Instance created");
  }

  public String getLabel() {
    return "Logger Service";
  }

  public String getDescription() {
    return "Logging warnings, errors, information, as well as capturing debug and trace information. Everything done through this interface is not meant for normal end users. Strings are not expected to be translated.";
  }

  public String getServiceClassName() {
    return "org.eclipse.e4.core.services.Logger";
  }

  public String getBundle() {
    return "org.eclipse.e4.core.services";
  }

  public String getProduct() {
    return "e4";
  }

  public String getCategory() {
    return "Core Services";
  }
}

and contributed like this using DS:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component 
  xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" 
  enabled="true" 
  immediate="true" 
  name="org.eclipse.e4.core.services.jdt">
   <implementation 
     class="org.eclipse.e4.core.services.jdt.LoggerProvider"/>
   <service>
      <provide interface="org.eclipse.e4.ui.jdt.IDIServiceProvider"/>
   </service>
</scr:component>

After having implemented the Class-Modification. I think the next logic step would be to write some PDE-Addon which simply registers all available DS-Services found in the Target-Platform into the DI-Registry. I’m still in an experimental stage so probably this is all crap and one has to address the problem differently.

Anyways I’ve learned something about IJavaProject and the AST-Stuff coming with JDT and it’s been a lot of fun so far.

e4 – Dependency Injection Tooling

In bug 302824 we started discussing how to make the use of DI easier and beside e.g. providing Helper-Classes the ideal thing would be to provide good tooling. Think about how hard OSGi-Development would be without PDE and I think the same is true for DI as well.

I had some free minutes (well in reality hours) today and thought about how such a tooling could look like. The first thing I’ve implemented today is a dialog showing core services and add them to your POJO (currently only the UI is working more or less).

There are other JDT/PDE extension we could provide to make DI in general easier but I need to make myself familiar with PDE/JDT-extensions before I know what’s possible.

e4 – Extending an existing Product

After some months of not having contributed substential stuff to e4 and in anticipation of the EclipseCon tutorial “e4 – Anatomy of an e4-Application”. I worked yesterday on some demo stuff which we’ll probably use show the audience:

  • The new development process when writing plugins using Mock-Objects
  • Extending an existing e4-Application

The idea of the extension is to add Flickr-Support (Searching and importing images and adding Images to flickr) to our e4-Photo-Demo using the Service-API provided by flickr.com.

One of the strengths of writing and extending e4-Applications is that you don’t need to bring up whole workbench but can develop all components standalone at first (you can even simply start with a none-OSGi-Application).

Here’s the process I followed

  • Writing the UI as an ordinary SWT-Application (No OSGi, No e4). The initial code looked something like this:
    public class Flickr {
      public Flickr(Composite comp) {
         // Create my UI
      }
      
      private void handleSearch(String apiKey, String tags) {
        // TODO implement search logic
      }
    
      public static void main(String[] args) {
        Display display = new Display();
        Shell shell = new Shell();
    		
        Flickr flickr = new Flickr(shell);
        shell.open();
    		
        while( ! shell.isDisposed() ) {
          if( ! display.readAndDispatch() ) {
            display.sleep();
          }
        }
    		
        display.dispose();
      }
    }
    

    After some codeing (well I thought writing something like a PagedTableViewer might me a nice thing) the UI looked like something like this:
    . The code is in a Bundle-Project “org.eclipse.e4.demo.e4photo.flickr” which depends on SWT-only for now (I let PDE manage even my standard Java-Project because this frees me from all the ClassPath-Configuration).

  • The next thing was to look at the Flickr-API and what a JavaService to talk with it could look like. The Service-Interface I came up with looked like this:
    public interface IFlickrService {
      public FlickrSearch createTagSearch(String apiKey, String tags) throws RemoteException;
    
      public List<FlickrPhoto> getPhotos(FlickrSearch search, int page) throws RemoteException;
    	
      public InputStream getPhoto(FlickrPhoto photo) throws RemoteException;
    }
    

    The service definition is also part of a separate bundle named ‘org.eclipse.e4.demo.e4photo.flickr.service’.

  • Next step was to create a bundle with a concrete implementation named ‘org.eclipse.e4.demo.e4photo.flickr.service.rest’. Which uses the REST-API provided. The service is self is also a simply POJO and so I was able to test it quite easily by simply adding a main-method.
    public class RestFlickrService implements IFlickrService {
      // Implementation of methods
    
      public static void main(String[] args) {
        try {
          RestFlickrService s = new RestFlickrService();
          FlickrSearch search = s.createTagSearch("46d3d5269fe6513602b3f0f06d9e2b2e", "eclipsecon");
    			
          for( int page = 1; page <= search.getPages(); page++ ) {
            System.err.println("--------------------------------");
            System.err.println("Page " + page);
            System.err.println("--------------------------------");
            List<FlickrPhoto> photos = s.getPhotos(search, page);
            for( FlickrPhoto p : photos ) {
              System.err.println("	* " + p);
            }
          }			
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
    

    Please don’t blame me that I haven’t written this by creating JUnit-Test but you should get the point that writeing application like this makes your whole application very easy to test in a real world application.

  • Now we need to wire the stuff together so until now we didn’t even used OSGi but now we can’t get away without it. First step is to use DS to register our service in the OSGi-Registry:
    <?xml version="1.0" encoding="UTF-8"?>
    <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.eclipse.e4.demo.e4photo.flickr.service.rest">
       <implementation class="org.eclipse.e4.demo.e4photo.flickr.service.rest.RestFlickrService"/>
       <service>
          <provide interface="org.eclipse.e4.demo.e4photo.flickr.service.IFlickrService"/>
       </service>
    </scr:component>
    
  • And we need to make our UI-Bundle use the IFlickrService. To prepare the stuff for DI we need to add the javax.inject-Bundle which holds the annotation of JSR-330.
    public class Flickr {
      @Inject
      private IFlickrService flickrService;
    
      private void handleSearch(String apiKey, String tags) {
        try {
          FlickrSearch search = flickrService.createTagSearch(apiKey, tags);
          table.setInput(new SearchInput(search));
        } catch (RemoteException e1) {
          Status s = new Status(IStatus.ERROR, "org.eclipse.e4.demo.e4photo.flickr", e1.getMessage(), e1);
          ErrorDialog.openError(table.getShell(), "Searchfailure", "Failure while executing search", s);
        }
      }
    }
    
  • Now we make an mock-application bundle ‘org.eclipse.e4.demo.e4photo.flickr.mock’ which holds an Equinox-Application which bootstraps the Dependency Framework coming with e4 and creates an instance of our view.
    public class Application implements IApplication {
      public Object start(IApplicationContext context) throws Exception {
        Display display = new Display();
        Shell shell = new Shell();
    		
        Bundle bundle = FrameworkUtil.getBundle(Application.class);
        BundleContext bundleContext = bundle.getBundleContext();
        IEclipseContext eclipseCtx = EclipseContextFactory.getServiceContext(bundleContext);
        eclipseCtx.set(Composite.class.getName(), shell);
    		
        ContextInjectionFactory.make(Flickr.class, eclipseCtx);
        shell.open();
    
        while( ! shell.isDisposed() ) {
          if( ! display.readAndDispatch() ) {
            display.sleep();
          }
        }
        display.dispose();
        return IApplication.EXIT_OK;
      }
    
      public void stop() {
        // nothing to do
      }
    }
    
  • Running this Application with all the bundles we create above plus the core OSGi-Bundles needed like (equinox.ds) will bring up the same application we’ve had after the first step. With the difference that now executing the search will really do something. We now have a running OSGi-Application which allows us to query Flickr for Photos.

  • Last step is to integrate the “Flickr-Application” as a view in the existing Photo-Demo. This is done using an the ‘org.eclipse.e4.workbench.model’ extension point which allows us to contribute ModelElements to the e4 Workbench-Model.

    Pointing to an XMI-File like this.
  • Add the bundles beside the one of the mock-Application to the Launch-Config of the e4-Photo-Demo and you now have support for searching Fotos from Flickr like shown at the start of the post.

I think one of the strengths of e4 is that it makes it easy to develop code in a way that you can run it standalone while developing. You can do this also to some extend in 3.x but at the moment you reach out to workbench-services you’ll get into trouble.

Writing a general mock framework for 3.x is quite hard because you need to rebuild the complete Workbench-Structure because your component is reaching out to them. For e4 the only thing needed is to provide mock implementation of the 20 things (=core workbench-services) and you are ready to work without bringing up an eclipse-instance to test your contribution.

e4 – why you don’t need e5

This was orginally a reply on Elias post on e5:

On “should take risks”:
We agreed that e4 would be compatible with 3.x. Is not 100% correct: We agreed on the fact that e4 will provide a compat layer so that people can run the 3.x plug-ins which is a completely different thing IMHO because the underpinning designs of e4 are not influenced by this fact.

So what you suggest is what we’ve done in e4 we started with a new set of ideas and code leaving the old one behind already which you notice if you look at the plain e4-bundles in CVS.

On “needs a driver”:
The driver for e4 in my way of thinking is RCP and though you probably don’t believe we are on a good way to make development of RCP much easier. Yet what is missing is tooling, wizards and documentation and people who mastered to learn programming e4-Applications and give you a lending hand.

There’s no need anymore for using plugin.xml for example. You can create an e4 application in a fully programmatic way only you don’t know it as a newcomer.

On “must be easy to learn & master”:
I agree but we should not forget what we are talking about. This are not HelloWorld-programs nor a simple webpages. We are talking about business applications. Still this is a valid point and we need to do our best to give people convenience tools and API to hide away the natural complexities of a multi purpose platform like e4 is one.

General sum up:
I really don’t think that you need an e5 any time soon if you look at how modular e4 is designed from scratch with

  • its extensible workbench-model at the bottom (it even allows you to add your own workbench concepts if you are unhappy with the one coming with e4)
  • its plugable rendering structure on the top
  • its abandoning of singletons making it useable in multi-user environments like RAP (by the use of DI)
  • its leveraging of OSGi (Direct support for OSGi-Services through DI, usage of the OSGi-EventSystem)
  • its even looser coupeling by the use of DI (e.g. I have code I run as plain SWT-Application and inside e4-Applications)

and this all with a really really small amount of size (as Boris already explained in his former reply your numbers are incorrect). The killer feature of e4 is that it comes with concepts and strategies to write UI applications but doesn’t force you the way to do it in certain way by allowing you to exchange (most) of them:

  • You don’t like plugin.xml to make up your UI – Great don’t use it and make up the workbench model from code, your own DSL (e.g. there’s an Xtext-Tutorial at EclipseCon where they show of how to define an Workbench-Model using a DSL), …
  • You don’t like the limitation of SWT or some of their controls – Great don’t use them and replace them with your own ones (and this even by not controling the Application-Startup like you had to do in your Ribbon-Examples for 3.x) by writing your own IPresentation engine which has about 5 methods you need to implement
  • You don’t even like SWT at all – Great don’t use it, use Swing, Qt, ncurses and write your own renderers
  • You don’t like DI but prefer to reach out to the OSGi-Service-Registry your own – Great do it. The argument that you don’t know which services are available is a tooling and documentation issue. The argument that you don’t know which services are available at a given time is something you need to get used to in dynamic environments like OSGi but at least e4 (when using DI) saves from writing code to handle this

I think e4 with the right documentation gives you (and many many people out there) exactly what you/they want so before starting to think about e5 I hope you dive deeper and exploit its possibilities.

To end this post what I like most about e4 is: It gives me back control of almost everything – if I want to – and I can’t live without this power (anymore).

UFaceKit – 2 (new) interesting features in latest nightly

Like the title already says the latest nightly build comes with 2 amazing features one already part of the code base since a long time (XPath to traverse the UI-DOM) the second one just hit SVN (plugable model-item mapping). I’m going to discuss them in short in this blog posting.

Plugable Model-Item-Mapping

You probably ask yourself. What’s this and why should I care. To understand the problem you must know how the current JFace-Viewers are working internally and which problems this can cause.

JFace-Viewers store strong Java-References between the domain model and the SWT-Item using TableItem#setData(Object)/TreeItem#setData(Object) and additionally if you turn on hashlookup (to speed up setting of selections, …) in an internal HashTable.

The problem with this is that your domain model stays resident in memory as long as the TableItem exists even if no one really needs it until you e.g. want to update the table-item. This implementation detail of current JFace-Viewers makes the use of CDO in UI less ideal because CDO can’t apply it’s clever memory management because your UI code holds strong references into your domain-object graph.

One can overcome this problem in JFace-Viewer world as well by writing some clever Content- and LabelProviders (The implementation is also available from our repository but not part of a build yet) but in my opinion not ideal from a users point of view. Moreover I think a viewer framework should have the possibility to plug-in “your” mapping strategy (e.g. provided by the domain-technoloy project you are using) according to the use case.

That’s why I decided that this feature has to be part of the core UFaceKit-Viewer-Framework and the support of it has just hit the SVN-Repository and is part of my shining new nightly athena build.

/*******************************************************************************
 * Copyright (c) 2010, BestSolution.at and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Tom Schindl <tom.schindl@bestsolution.at> - Initial API and implementation
 *******************************************************************************/
package org.eclipse.ufacekit.ui.jface.cdo.viewers;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.ufacekit.ui.jface.viewers.Viewer;
import org.eclipse.ufacekit.ui.jface.viewers.mapping.AbstractTableItemModelMapping;

public class CdoModelTableItemMapping<ModelElement extends CDOObject,Item extends org.eclipse.swt.widgets.Item> extends AbstractTableItemModelMapping<ModelElement, Item> {
  private CDOView view;
  private Map<CDOID, Item> map;

  public CdoModelTableItemMapping( CDOView view, Viewer<ModelElement, ?> viewer) {
    super(viewer);
    this.view = view;
    this.map = new HashMap<CDOID, Item>();
  }

  @Override
  public void associate(ModelElement model, Item item) {
    if (map.containsKey(model.cdoID())) {
      throw new IllegalStateException("This mapping only supports one instance of a model element");
    }
    item.setData(model.cdoID());
    map.put(model.cdoID(), item);
  }

  @Override
  public void disassociate(Item item) {
    map.remove(item.getData());
    item.setData(null);
  }

  @Override
  public void disassociateAll() {
    map.clear();
  }

  @SuppressWarnings("unchecked")
  @Override
  public ModelElement lookup(Item item) {
    return (ModelElement) view.getObject( (CDOID)item.getData() );
  }

  @Override
  public Collection<Item> lookup(ModelElement element) {
    Item item = (Item) map.get(element);
    if( item != null ) {
      return Collections.singleton(item);
    }

    return Collections.emptyList();
  }
}

This implementation is completely untested but I think you should get the point because we are not restoring the domain object but look it up from our local CDOView we can once more rely on CDOs clever memory management. Nice isn’t it?

XPath support to traverse your UI-DOM

This feature is part of UFaceKit sources since day one in the SVN-Repository but I added it not into the first nightly builds. I think the XPath support for UIs is a fairly unique feature of UFaceKit and the reflective API makes it extremly easy to implement it operations like e.g. applying changes to a many widgets.

package testproject;

import java.util.Iterator;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.ufacekit.core.xpath.common.XPathContext;
import org.eclipse.ufacekit.core.xpath.common.XPathContextFactory;
import org.eclipse.ufacekit.ui.core.UIDesktop;
import org.eclipse.ufacekit.ui.core.UIFactory;
import org.eclipse.ufacekit.ui.core.UIRunnable;
import org.eclipse.ufacekit.ui.core.UIWidget;
import org.eclipse.ufacekit.ui.core.controls.UIApplicationWindow;
import org.eclipse.ufacekit.ui.core.controls.UIButton;
import org.eclipse.ufacekit.ui.core.controls.UIComposite;
import org.eclipse.ufacekit.ui.core.controls.UIInputField;
import org.eclipse.ufacekit.ui.core.controls.UILabel;
import org.eclipse.ufacekit.ui.core.controls.UIApplicationWindow.ApplicationWindowUIInfo;
import org.eclipse.ufacekit.ui.core.controls.util.Rectangle;
import org.eclipse.ufacekit.ui.core.form.UIGridFormBuilder;
import org.eclipse.ufacekit.ui.core.layouts.GridLayoutData;
import org.eclipse.ufacekit.ui.core.layouts.UIFillLayout;
import org.eclipse.ufacekit.ui.core.layouts.GridLayoutData.Alignment;
import org.eclipse.ufacekit.ui.core.xpath.UFacekitXPathContextFactory;
import org.eclipse.ufacekit.ui.jface.core.JFaceFactory;
import org.eclipse.ufacekit.ui.uform.UBeanForm; 

public class Application implements IApplication {

  public Object start(IApplicationContext context) throws Exception {
    JFaceFactory factory = new JFaceFactory();
		
    final UIDesktop desktop = factory.newDesktop();
    desktop.runWithDefaultRealm(new UIRunnable<UIDesktop>() {
      @Override
      protected IStatus run(UIDesktop arg0) {
        createUI(arg0);
        return Status.OK_STATUS;
      }
    });
    desktop.run();

    return IApplication.EXIT_OK;
  }
	
  private void createUI(UIDesktop d) {
    UIFactory<?> f = d.getFactory();
		
    UIFillLayout l = f.newFillLayout();
    final UIApplicationWindow window = f.newApplicationWindow(d, new ApplicationWindowUIInfo(l));
    window.setText("UFaceKit - Hello World");
		
    UIComposite comp = f.newComposite(window, new UIComposite.CompositeUIInfo(null, f.newGridLayout(1)));
    UILabel label = f.newLabel(comp, new UILabel.LabelUIInfo(GridLayoutData.fillHorizontalData()));
    label.setText("Form Example");
		
    UBeanForm form = new UBeanForm(f);		
		
     UIGridFormBuilder builder = UIGridFormBuilder.newInstance(comp, GridLayoutData.fillHorizontalData(), form);
     builder.newLabel("Firstname");
     builder.newInputField(UIInputField.InputFieldBindingInfo.newTextFieldInfo(form.detailValue(Person.FIRSTNAME, String.class)) );
		
      builder.newLabel("Surname");
      builder.newInputField(UIInputField.InputFieldBindingInfo.newTextFieldInfo(form.detailValue(Person.SURNAME, String.class)) );
		
      UIButton button = f.newButton(comp, new UIButton.ButtonUIInfo(new GridLayoutData(Alignment.END, Alignment.DEFAULT)));
      button.setText("Save");
      button.setActionRunnable(new UIRunnable<UIButton>() {

      @Override
      protected IStatus run(UIButton b) {
        XPathContextFactory<UIWidget> factory = UFacekitXPathContextFactory.newInstance();
        XPathContext context = factory.newContext(b.getParent());
				
        Iterator<?> iterator = context.iterate("UIComposite/UIInputField");
        boolean flag = true;
        while( iterator.hasNext() ) {
          UIInputField field = (UIInputField) iterator.next();
          if( field.getText().equals("") ) {
            flag = false;
            field.getStyle().setBackground("#ff0000");	
          } else {
            field.getStyle().setBackgroundColor(null);
          }
        }
				
        if( ! flag ) {
          b.getDesktop().showErrorDialog(
            b.getWindow(), 
            "Validation Error", 
            "Required fields are marked read", 
            new Status(IStatus.ERROR, Activator.PLUGIN_ID, ""),
            null );
        }
				
        return Status.OK_STATUS;
      }
    });
    window.open();
    window.setBounds(new Rectangle(500, 400, 400, 250));
  }

  public void stop() {
    // nothing to do
  }
}

This creates an UI like this: