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 }