Marco van Meegen
Senior IT-Consulting - React Typescript J2EE Java Eclipse SQL ...and more


designelement missing
designelement missing
 
spacer missing
spacer missing
spacer missing
RCP Forms Plugin

Eclipse RCP forms are very limited for business application demands; this project aims at enhancing UI Forms, Data Binding and puts them together to offer a profound framework for creating, binding and validating forms in Eclipse.

It will be tested against RCP and RAP platforms; thus all Forms created with RCP Forms will run without changes in a Web Browser or in an RCP Application/Eclipse Workbench.

Content

  1. Features
  2. Problems with existing Technology
  3. Concepts
  4. Runtime
  5. Examples
  6. Download
  7. Getting Started

The Sourceforge Wiki contains more details and most up-to-date information.

Features

  • dead-simple development of forms with data binding and validation
  • avoids low level error prone code e.g. for listener registration/deregistration
  • 80/20: 80% of use case is written with one line using default values, e.g. if you bind a text field to a java.util.Date property, the text field will automatically be converted to a date and vice versa; if no date is entered an error marker will be shown
  • 100% based on Eclipse standards, no new concepts, just a thin layer on top, e.g. above feature is available through standard Eclipse Databinding, but using a unifying API so the developer need not know any details about update strategies, converters and stuff
  • automatic binding of enum properties, e.g. binding against a combo box will automatically fill the combo list with all possible enum values and do all the low-level sync stuff. It really is one line of code !
  • automatic handling of Table Viewing and Editing, just configure the columns and related properties and if they should be editable, the editor type
  • can run standalone, on osgi and *RAP
  • Forms can be easily embedded into Eclipse Editors, Viewers, Wizards and Dialogs
  • makes no assumptions on your data model, through a ModelAdapter all data models can be used which can fire change events
  • model adapters can deliver additional information, e.g. extract validation constraints like field-lengths, regular expressions for email etc. directly from your specific data model or provide possible values for object references via range adapters (this is cool for EMF-based models)

* features are only planned yet

Problems with existing Technology

The motivation for RCP Forms was a lack of comfort and features of existing technologies: UI Forms, Databinding, SWT Widgets. There is no simple to learn API which enables a newbie to develop forms which offer data binding, validation and widget state management without digging into details of the involved Eclipse technologies.

Here is a list of shortcomings:

  • UI Forms have a nice look and feel, but state of widgets does not render correctly anymore, e.g. disabled components dont look disabled
  • Error Markers and Decorations for Fields don't work easily with scrolled Forms and expandable sections
  • Tables/Table Viewers cannot edit and traverse focus correctly out-of-the-box
  • Data Bindings documentation is very sparse and not too helpful
  • Data Binding does not support e.g. Enumerations or Radio Groups out of the box
  • Widget States and Decorations (e.g. error markers, required marker) should be supported by widgets directly and by all widgets consistently
  • UI Logic should be easily unit testable
  • UI Forms have a confusing/not well defined life cycle, managed forms are weak in functionality#
  • There are a lot of different UI concepts in Eclipse originating from different areas, e.g. Viewparts, Editor Parts, Multipart Editors, Form Parts, Wizard Pages. UI Forms are not easily suitable for all Eclipse artefacts
  • Form Layout on resize is a complex topic, there is no best practice on how to do that
  • Text widgets usually adapt their size to the contained text on layout, not to the maximum nr of characters allowed
  • no direct support for validation rules
  • no best practice on binding UI to data
  • there is no standard calendar widget for entering dates
  • Table Cell Editors for Tables are error-prone and difficult to use, currently only Combo and Text are available
  • ... and and and ...

Due to these drawbacks most Business Applications have to write their own framework/extensions to the existing technology to get the job done of writing forms.

This might damage RCP reputation and is repeated effort which produces different standards. This project is built on experience using RCP in a big financial application project and aims at solving these problems so programmers can focus on building their UI and business logic instead of solving deficiencies in the RCP technology used.

Concepts

RCPForms is a very thin layer on top of standard eclipse APIs focused on offering an easy to learn API which is based a lot on defaults (80% case should not need any configuration parameters) and best practices (e.g. for list-based controls you would like to use a viewer instead of programming directly against the SWT control).

The Presentation Model approach separates UI from Data. UI code mainly consists of creating controls, layout and binding against data and ui state attributes in the presentation model.

  • Java Beans, EMF and any other Object to be used as presentation model, all model dependencies factored out into a model adapter
  • Wrappers around SWT Widgets to enhance with state/decoration rendering and factory, easier usage through subclasses like RCPRadioButton, RCPRadioGroup
  • Eclipse Data binding also used for UI state binding
  • support for automatic handling of enumerations, arbitrary enumeration datatypes can be used via adapter, e.g. extensible Enumerations where Literals might be loaded from a Database. Default support for java enums included.
  • Table Configuration for easy creation of editable, navigable tables and binding against Lists of beans.
  • Validation of field values with error markers using Eclipse Databinding
  • Validator concept where validators declare their field dependencies and validation state is managed by the framework
  • RCP Forms are designed in a way that the same form class can be used in all contexts (like Dialog, Wizardpage, View) with same behavior
  • Forms are composed of FormParts, which are reusable in other locations

Runtime

Forms are supposed to be able to run in three different environments; currently focus is on 1,2 but the final API is planned to be able to run as RAP application too:

  1. standalone as SWT application
  2. in an osgi runtime as RCP application
  3. *in a web browser as RAP application

* features are only planned yet

Examples

Creating a form should be simple, minimum knowledge about the internal workings of JFace or Databinding should be needed:

  1. Define your presentation model (which is a bean containing properties for data to be displayed and properties for ui state like enabled/disabled).
  2. Define the UI elements and their associated layout
  3. Bind UI value and state to presentation model properties
  4. Optionally: create validators for properties; once defined all properties are automatically tracked for changes and error markers are displayed on all ui controls displaying properties which affect the validator
  5. Optionally: structure your model into reusable units (form parts)
public class ExampleFormPart extends RCPFormPart
{
    private RCPRadioGroup radioGroup = new RCPRadioGroup("Gender again:",false);

    private RCPText name = new RCPText("Name:");

    private RCPText age = new RCPText("Age:");

    private RCPCombo genderCombo = new RCPCombo("Gender:");

    private RCPDatePicker birthdate = new RCPDatePicker("Birthdate:");

    public void createUI(FormToolkit formToolkit, Composite parent)
    {

        final RCPSection mainSection = new RCPSection("RCPForms Example Widgets and Binding");
        // create different widgets and sections
        GridBuilder sectionBuilder = new GridBuilder(formToolkit, parent, 2)
                .addContainer(mainSection,3);
        sectionBuilder.addLine(name, 30);
        sectionBuilder.addLine(age, 3);
        sectionBuilder.addLine(genderCombo);
        sectionBuilder.addLine(birthdate);
        sectionBuilder.fill(1).addLine(radioGroup);
        // create buttons for values using label provider to create label
        radioGroup.createRadioButtons(TestModel.Gender.values(), new LabelProvider());
    }

    public void bind(ValidationManager bm, Object modelBean)
    {
        bm.bindValue(name, modelBean, TestModel.P_Name);
        bm.bindValue(age, modelBean, TestModel.P_Age);
        bm.bindValue(genderCombo, modelBean, TestModel.P_Gender);
        bm.bindValue(birthdate, modelBean, TestModel.P_BirthDate);
        bm.bindValue(radioGroup, modelBean, TestModel.P_Gender);
    }

    public static void main(String[] args)
    {

        final TestModel model = new TestModel();
        final ExampleFormPart part = new ExampleFormPart();
        model.addPropertyChangeListener(new PropertyChangeListener()
        {
            public void propertyChange(PropertyChangeEvent evt)
            {
                System.out.println("Model changed: " + model);
            }
        });
        RCPForm form = new RCPForm("Quickstart Example", part);
        form.setInput(new Object[]{model});
        form.startTestShell();
    }

    @Override
    public void setState(EControlState state, boolean value)
    {
        // not needed here
    }
}

This code creates and binds (automatically synchronizes widget changes and bean property changes in both directions) the following form against a standard Java Bean:

If wrong values are entered automatically an error marker shows up as shown below:

Creating additional validators and error markers is a snap. Create a validator, define its dependencies and logic.

It will automatically be revalidated if from or to properties change and error markers will be set to all widgets which are bound to from or to property:

 		viewModelManager.addValidator(this, new AbstractModelValidator() {
			public Object[] getProperties() {
				return new String[]{ TestModel.P_From, TestModel.P_To };
			}
			public IStatus validate(Object value) {
				TestModel model = (TestModel) value;
				IStatus result = ok();
				if (model.getFrom() != null && model.getTo() != null && model.getFrom().after(model.getTo())) {
						result = error(From Date must be earlier than To Date");
					}
				}
				return result;
			}
		});

Download

The project is hosted on source forge, releases are available for download here.

Getting Started

Make sure you have at least Eclipse 3.3. Since Databinding is needed by rcpforms which was introduced in Eclipse 3.3, it will NOT WORK with earlier versions of Eclipse and is only tested with 3.3. (you might try adding databinding plugins to 3.2, please mail me if you succeeded so I can add instructions here).

To get started with RCPForms, download the release source zip.

Import the downloaded zip contents directly in your workspace using "Import-->Existing Projects into Workspace-->Select Archive File net.sf.rcpforms_x_y_z.zip, check the rcpforms and test plugins.

In the de.mvmsoft.rcpforms.test plugin open the class RCPWidgetsManualTest. Select "Run as Java Application" and voila, you should see the test application which demonstrates the main features of the framework.

See http://rcpforms.wiki.sourceforge.net/MainGettingStarted and the User Manual for more details.

Then have a look at the Example plugin . This is an easy to understand example which gives you an idea of what is needed to get your form running.

Currently RCPForms is beta, thus API might change; especially the Builder is very rudimentary and does not support much of the GridLayout features. Enhance it with additional methods to suite your needs and contribute back. Thanks !

 

designelement missing
spacer missing
©Copyright 2002-2011 Marco van Meegen All Rights Reserved
For more information feel free to Contact Me

Impressum und Disclaimer

spacer missing