Menu

FormGenerator

Remo

Form Generator

Since RCPForms API is specifically designed to create business forms with low noise, you don't really need a generator.

But for a quick start, fast prototypes, convincing your boss to use RCPForms, a generator might be of help.

Thus we created one using ingenious XText techology.

How it works

We have created a domain specific language for describing forms. After installing the generator into Eclipse, create a file with extension ".frm", e.g. SimpleSample.frm.

Open it (should open by default with the Form DSL Editor) and write your declarative UI (yes, this was promised for e4, but with rcpforms you have it now, and much more specifically tailored to what you need !).

The editor has code completion, syntax highlighting, error markers, templates - everything you expect from Eclipse Editors. After finishing, press "Generate Java" from the context menu and the source code is generated.

Here a simple example using the most important widgets supported by the generator as DSL:

package net.sf.rcpforms.simplesample.generatedexample;

view TestView form=TestForm;
form TestForm label="Test Form" parts=TestFormPart,TestFormPart input=TestFormDataModel,TestFormDataModel;

formpart TestFormPart input=net.sf.rcpforms.simplesample.example.TestFormDataModel columns=1 defaultBuilderMethod="addLine($)"
{
  Section section builderMethod="addContainer($,3)" 
  {
    Text name property="name" label="Name: " mandatory;
    Text number property="streetNumber" label="Number: ";
    Combo country property="country" label="Country: ";
    DatePicker birthDate property="birthdate" label="Birthdate: ";
    Checkbox check property="smoker" label="Smoker";
      Text state property="state" label="State:" readonly;
    RadioGroup group property="state" label="Status" builderMethod="addContainerSpan($,1,3,1,false)" 
    {
        RadioButton rb1 label="new";
        RadioButton rb2 label="work in progress";
        RadioButton rb3 label="done";
      }
  }
}

This creates a form part with a main method which can be bound to the TestFormDataModel? listed below and results in this:

Generated Form Part

The Form DSL

Currently the DSL is defined by this grammar (subject to be extended in the future):

Model:

'package' ID ('.' ID) ';' (Type);

Type:

Form|View|FormPart?;

Form:

'form' ID 'label' '=' STRING 'parts' '=' IDList ('input' '=' IDList)? ';';

View:

'view' ID 'form' '=' ID ('input' '=' IDList)? ';';

IDList:

ID|ID ',' IDList;

FormPart?:

'formpart' ID ('input' '=' ID ('.' ID)*)? 'columns' '=' INT 'defaultBuilderMethod' '=' STRING Composite;

Composite:

'{' (UIElement)+ '}';

UIElement:

Section|RadioGroup?|Widget;

RadioGroup?:

type='RadioGroup?' WidgetAttributes? Composite;

Section:

'Section' ID ('label' '=' STRING)? 'builderMethod' '=' STRING Composite;

Widget:

'Text' WidgetAttributes? ';' |'Combo' WidgetAttributes? ';' |'Checkbox' WidgetAttributes? ';' |'Button' WidgetAttributes? ';' |'RadioButton?' WidgetAttributes? ';' |'DatePicker?' WidgetAttributes? ';';

WidgetAttributes?:

ID ('property' '=' STRING)? ('label' '=' STRING)? ('mandatory')? ('readonly')? ('disabled')? ('recommended')? ('builderMethod' '=' STRING)?;

Installing the Generator

Currently there is no simple Generator feature install available, since it heavily depends on XText, ANTLR and modeling project components, e.g. the Galileo 3.5SR1 Modeling Tools Package is a very good start.

Then follow the XText installation instructions at http://www.eclipse.org/Xtext/download/; the Generator was developed using XText 0.7.2 which currently needs Eclipse 3.5 and several modeling components. You should use the ANTLR parser as described since this is not bundled with the package.

  • get an eclipse installation running with XText 0.7.2 and MWE e.g. Galileo 3.5SR1 Modeling Tools Package
  • get the ANTLR parser from the itemis update site
  • Checkout all projects under trunk/generator from rcpforms subversion into your workspace.
  • start a runtime workbench, create a new file with suffix .frm
  • open it and check if it has syntax highlighting (should open with FormDsl? Editor)
  • write your spec
  • In editor context menu press "Generate Java" to create the source code; it will go into the same directory as the template

TODO: find a clean installer way and supported eclipse versions for all this stuff

The Model

The model needed to bind the formpart above is (modeled as JavaBean?):

package net.sf.rcpforms.simplesample.example;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TestFormDataModel 
{

    protected PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);

    public static final String P_Name = "name";
    public static final String P_StreetNumber = "streetNumber";

    public static final String P_Country = "country";
    public static final String P_Birthdate = "birthdate";
    public static final String P_Smoker = "smoker";
    public static final String P_State= "state";

    private String name;
    private Integer streetNumber;
    public enum Country {GERMANY, FRANCE, US, UK};
    private Country country;
    private Date birthdate;
    private boolean smoker;
    private String state;

    public boolean isSmoker() {
        return smoker;
    }

    public void setSmoker(boolean smoker) {
        Object oldValue = this.smoker;
        this.smoker = smoker;
        propertyChangeSupport.firePropertyChange(TestFormDataModel.P_Smoker, oldValue, smoker);
    }

    private SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy");

    public TestFormDataModel()
    {
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        Object oldValue = this.name;
        this.name = name;
        propertyChangeSupport.firePropertyChange(TestFormDataModel.P_Name, oldValue, name);
    }

    public String getState()
    {
        return state;
    }

    public void setState(String state)
    {
        Object oldValue = this.state;
        this.state= state;
        propertyChangeSupport.firePropertyChange(TestFormDataModel.P_State, oldValue, state);
    }

    public Integer getStreetNumber()
    {
        return streetNumber;

    }

    public void setStreetNumber(Integer streetNumber)
    {
        Object oldValue = this.streetNumber;
        this.streetNumber = streetNumber;
        propertyChangeSupport.firePropertyChange(TestFormDataModel.P_StreetNumber, oldValue,
                streetNumber);
    }

    public Country getCountry()
    {
        return country;
    }

    public void setCountry(Country country)
    {
        Object oldValue = this.country;
        this.country = country;
        propertyChangeSupport.firePropertyChange(TestFormDataModel.P_Country, oldValue, country);
    }

    public Date getBirthdate()
    {
        return birthdate;
    }

    public void setBirthdate(Date birthdate)
    {
        Object oldValue = this.birthdate;
        this.birthdate = birthdate;
        propertyChangeSupport.firePropertyChange(TestFormDataModel.P_Birthdate, oldValue, birthdate);
    }

    public String toString()
    {
        StringBuilder sb = new StringBuilder(this.getClass().getCanonicalName());
        sb.append(", Name: ").append(name).append(" - ").append(
                birthdate == null ? "not set" : dateFormatter.format(birthdate)).append(", ");
        sb.append(" ").append(streetNumber).append(", ");
        sb.append("Country: ").append(country).append(", ");
        sb.append("Smoker: ").append(smoker).append(", ");
        return sb.toString();
    }

    public void addPropertyChangeListener(PropertyChangeListener listener)
    {
        propertyChangeSupport.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener)
    {
        propertyChangeSupport.removePropertyChangeListener(listener);
    }

}

Related

Documentation: Home
Documentation: MainGettingStarted

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.