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: SPanel.java,v 1.7 2002/09/13 17:04:40 ludovicc Exp $ 37 */ 38 package org.scopemvc.view.swing; 39 40 41 import java.awt.Component; 42 import java.awt.Container; 43 import org.apache.commons.logging.Log; 44 import org.apache.commons.logging.LogFactory; 45 import org.scopemvc.controller.basic.BasicController; 46 import org.scopemvc.core.Control; 47 import org.scopemvc.core.PropertyView; 48 import org.scopemvc.core.Selector; 49 import org.scopemvc.core.View; 50 import org.scopemvc.view.util.ModelBindable; 51 52 /*** 53 * <P> 54 * 55 * A JPanel implementation of View for use in Swing-based user interfaces. 56 * {@link org.scopemvc.controller.swing.SwingContext} uses the following methods 57 * from the {@link SwingView} base class that should be overridden in subclasses 58 * that can be shown as top-level views in a Window: 59 * <UL> 60 * <LI> {@link #getTitle}</LI> 61 * <LI> {@link #getDisplayMode}</LI> 62 * <LI> {@link #getCloseControl}</LI> 63 * <LI> {@link #isResizable}</LI> 64 * </UL> 65 * </P> <P> 66 * 67 * SPanel can be bound either to an entire model object, or to a property of a 68 * model. In either case it binds child components to the model it shows (either 69 * the entire model or a property of it, assumed to be a submodel). <B>Note: 70 * </B>See {@link SUnboundPanel} for an SPanel that doesn't bind to a model, 71 * isolating its contained views from the model-binding hierarchy. </P> <P> 72 * 73 * SPanel uses a {@link org.scopemvc.view.swing.SwingBoundModel SwingBoundModel} 74 * delegate. </P> <P> 75 * 76 * SPanel implements the CHANGE_MODEL_CONTROL_ID Control when the shown model 77 * object changes. This supports BasicController which needs to know when its 78 * current model changes. </P> 79 * 80 * @author <A HREF="mailto:smeyfroi@users.sourceforge.net">Steve Meyfroidt</A> 81 * @created 05 September 2002 82 * @version $Revision: 1.7 $ $Date: 2002/09/13 17:04:40 $ 83 */ 84 public class SPanel 85 extends SwingView 86 implements ModelBindable, Refreshable, PropertyView { 87 88 private static final Log LOG = LogFactory.getLog(SPanel.class); 89 90 // ------------------- Delegate to SwingBoundModel ------------------- 91 92 /*** 93 * Helper to manage model to view binding. 94 */ 95 private SwingBoundModel boundModel = new SwingBoundModel(this); 96 97 // --------------------- shownModel ----------------------- 98 99 /*** 100 * The model object that the SPanel presents, which may be a property of the 101 * bound model if a Selector is specified. 102 */ 103 private Object shownModel; 104 105 106 private static void populateSubComponents(Component inComponent, Object inModel) { 107 if (inComponent instanceof SwingView) { 108 if (LOG.isDebugEnabled()) { 109 LOG.debug("populateSubComponents: component: " + inComponent + ", subview count: " + ((SwingView) inComponent).getSubViewCount()); 110 } 111 for (int i = ((SwingView) inComponent).getSubViewCount() - 1; i >= 0; --i) { 112 SwingSubView ssv = ((SwingView) inComponent).getSubView(i); 113 if (LOG.isDebugEnabled()) { 114 LOG.debug("populateSubComponents: subview: " + ssv); 115 } 116 ssv.setBoundModel(inModel); 117 } 118 } 119 120 if (!(inComponent instanceof Container)) { 121 return; 122 } 123 124 if (LOG.isDebugEnabled()) { 125 LOG.debug("populateSubComponents: component: " + inComponent + ", component count: " + ((Container) inComponent).getComponentCount()); 126 } 127 for (int i = ((Container) inComponent).getComponentCount() - 1; i >= 0; --i) { 128 Component c = ((Container) inComponent).getComponent(i); 129 if (c instanceof View) { 130 ((View) c).setBoundModel(inModel); 131 } else { 132 populateSubComponents(c, inModel); 133 } 134 } 135 } 136 137 138 private static void refreshSubComponents(Component inComponent) { 139 if (inComponent instanceof SwingView) { 140 for (int i = ((SwingView) inComponent).getSubViewCount() - 1; i >= 0; --i) { 141 SwingSubView ssv = ((SwingView) inComponent).getSubView(i); 142 if (ssv instanceof Refreshable) { 143 ((Refreshable) ssv).refresh(); 144 } 145 } 146 } 147 148 if (!(inComponent instanceof Container)) { 149 return; 150 } 151 152 for (int i = ((Container) inComponent).getComponentCount() - 1; i >= 0; --i) { 153 Component c = ((Container) inComponent).getComponent(i); 154 if (c instanceof Refreshable) { 155 ((Refreshable) c).refresh(); 156 } else { 157 refreshSubComponents(c); 158 } 159 } 160 } 161 162 163 /*** 164 * Gets the bound model 165 * 166 * @return The boundModel value 167 */ 168 public final Object getBoundModel() { 169 return boundModel.getBoundModel(); 170 } 171 172 173 /*** 174 * Gets the selector 175 * 176 * @return The selector value 177 */ 178 public final Selector getSelector() { 179 return boundModel.getSelector(); 180 } 181 182 183 /*** 184 * Makes no sense: can't change the property using an SPanel! 185 * 186 * @return The viewValue value 187 */ 188 public final Object getViewValue() { 189 return getShownModel(); 190 } 191 192 193 /*** 194 * Get the model object that the SPanel presents, which may be a property of 195 * the bound model if a Selector is specified. 196 * 197 * @return The shownModel value 198 */ 199 public final Object getShownModel() { 200 return shownModel; 201 } 202 203 204 /*** 205 * Sets the selector 206 * 207 * @param inSelector The new selector value 208 */ 209 public final void setSelector(Selector inSelector) { 210 boundModel.setSelector(inSelector); 211 } 212 213 214 /*** 215 * Sets the selector string 216 * 217 * @param inSelectorString The new selectorString value 218 */ 219 public final void setSelectorString(String inSelectorString) { 220 boundModel.setSelectorString(inSelectorString); 221 } 222 223 224 /*** 225 * Sets the bound model 226 * 227 * @param inModel The new boundModel value 228 */ 229 public void setBoundModel(Object inModel) { 230 boundModel.setBoundModel(inModel); 231 } 232 233 234 // --------------------- Implement ModelBindable ---------------------- 235 236 /*** 237 * Ignores inReadOnly. 238 * 239 * @param inValue TODO: Describe the Parameter 240 * @param inReadOnly TODO: Describe the Parameter 241 */ 242 public void updateFromProperty(Object inValue, boolean inReadOnly) { 243 if (LOG.isDebugEnabled()) { 244 LOG.debug("updateFromProperty: " + inValue + ", " + inReadOnly); 245 } 246 247 setShownModel(inValue); 248 } 249 250 251 /*** 252 * Makes no sense. 253 * 254 * @param inException TODO: Describe the Parameter 255 */ 256 public void validationFailed(Exception inException) { 257 // noop 258 } 259 260 261 /*** 262 * Makes no sense. 263 */ 264 public void validationSuccess() { 265 // noop 266 } 267 268 269 // ------------------ Refreshable ------------------------- 270 271 /*** 272 * TODO: document the method 273 */ 274 public void refresh() { 275 // Get the model's state 276 Object propertyValue = boundModel.getPropertyValue(); 277 boolean propertyReadOnly = boundModel.getPropertyReadOnly(); 278 279 // If no change in shown model then just refresh children 280 // ... else update this and children will be updated automatically 281 if (getShownModel() == propertyValue) { 282 refreshSubComponents(this); 283 } else { 284 updateFromProperty(propertyValue, propertyReadOnly); 285 } 286 } 287 288 289 /*** 290 * Called internally from updateFromProperty(). Issues a 291 * CHANGE_MODEL_CONTROL_ID Control to notify parent Controller of the 292 * change. 293 * 294 * @param inModel The new shownModel value 295 */ 296 private void setShownModel(Object inModel) { 297 298 if (shownModel == inModel) { 299 return; 300 } 301 302 shownModel = inModel; 303 304 // Issue the BasicController.CHANGE_MODEL_CONTROL_ID 305 // Only valid for this View, so don't use the usual delegation to 306 // ... the nearest View that has a Controller 307 if (getController() != null) { 308 getController().handleControl(new Control(BasicController.CHANGE_MODEL_CONTROL_ID, shownModel)); 309 } 310 311 // Now pass on the new shown model object to all sub-Views 312 if (LOG.isDebugEnabled()) { 313 LOG.debug("updateFromModel: updating child Views with model " + inModel); 314 } 315 populateSubComponents(this, inModel); 316 } 317 } 318

This page was automatically generated by Maven