001    package org.springframework.richclient.samples.showcase.util;
002    
003    import java.beans.PropertyChangeEvent;
004    import java.beans.PropertyChangeListener;
005    import java.util.Set;
006    
007    import javax.swing.JTextArea;
008    
009    import org.springframework.binding.form.FormModel;
010    import org.springframework.binding.form.ValidatingFormModel;
011    import org.springframework.richclient.command.AbstractCommand;
012    import org.springframework.richclient.command.ActionCommand;
013    import org.springframework.richclient.command.ToggleCommand;
014    import org.springframework.richclient.form.AbstractForm;
015    
016    /**
017     * A Form with a {@link JTextArea} that can be used to show some useful
018     * messages. Can be used to show events to clarify and examine how user input is
019     * handled. Note that the actual TextArea should be inserted by the surrounding
020     * component/dialog. This to be able to reuse the textArea for various purposes.
021     *
022     * @author Jan Hoskens
023     */
024    public abstract class AbstractReporterForm extends AbstractForm implements Reporter {
025            private JTextArea messageArea;
026    
027            private ActionCommand printFormObjectCommand;
028    
029            private ActionCommand printFormModelCommand;
030    
031            private ActionCommand printFieldsCommand;
032    
033            private StateSynchronizingToggleCommand enableCommand;
034    
035            private StateSynchronizingToggleCommand readOnlyCommand;
036    
037            private StateSynchronizingToggleCommand validatingCommand;
038    
039            private ToggleCommand logFormModelPropertyChangeCommand;
040    
041            private PropertyChangeListener formModelPropertyChangeListener = new LogPropertyChangeListener();
042    
043            public AbstractReporterForm(FormModel formModel) {
044                    super(formModel);
045            }
046    
047            public AbstractReporterForm(FormModel formModel, String id) {
048                    super(formModel, id);
049            }
050    
051            /**
052             * Set the textArea to write messages to.
053             */
054            public void setMessageArea(JTextArea messageArea) {
055                    this.messageArea = messageArea;
056            }
057    
058            /**
059             * Returns the textArea to append info.
060             */
061            public JTextArea getMessageArea() {
062                    return messageArea;
063            }
064    
065            /**
066             * Print the backing form object details. Default behaviour is to call
067             * toString() on the formObject.
068             */
069            public StringBuilder getFormObjectDetails(StringBuilder builder, FormModel formModel) {
070                    builder.append("[FORMOBJECT " + formModel.getId() + "] ");
071                    builder.append(formModel.getFormObject());
072                    builder.append("\n");
073                    return builder;
074            }
075    
076            /**
077             * Print all the values from the valueModels in the formModel. Default
078             * behaviour is to iterate over all fields and print their value.
079             */
080            public StringBuilder getFieldsDetails(StringBuilder builder, FormModel formModel) {
081                    builder.append("[FIELDS " + formModel.getId() + "] ");
082                    Set<String> fieldNames = formModel.getFieldNames();
083                    for (String fieldName : fieldNames) {
084                            builder.append(fieldName).append(" = ");
085                            builder.append(formModel.getValueModel(fieldName).getValue());
086                            builder.append(", ");
087                    }
088                    builder.append("\n");
089                    return builder;
090            }
091    
092            public StringBuilder getFormModelDetails(StringBuilder builder, FormModel formModel) {
093                    builder.append("[FORMMODEL " + formModel.getId() + "] ");
094                    builder.append(formModel.toString());
095                    builder.append("\n");
096                    return builder;
097            }
098    
099            public ActionCommand getPrintFormObjectCommand() {
100                    if (printFormObjectCommand == null) {
101                            printFormObjectCommand = new ActionCommand(getPrintFormObjectCommandFaceDescriptorId()) {
102    
103                                    protected void doExecuteCommand() {
104                                            getMessageArea().append(getFormObjectDetails(new StringBuilder(), getFormModel()).toString());
105                                    }
106                            };
107                            getCommandConfigurer().configure(printFormObjectCommand);
108                    }
109                    return printFormObjectCommand;
110            }
111    
112            public ActionCommand getPrintFieldsCommand() {
113                    if (printFieldsCommand == null) {
114                            printFieldsCommand = new ActionCommand(getPrintFieldsCommandFaceDescriptorId()) {
115    
116                                    protected void doExecuteCommand() {
117                                            getMessageArea().append(getFieldsDetails(new StringBuilder(), getFormModel()).toString());
118                                    }
119                            };
120                            getCommandConfigurer().configure(printFieldsCommand);
121                    }
122                    return printFieldsCommand;
123            }
124    
125            public ActionCommand getPrintFormModelCommand() {
126                    if (printFormModelCommand == null) {
127                            printFormModelCommand = new ActionCommand(getPrintFormModelCommandFaceDescriptorId()) {
128    
129                                    protected void doExecuteCommand() {
130                                            getMessageArea().append(getFormModelDetails(new StringBuilder(), getFormModel()).toString());
131                                    }
132                            };
133                            getCommandConfigurer().configure(printFormModelCommand);
134                    }
135                    return printFormModelCommand;
136            }
137    
138            public StateSynchronizingToggleCommand getReadOnlyFormModelCommand() {
139                    if (readOnlyCommand == null) {
140                            readOnlyCommand = new StateSynchronizingToggleCommand(getReadOnlyCommandFaceDescriptorId()) {
141                                    @Override
142                                    protected void doOnSelection() {
143                                            getFormModel().setReadOnly(true);
144                                    }
145    
146                                    @Override
147                                    protected void doOnDeselection() {
148                                            getFormModel().setReadOnly(false);
149                                    }
150                            };
151                            readOnlyCommand.setSelected(getFormModel().isReadOnly());
152                            getFormModel().addPropertyChangeListener(FormModel.READONLY_PROPERTY,readOnlyCommand);
153                            getCommandConfigurer().configure(readOnlyCommand);
154                    }
155                    return readOnlyCommand;
156            }
157    
158            public StateSynchronizingToggleCommand getEnableFormModelCommand() {
159                    if (enableCommand == null) {
160                            enableCommand = new StateSynchronizingToggleCommand(getEnableCommandFaceDescriptorId()) {
161                                    @Override
162                                    protected void doOnSelection() {
163                                            getFormModel().setEnabled(true);
164                                    }
165    
166                                    @Override
167                                    protected void doOnDeselection() {
168                                            getFormModel().setEnabled(false);
169                                    }
170                            };
171                            enableCommand.setSelected(getFormModel().isEnabled());
172                            getFormModel().addPropertyChangeListener(FormModel.ENABLED_PROPERTY,enableCommand);
173                            getCommandConfigurer().configure(enableCommand);
174                    }
175                    return enableCommand;
176            }
177    
178            public ToggleCommand getValidatingFormModelCommand() {
179                    if (validatingCommand == null) {
180                            validatingCommand = new StateSynchronizingToggleCommand(getValidatingCommandFaceDescriptorId()) {
181                                    @Override
182                                    protected void doOnSelection() {
183                                            getFormModel().setValidating(true);
184                                    }
185    
186                                    @Override
187                                    protected void doOnDeselection() {
188                                            getFormModel().setValidating(false);
189                                    }
190                            };
191                            validatingCommand.setSelected(getFormModel().isValidating());
192                            getFormModel().addPropertyChangeListener(ValidatingFormModel.VALIDATING_PROPERTY,validatingCommand);
193                            getCommandConfigurer().configure(validatingCommand);
194                    }
195                    return validatingCommand;
196            }
197    
198            public ToggleCommand getLogFormModelPropertyChangeCommand() {
199                    if (logFormModelPropertyChangeCommand == null) {
200                            logFormModelPropertyChangeCommand = new ToggleCommand(
201                                            getLogFormModelPropertyChangeCommandFaceDescriptorId()) {
202                                    @Override
203                                    protected void onSelection() {
204                                            registerFormModelPropertyChangeListener();
205                                    }
206    
207                                    @Override
208                                    protected void onDeselection() {
209                                            unregisterFormModelPropertyChangeListener();
210                                    }
211                            };
212                            getCommandConfigurer().configure(logFormModelPropertyChangeCommand);
213                    }
214                    return logFormModelPropertyChangeCommand;
215            }
216    
217            public AbstractCommand[] getReporterCommands() {
218                    return new AbstractCommand[] { getPrintFormObjectCommand(), getPrintFormModelCommand(),
219                                    getPrintFieldsCommand(), getCommitCommand(), getNewFormObjectCommand(), getRevertCommand(),
220                                    getLogFormModelPropertyChangeCommand() };
221            }
222    
223            public void registerFormModelPropertyChangeListener() {
224                    ValidatingFormModel formModel = getFormModel();
225                    formModel.addPropertyChangeListener(FormModel.COMMITTABLE_PROPERTY, formModelPropertyChangeListener);
226                    formModel.addPropertyChangeListener(FormModel.DIRTY_PROPERTY, formModelPropertyChangeListener);
227                    formModel.addPropertyChangeListener(FormModel.ENABLED_PROPERTY, formModelPropertyChangeListener);
228                    formModel.addPropertyChangeListener(FormModel.READONLY_PROPERTY, formModelPropertyChangeListener);
229                    formModel.addPropertyChangeListener(ValidatingFormModel.VALIDATING_PROPERTY, formModelPropertyChangeListener);
230            }
231    
232            public void unregisterFormModelPropertyChangeListener() {
233                    ValidatingFormModel formModel = getFormModel();
234                    formModel.removePropertyChangeListener(FormModel.COMMITTABLE_PROPERTY, formModelPropertyChangeListener);
235                    formModel.removePropertyChangeListener(FormModel.DIRTY_PROPERTY, formModelPropertyChangeListener);
236                    formModel.removePropertyChangeListener(FormModel.ENABLED_PROPERTY, formModelPropertyChangeListener);
237                    formModel.removePropertyChangeListener(FormModel.READONLY_PROPERTY, formModelPropertyChangeListener);
238                    formModel
239                                    .removePropertyChangeListener(ValidatingFormModel.VALIDATING_PROPERTY, formModelPropertyChangeListener);
240            }
241    
242            protected String getPrintFormObjectCommandFaceDescriptorId() {
243                    return "reporterForm.printFormObjectCommand";
244            }
245    
246            protected String getPrintFieldsCommandFaceDescriptorId() {
247                    return "reporterForm.printFieldsCommand";
248            }
249    
250            protected String getPrintFormModelCommandFaceDescriptorId() {
251                    return "reporterForm.printFormModelCommand";
252            }
253    
254            protected String getEnableCommandFaceDescriptorId() {
255                    return "reporterForm.enableCommand";
256            }
257    
258            protected String getReadOnlyCommandFaceDescriptorId() {
259                    return "reporterForm.readOnlyCommand";
260            }
261    
262            protected String getValidatingCommandFaceDescriptorId() {
263                    return "reporterForm.validatingCommand";
264            }
265    
266            protected String getLogFormModelPropertyChangeCommandFaceDescriptorId() {
267                    return "reporterForm.logFormModelPropertyChangeCommand";
268            }
269    
270            protected String getCommitCommandFaceDescriptorId() {
271                    return "reporterForm.commitCommand";
272            }
273    
274            protected String getRevertCommandFaceDescriptorId() {
275                    return "reporterForm.revertCommand";
276            }
277    
278            protected String getNewFormObjectCommandId() {
279                    return "reporterForm.newCommand";
280            }
281    
282            public static abstract class StateSynchronizingToggleCommand extends ToggleCommand implements PropertyChangeListener {
283    
284                    private boolean isSynchronizing = false;
285    
286                    public StateSynchronizingToggleCommand(String id) {
287                            super(id);
288                    }
289    
290                    @Override
291                    protected final void onSelection() {
292                            if (!isSynchronizing)
293                                    doOnSelection();
294                    }
295    
296                    @Override
297                    protected final void onDeselection() {
298                            if (!isSynchronizing)
299                                    doOnDeselection();
300                    }
301    
302                    protected abstract void doOnSelection();
303    
304                    protected abstract void doOnDeselection();
305    
306                    public void propertyChange(PropertyChangeEvent evt) {
307                            isSynchronizing = true;
308                            setSelected((Boolean) evt.getNewValue());
309                            isSynchronizing = false;
310                    }
311            }
312    
313            protected class LogPropertyChangeListener implements PropertyChangeListener {
314    
315                    public void propertyChange(PropertyChangeEvent evt) {
316                            getMessageArea().append("[EVENT");
317                            if (evt.getSource() instanceof FormModel)
318                                    getMessageArea().append(" " + ((FormModel)evt.getSource()).getId());
319                            getMessageArea().append("] property = " + evt.getPropertyName());
320                            getMessageArea().append(", oldValue = " + evt.getOldValue());
321                            getMessageArea().append(", newValue = " + evt.getNewValue());
322                            getMessageArea().append("\n");
323                    }
324            };
325    }