<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8177296879507503177</id><updated>2012-02-03T09:55:27.030+01:00</updated><category term='sandbox'/><category term='interceptor'/><category term='spring-rich'/><category term='form'/><category term='tutorial'/><title type='text'>Spring Rich Client Project</title><subtitle type='html'>This is the development blog of the Spring Rich Client Project Team.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://spring-rich.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8177296879507503177/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://spring-rich.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Peter De Bruycker</name><uri>http://www.blogger.com/profile/00755211011636109687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>2</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8177296879507503177.post-5962522838798625464</id><published>2008-01-14T08:44:00.000+01:00</published><updated>2008-12-11T15:36:37.763+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='interceptor'/><category scheme='http://www.blogger.com/atom/ns#' term='sandbox'/><category scheme='http://www.blogger.com/atom/ns#' term='spring-rich'/><category scheme='http://www.blogger.com/atom/ns#' term='form'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><title type='text'>Integrating xswingx Prompt</title><content type='html'>&lt;p&gt;In this tutorial you will learn how to create your own &lt;code&gt;FormComponentInterceptor&lt;/code&gt;, by integrating &lt;a href="http://code.google.com/p/xswingx/"&gt;xswingx&lt;/a&gt;. The xswingx project provides &lt;a href="http://designinginterfaces.com/Input_Prompt"&gt;input prompts&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;As our new interceptor will intercept text components, we can subclass the &lt;code&gt;TextComponentInterceptor&lt;/code&gt; class, which defines a &lt;code&gt;protected void processComponent(String propertyName, JTextComponent textComponent)&lt;/code&gt; method:&lt;br /&gt;&lt;pre class="source-code"&gt;public class PromptTextFieldFormComponentInterceptor extends TextComponentInterceptor {&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The following attributes are needed. The &lt;code&gt;MessageSource&lt;/code&gt; to fetch the prompt text, the &lt;code&gt;FormModel&lt;/code&gt; to scope our message key, and the prompt key to construct the message key:&lt;pre class="source-code"&gt;    private MessageSource messageSource;&lt;br /&gt;    private FormModel formModel;&lt;br /&gt;    private String promptKey;&lt;br /&gt;&lt;br /&gt;    public PromptTextFieldFormComponentInterceptor(FormModel formModel, MessageSource messageSource,&lt;br /&gt;                                                                 String promptKey) {&lt;br /&gt;        this.formModel = formModel;&lt;br /&gt;        this.messageSource = messageSource;&lt;br /&gt;        this.promptKey = promptKey;&lt;br /&gt;    }&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The &lt;code&gt;processComponent&lt;/code&gt; method will use the &lt;code&gt;MessageSource&lt;/code&gt; to find the prompt text (using the keys created by the &lt;code&gt;getMessageKeys&lt;/code&gt; method), and will use the xswingx &lt;code&gt;PromptSupport&lt;/code&gt; class to install the prompt on the &lt;code&gt;JTextComponent&lt;/code&gt;:&lt;br /&gt;&lt;pre class="source-code"&gt;    protected void processComponent(String propertyName, JTextComponent textComponent) {&lt;br /&gt;        String prompt = messageSource.getMessage(new DefaultMessageSourceResolvable(getMessageKeys(formModel,&lt;br /&gt;                propertyName), ""), Locale.getDefault());&lt;br /&gt;&lt;br /&gt;        if (StringUtils.hasText(prompt)) {&lt;br /&gt;            PromptSupport.setPrompt(prompt, textComponent);&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;And finally the &lt;code&gt;getMessageKeys&lt;/code&gt; method, which will create an array of message keys used to load the message. Two keys will be created, &lt;code&gt;formModelId.propertyName.promptKey&lt;/code&gt; and &lt;code&gt;propertyName.promptKey&lt;/code&gt;:&lt;br /&gt;&lt;pre class="source-code"&gt;    protected String[] getMessageKeys(FormModel formModel, String propertyName) {&lt;br /&gt;        return new String[] { formModel.getId() + "." + propertyName + "." + promptKey,&lt;br /&gt;                              propertyName + "." + promptKey };&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now define the interceptor in the &lt;code&gt;formComponentInterceptorFactory&lt;/code&gt; bean in your application context:&lt;pre class="source-code"&gt; &amp;lt;bean class="org.springframework.richclient.form.PromptTextFieldFormComponentInterceptorFactory"/&amp;gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;And add some messages to &lt;code&gt;messages.properties&lt;/code&gt;:&lt;pre class="source-code"&gt;firstName.prompt=&amp;lt;Enter the first name&amp;gt;&lt;br /&gt;lastName.prompt=&amp;lt;Enter the last name&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;This is the result:&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_MQEaj5HE4pU/R4sYadvCLFI/AAAAAAAAALk/Op-B1RfUFnQ/s1600-h/prompt.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_MQEaj5HE4pU/R4sYadvCLFI/AAAAAAAAALk/Op-B1RfUFnQ/s400/prompt.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5155241041393232978" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_MQEaj5HE4pU/R4sZWtvCLII/AAAAAAAAAL8/2NrjSYW8v-k/s1600-h/prompt2.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_MQEaj5HE4pU/R4sZWtvCLII/AAAAAAAAAL8/2NrjSYW8v-k/s400/prompt2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5155242076480351362" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8177296879507503177-5962522838798625464?l=spring-rich.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spring-rich.blogspot.com/feeds/5962522838798625464/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8177296879507503177&amp;postID=5962522838798625464' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8177296879507503177/posts/default/5962522838798625464'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8177296879507503177/posts/default/5962522838798625464'/><link rel='alternate' type='text/html' href='http://spring-rich.blogspot.com/2008/01/integrating-xswingx-prompt.html' title='Integrating xswingx Prompt'/><author><name>Peter De Bruycker</name><uri>http://www.blogger.com/profile/00755211011636109687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_MQEaj5HE4pU/R4sYadvCLFI/AAAAAAAAALk/Op-B1RfUFnQ/s72-c/prompt.png' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8177296879507503177.post-2388313309009912321</id><published>2008-01-07T09:15:00.000+01:00</published><updated>2008-12-11T15:36:38.727+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sandbox'/><category scheme='http://www.blogger.com/atom/ns#' term='spring-rich'/><category scheme='http://www.blogger.com/atom/ns#' term='form'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><title type='text'>How to use the ListSelectionDialogBinder</title><content type='html'>This tutorial is based on the Simple Sample.&lt;br /&gt;&lt;br /&gt;We will add new property "favorite fruit" to the &lt;code&gt;Contact&lt;/code&gt; class.&lt;br /&gt;&lt;br /&gt;First we create a new Fruit class:&lt;br /&gt;&lt;pre class="source-code"&gt;public class Fruit {&lt;br /&gt;    private String name;&lt;br /&gt;    public Fruit(String name) {&lt;br /&gt;        this.name = name;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public String getName() {&lt;br /&gt;        return name;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Then we add the &lt;code&gt;favoriteFruit&lt;/code&gt; property: &lt;pre class="source-code"&gt;public class Contact {&lt;br /&gt;    ...&lt;br /&gt;    private Fruit favoriteFruit;&lt;br /&gt;    ...&lt;br /&gt;    public Fruit getFavoriteFruit() {&lt;br /&gt;        return favoriteFruit;&lt;br /&gt;    }&lt;br /&gt;    public void setFavoriteFruit(Fruit fruit) {&lt;br /&gt;        this.favoriteFruit = fruit;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;In the &lt;code&gt;richclient-application-context.xml&lt;/code&gt; we have to define the &lt;code&gt;ListSelectionDialogBinder&lt;/code&gt; for properties of the type &lt;code&gt;Fruit&lt;/code&gt;:&lt;pre class="source-code"&gt;&lt;br /&gt;&amp;lt;bean id="binderSelectionStrategy" class="org.springframework.richclient.form.binding.swing.SwingBinderSelectionStrategy"&amp;gt;&lt;br /&gt;    &amp;lt;property name="bindersForPropertyTypes"&amp;gt;&lt;br /&gt;        &amp;lt;map&amp;gt;&lt;br /&gt;            &amp;lt;entry&amp;gt;&lt;br /&gt;                &amp;lt;key&amp;gt;&amp;lt;value type="java.lang.Class"&amp;gt;&lt;strong&gt;org.springframework.richclient.samples.simple.domain.Fruit&lt;/strong&gt;&amp;lt;/value&amp;gt;&amp;lt;/key&amp;gt;&lt;br /&gt;                &amp;lt;bean class="&lt;strong&gt;org.springframework.richclient.selection.binding.ListSelectionDialogBinder&lt;/strong&gt;"/&amp;gt;&lt;br /&gt;            &amp;lt;/entry&amp;gt;&lt;br /&gt;        &amp;lt;/map&amp;gt;&lt;br /&gt;    &amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/pre&gt;&lt;br /&gt;The only thing that's left is the &lt;code&gt;ContactForm&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;For the &lt;code&gt;ListSelectionDialogBinder&lt;/code&gt; it's necessary to build a context to feed to the binding.&lt;br /&gt;&lt;br /&gt;A context is nothing more than a &lt;code&gt;Map&lt;/code&gt;.&lt;pre class="source-code"&gt;    Map fruitContext = new HashMap();&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here we build the list of fruits the user can choose from, but in real life this will probably come from the database ...&lt;pre class="source-code"&gt;    List fruits = new ArrayList();&lt;br /&gt;    fruits.add(new Fruit("apple"));&lt;br /&gt;    fruits.add(new Fruit("banana"));&lt;br /&gt;    fruits.add(new Fruit("kiwi"));&lt;br /&gt;    fruits.add(new Fruit("orange"));&lt;br /&gt;    fruits.add(new Fruit("pear"));&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We use the fruit in the selectable items:&lt;pre class="source-code"&gt;    fruitContext.put(ListSelectionDialogBinder.SELECTABLE_ITEMS_KEY, fruits);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The following code will use the name of the fruit as label, and will show "&amp;lt;no&amp;gt;" for &lt;code&gt;null&lt;/code&gt; values:&lt;pre class="source-code"&gt;    fruitContext.put(ListSelectionDialogBinder.LABEL_PROVIDER_KEY, new LabelProvider() {&lt;br /&gt;        public String getLabel(Object item) {&lt;br /&gt;            Fruit bean = (Fruit) item;&lt;br /&gt;            return bean == null ? "&lt;no&gt;" : bean.getName();&lt;br /&gt;        }&lt;br /&gt;    });&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you want filtering, add the following entries. This will allow the user to filter the dialog on the name property of the fruit.&lt;pre class="source-code"&gt;    fruitContext.put(ListSelectionDialogBinder.FILTERED_KEY, Boolean.TRUE);&lt;br /&gt;    fruitContext.put(ListSelectionDialogBinder.FILTER_PROPERTIES_KEY,&lt;br /&gt;                                             new String[] { "name" });&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And finally we add the binding to the form:&lt;pre class="source-code"&gt;    formBuilder.addSeparator("Fun stuff");&lt;br /&gt;    formBuilder.row();&lt;br /&gt;    formBuilder.add(getBindingFactory().createBinding("favoriteFruit", fruitContext),&lt;br /&gt;                                             "colSpan=1");&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And this is the result:&lt;br /&gt;&lt;br /&gt;Nothing selected:&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_MQEaj5HE4pU/R4HyuNvCLBI/AAAAAAAAALA/-lfWBkwwy-4/s1600-h/listselectiondialogbinding1.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5152666324463397906" style="CURSOR: hand" alt="" src="http://2.bp.blogspot.com/_MQEaj5HE4pU/R4HyuNvCLBI/AAAAAAAAALA/-lfWBkwwy-4/s320/listselectiondialogbinding1.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And when we click on the select button:&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_MQEaj5HE4pU/R4H01tvCLCI/AAAAAAAAALI/6QAD9LCcF7g/s1600-h/listselectiondialogbinding2.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5152668652335672354" style="CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_MQEaj5HE4pU/R4H01tvCLCI/AAAAAAAAALI/6QAD9LCcF7g/s320/listselectiondialogbinding2.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And select "orange" we get this:&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_MQEaj5HE4pU/R4H1bNvCLEI/AAAAAAAAALY/L2de5y8XLfQ/s1600-h/listselectiondialogbinding3.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5152669296580766786" style="CURSOR: hand" alt="" src="http://2.bp.blogspot.com/_MQEaj5HE4pU/R4H1bNvCLEI/AAAAAAAAALY/L2de5y8XLfQ/s320/listselectiondialogbinding3.png" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8177296879507503177-2388313309009912321?l=spring-rich.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spring-rich.blogspot.com/feeds/2388313309009912321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8177296879507503177&amp;postID=2388313309009912321' title='36 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8177296879507503177/posts/default/2388313309009912321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8177296879507503177/posts/default/2388313309009912321'/><link rel='alternate' type='text/html' href='http://spring-rich.blogspot.com/2008/01/how-to-use-listselectiondialogbinder.html' title='How to use the ListSelectionDialogBinder'/><author><name>Peter De Bruycker</name><uri>http://www.blogger.com/profile/00755211011636109687</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_MQEaj5HE4pU/R4HyuNvCLBI/AAAAAAAAALA/-lfWBkwwy-4/s72-c/listselectiondialogbinding1.png' height='72' width='72'/><thr:total>36</thr:total></entry></feed>
