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 }