View Javadoc
1 /* 2 * Scope: a generic MVC framework. 3 * Copyright (c) 2000-2002, The Scope team 4 * All rights reserved. 5 * 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * Neither the name "Scope" nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 * 35 * 36 * $Id: SPasswordField.java,v 1.11 2002/09/13 17:04:41 ludovicc Exp $ 37 */ 38 package org.scopemvc.view.swing; 39 40 41 import java.awt.event.ActionEvent; 42 import java.awt.event.ActionListener; 43 import java.awt.event.FocusEvent; 44 import java.awt.event.FocusListener; 45 import java.beans.Beans; 46 import javax.swing.JPasswordField; 47 import javax.swing.JToolTip; 48 import org.apache.commons.logging.Log; 49 import org.apache.commons.logging.LogFactory; 50 import org.scopemvc.core.Control; 51 import org.scopemvc.core.Controller; 52 import org.scopemvc.core.PropertyView; 53 import org.scopemvc.core.Selector; 54 import org.scopemvc.util.Debug; 55 import org.scopemvc.util.convertor.StringConvertor; 56 import org.scopemvc.util.convertor.StringConvertors; 57 import org.scopemvc.view.util.ModelBindable; 58 59 /*** 60 * <P> 61 * 62 * A JPasswordField that works the same way as {@link STextField}. </P> <P> 63 * 64 * Note this is a copy/paste from STextField because no multiple inheritance and 65 * JPasswordField plaf objects depend on instanceof JPasswordField (which isn't 66 * an interface... doh!). </P> 67 * 68 * @author <A HREF="mailto:smeyfroi@users.sourceforge.net">Steve Meyfroidt</A> 69 * @created 05 September 2002 70 * @version $Revision: 1.11 $ $Date: 2002/09/13 17:04:41 $ 71 * @see STextField 72 */ 73 public class SPasswordField extends JPasswordField 74 implements PropertyView, FocusListener, ActionListener, ModelBindable, Refreshable { 75 76 private static final Log LOG = LogFactory.getLog(SPasswordField.class); 77 78 /*** 79 * Helper to manage model to view binding. 80 */ 81 private SwingBoundModel boundModel = new SwingBoundModel(this); 82 83 /*** 84 * Helper to manage validation state. 85 */ 86 private ValidationHelper validationHelper = new ValidationHelper(this); 87 88 /*** 89 * ID of the Control issued when user hits Enter in the STextField. 90 */ 91 private String controlID; 92 93 /*** 94 * STextField can "hold" a null when bound to a property that happens to be 95 * null. 96 */ 97 private boolean valueIsNull = false; 98 99 /*** 100 * Does this textfield disable itself if the model property it is bound to 101 * becomes null? 102 */ 103 private boolean disableOnNull = false; 104 105 /*** 106 * The StringConvertor used to convert the model property to and from the 107 * String representation that the user edits in the textfield. 108 */ 109 private StringConvertor stringConvertor; 110 111 112 /*** 113 * Constructor for the SPasswordField object 114 */ 115 public SPasswordField() { 116 setEnabled(Beans.isDesignTime()); 117 addFocusListener(this); 118 addActionListener(this); 119 } 120 121 122 /*** 123 * @return true if the textfield should be disabled when it edits a null 124 * property value. Otherwise, a null property is treated as an empty 125 * String. 126 */ 127 public final boolean isDisableOnNull() { 128 return disableOnNull; 129 } 130 131 132 // ------------------- Delegate to BoundModel ------------------- 133 134 /*** 135 * Gets the bound model 136 * 137 * @return The boundModel value 138 */ 139 public final Object getBoundModel() { 140 return boundModel.getBoundModel(); 141 } 142 143 144 /*** 145 * Gets the selector 146 * 147 * @return The selector value 148 */ 149 public final Selector getSelector() { 150 return boundModel.getSelector(); 151 } 152 153 154 // ---------- Issue a Control when user hits Enter in the STextfield -------------- 155 156 /*** 157 * Gets the control ID 158 * 159 * @return The controlID value 160 */ 161 public final String getControlID() { 162 return controlID; 163 } 164 165 166 /*** 167 * Get the current value (what would be set as a property of the bound model 168 * object) being presented on the View. 169 * 170 * @return property value from parsing the textfield's current String 171 * representation. 172 * @exception IllegalArgumentException if the conversion from String fails. 173 */ 174 public Object getViewValue() throws IllegalArgumentException { 175 String text = new String(getPassword()); 176 177 if (stringConvertor == null 178 || valueIsNull 179 || (isDisableOnNull() && text.length() < 1)) { 180 return null; 181 } 182 183 return stringConvertor.stringAsValue(text); 184 } 185 186 187 /*** 188 * Don't assign a Controller to STextField, instead delegate to the 189 * containing SwingView that has a parent Controller. 190 * 191 * @return The controller value 192 */ 193 public Controller getController() { 194 return null; 195 } 196 197 198 /*** 199 * Don't assign a Controller to STextField, instead delegate to the 200 * containing SwingView that has a parent Controller. 201 * 202 * @param inControl TODO: Describe the Parameter 203 */ 204 public void issueControl(Control inControl) { 205 SwingUtil.issueControl(this, inControl); 206 } 207 208 209 // ------------ Convenience ------------------- 210 211 /*** 212 * Gets the password text 213 * 214 * @return The passwordText value 215 */ 216 public String getPasswordText() { 217 return new String(getPassword()); 218 } 219 220 221 /*** 222 * Set this to true if the textfield should be disabled when it edits a null 223 * property value. Otherwise, a null property is treated as an empty String. 224 * 225 * @param inDisable The new disableOnNull value 226 */ 227 public final void setDisableOnNull(boolean inDisable) { 228 disableOnNull = inDisable; 229 } 230 231 232 /*** 233 * Sets the bound model 234 * 235 * @param inModel The new boundModel value 236 */ 237 public final void setBoundModel(Object inModel) { 238 boundModel.setBoundModel(inModel); 239 setupStringConvertor(); 240 } 241 242 243 /*** 244 * Sets the selector 245 * 246 * @param inSelector The new selector value 247 */ 248 public final void setSelector(Selector inSelector) { 249 boundModel.setSelector(inSelector); 250 setupStringConvertor(); 251 } 252 253 254 /*** 255 * Sets the selector string 256 * 257 * @param inSelectorString The new selectorString value 258 */ 259 public final void setSelectorString(String inSelectorString) { 260 boundModel.setSelectorString(inSelectorString); 261 setupStringConvertor(); 262 } 263 264 265 /*** 266 * Set the ID of the Control that will be issued when Enter key is pressed 267 * in this STextField. If null no Control will be issued. 268 * 269 * @param inControlID The new controlID value 270 */ 271 public final void setControlID(String inControlID) { 272 controlID = inControlID; 273 } 274 275 276 /*** 277 * Override to call super.setText() only if new value not equals() old 278 * value. 279 * 280 * @param t new text. 281 */ 282 public void setText(String t) { 283 if (Debug.ON) { 284 Debug.assertTrue(getPassword() != null, "null getPassword()"); 285 } 286 if (!new String(getPassword()).equals(t)) { 287 super.setText(t); 288 } 289 } 290 291 /*** 292 * Don't assign a Controller to this component, instead delegate to the 293 * containing SwingView that has a parent Controller. 294 * 295 * @param inController The new controller value 296 */ 297 public void setController(Controller inController) { 298 throw new UnsupportedOperationException("Can't assign a Controller to a " + getClass()); 299 } 300 301 // --------------------- Implement ModelBindable ---------------------- 302 303 /*** 304 * Converts the incoming value to a String via appropriate {@link 305 * org.scopemvc.util.convertor.StringConvertor}. For incoming null either 306 * disable field or set text to empty String. 307 * 308 * @param inValue TODO: Describe the Parameter 309 * @param inReadOnly TODO: Describe the Parameter 310 */ 311 public void updateFromProperty(Object inValue, boolean inReadOnly) { 312 if (LOG.isDebugEnabled()) { 313 LOG.debug("updateFromProperty: " + inValue + ", " + inReadOnly); 314 } 315 316 if (stringConvertor == null) { 317 valueIsNull = true; 318 // ? 319 setEnabled(false); 320 // setText(""); 321 return; 322 } 323 324 if (inValue == null && isDisableOnNull()) { 325 valueIsNull = true; 326 setEnabled(false); 327 // setText(""); 328 return; 329 } 330 331 valueIsNull = false; 332 //(inValue == null); 333 setEnabled(!inReadOnly); 334 try { 335 String text = stringConvertor.valueAsString(inValue); 336 setText(text); 337 } catch (IllegalArgumentException e) { 338 // should never happen normally -- comes from getValue() but the 339 // ... property value must always be convertible to String? 340 LOG.error("updateFromProperty", e); 341 setEnabled(false); 342 } 343 } 344 345 346 /*** 347 * TODO: document the method 348 * 349 * @param inException TODO: Describe the Parameter 350 */ 351 public void validationFailed(Exception inException) { 352 validationHelper.validationFailed(inException); 353 } 354 355 356 /*** 357 * TODO: document the method 358 */ 359 public void validationSuccess() { 360 validationHelper.validationSuccess(); 361 } 362 363 364 /*** 365 * TODO: document the method 366 * 367 * @return TODO: Describe the Return Value 368 */ 369 public JToolTip createToolTip() { 370 return validationHelper.createToolTip(super.createToolTip()); 371 } 372 373 374 // ---------------------- View to model ---------------------- 375 376 /*** 377 * TODO: document the method 378 * 379 * @param inEvent TODO: Describe the Parameter 380 */ 381 public void focusLost(FocusEvent inEvent) { 382 if (LOG.isDebugEnabled()) { 383 LOG.debug("focusLost"); 384 } 385 386 if (!inEvent.isTemporary()) { 387 boundModel.updateModel(); 388 } 389 } 390 391 392 /*** 393 * TODO: document the method 394 * 395 * @param inEvent TODO: Describe the Parameter 396 */ 397 public void focusGained(FocusEvent inEvent) { } 398 399 400 /*** 401 * Sync model object to View and issue a Control if ControlID set. 402 * 403 * @param e TODO: Describe the Parameter 404 */ 405 public void actionPerformed(ActionEvent e) { 406 boundModel.updateModel(); 407 // ... then do the sync to model 408 409 if (controlID != null) { 410 Control control = new Control(controlID); 411 issueControl(control); 412 } 413 } 414 415 416 // ------------------ Refreshable ------------------------- 417 418 /*** 419 * TODO: document the method 420 */ 421 public void refresh() { 422 Object propertyValue = boundModel.getPropertyValue(); 423 boolean propertyReadOnly = boundModel.getPropertyReadOnly(); 424 updateFromProperty(propertyValue, propertyReadOnly); 425 } 426 427 428 /*** 429 * TODO: document the method 430 */ 431 protected void setupStringConvertor() { 432 try { 433 Object m = getBoundModel(); 434 Selector s = getSelector(); 435 if (m != null) { 436 Class clazz = boundModel.getPropertyManager().getPropertyClass(m, s); 437 stringConvertor = StringConvertors.forClass(clazz); 438 } 439 } catch (Exception e) { 440 stringConvertor = null; 441 } 442 } 443 }

This page was automatically generated by Maven