Spring Rich Client Project

This is the development blog of the Spring Rich Client Project Team.

Monday, January 14, 2008

Integrating xswingx Prompt

In this tutorial you will learn how to create your own FormComponentInterceptor, by integrating xswingx. The xswingx project provides input prompts.


As our new interceptor will intercept text components, we can subclass the TextComponentInterceptor class, which defines a protected void processComponent(String propertyName, JTextComponent textComponent) method:

public class PromptTextFieldFormComponentInterceptor extends TextComponentInterceptor {


The following attributes are needed. The MessageSource to fetch the prompt text, the FormModel to scope our message key, and the prompt key to construct the message key:

    private MessageSource messageSource;
private FormModel formModel;
private String promptKey;

public PromptTextFieldFormComponentInterceptor(FormModel formModel, MessageSource messageSource,
String promptKey) {
this.formModel = formModel;
this.messageSource = messageSource;
this.promptKey = promptKey;
}


The processComponent method will use the MessageSource to find the prompt text (using the keys created by the getMessageKeys method), and will use the xswingx PromptSupport class to install the prompt on the JTextComponent:

    protected void processComponent(String propertyName, JTextComponent textComponent) {
String prompt = messageSource.getMessage(new DefaultMessageSourceResolvable(getMessageKeys(formModel,
propertyName), ""), Locale.getDefault());

if (StringUtils.hasText(prompt)) {
PromptSupport.setPrompt(prompt, textComponent);
}
}


And finally the getMessageKeys method, which will create an array of message keys used to load the message. Two keys will be created, formModelId.propertyName.promptKey and propertyName.promptKey:

    protected String[] getMessageKeys(FormModel formModel, String propertyName) {
return new String[] { formModel.getId() + "." + propertyName + "." + promptKey,
propertyName + "." + promptKey };
}
}


Now define the interceptor in the formComponentInterceptorFactory bean in your application context:

 <bean class="org.springframework.richclient.form.PromptTextFieldFormComponentInterceptorFactory"/>


And add some messages to messages.properties:

firstName.prompt=<Enter the first name>
lastName.prompt=<Enter the last name>



This is the result:


Monday, January 7, 2008

How to use the ListSelectionDialogBinder

This tutorial is based on the Simple Sample.

We will add new property "favorite fruit" to the Contact class.

First we create a new Fruit class:
public class Fruit {
private String name;
public Fruit(String name) {
this.name = name;
}

public String getName() {
return name;
}
}

Then we add the favoriteFruit property:
public class Contact {
...
private Fruit favoriteFruit;
...
public Fruit getFavoriteFruit() {
return favoriteFruit;
}
public void setFavoriteFruit(Fruit fruit) {
this.favoriteFruit = fruit;
}
}

In the richclient-application-context.xml we have to define the ListSelectionDialogBinder for properties of the type Fruit:

<bean id="binderSelectionStrategy" class="org.springframework.richclient.form.binding.swing.SwingBinderSelectionStrategy">
<property name="bindersForPropertyTypes">
<map>
<entry>
<key><value type="java.lang.Class">org.springframework.richclient.samples.simple.domain.Fruit</value></key>
<bean class="org.springframework.richclient.selection.binding.ListSelectionDialogBinder"/>
</entry>
</map>
</property>
</bean>

The only thing that's left is the ContactForm.

For the ListSelectionDialogBinder it's necessary to build a context to feed to the binding.

A context is nothing more than a Map.
    Map fruitContext = new HashMap();


Here we build the list of fruits the user can choose from, but in real life this will probably come from the database ...
    List fruits = new ArrayList();
fruits.add(new Fruit("apple"));
fruits.add(new Fruit("banana"));
fruits.add(new Fruit("kiwi"));
fruits.add(new Fruit("orange"));
fruits.add(new Fruit("pear"));


We use the fruit in the selectable items:
    fruitContext.put(ListSelectionDialogBinder.SELECTABLE_ITEMS_KEY, fruits);


The following code will use the name of the fruit as label, and will show "<no>" for null values:
    fruitContext.put(ListSelectionDialogBinder.LABEL_PROVIDER_KEY, new LabelProvider() {
public String getLabel(Object item) {
Fruit bean = (Fruit) item;
return bean == null ? "" : bean.getName();
}
});


If you want filtering, add the following entries. This will allow the user to filter the dialog on the name property of the fruit.
    fruitContext.put(ListSelectionDialogBinder.FILTERED_KEY, Boolean.TRUE);
fruitContext.put(ListSelectionDialogBinder.FILTER_PROPERTIES_KEY,
new String[] { "name" });


And finally we add the binding to the form:
    formBuilder.addSeparator("Fun stuff");
formBuilder.row();
formBuilder.add(getBindingFactory().createBinding("favoriteFruit", fruitContext),
"colSpan=1");


And this is the result:

Nothing selected:


And when we click on the select button:


And select "orange" we get this: