Coverage report

  %line %branch
org.apache.commons.jelly.tags.swing.ComponentTag
1% 
45% 

 1  
 /*
 2  
  * Copyright 2002,2004 The Apache Software Foundation.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *      http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.apache.commons.jelly.tags.swing;
 17  
 
 18  
 
 19  
 import java.awt.Component;
 20  
 import java.awt.Container;
 21  
 import java.awt.Dimension;
 22  
 import java.awt.Font;
 23  
 import java.awt.LayoutManager;
 24  
 import java.awt.Point;
 25  
 import java.awt.Window;
 26  
 import java.awt.event.FocusListener;
 27  
 import java.awt.event.KeyListener;
 28  
 import java.awt.event.WindowListener;
 29  
 import java.lang.reflect.InvocationTargetException;
 30  
 import java.util.Map;
 31  
 
 32  
 import javax.swing.Action;
 33  
 import javax.swing.JFrame;
 34  
 import javax.swing.JMenu;
 35  
 import javax.swing.JMenuBar;
 36  
 import javax.swing.JScrollPane;
 37  
 import javax.swing.JSplitPane;
 38  
 import javax.swing.RootPaneContainer;
 39  
 import javax.swing.border.Border;
 40  
 
 41  
 import org.apache.commons.beanutils.BeanUtils;
 42  
 import org.apache.commons.beanutils.ConvertUtils;
 43  
 import org.apache.commons.jelly.JellyTagException;
 44  
 import org.apache.commons.jelly.MissingAttributeException;
 45  
 import org.apache.commons.jelly.XMLOutput;
 46  
 import org.apache.commons.jelly.tags.core.UseBeanTag;
 47  
 import org.apache.commons.jelly.tags.swing.converters.DebugGraphicsConverter;
 48  
 import org.apache.commons.logging.Log;
 49  
 import org.apache.commons.logging.LogFactory;
 50  
 
 51  
 /**
 52  
  * This tag creates a Swing component and adds it to its parent tag, optionally declaring this
 53  
  * component as a variable if the <i>var</i> attribute is specified.</p>
 54  
  *
 55  
  * <p> This tag clears the reference to it's bean after doTag runs.
 56  
  * This means that child tags can access the component (bean) normally
 57  
  * during execution but should not hold a reference to this
 58  
  * tag after their doTag completes.
 59  
  * </p>
 60  
  *
 61  
  * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
 62  
  * @version $Revision: 331171 $
 63  
  */
 64  
 public class ComponentTag extends UseBeanTag implements ContainerTag {
 65  
 
 66  
     /** The Log to which logging calls will be made. */
 67  8
     private static final Log log = LogFactory.getLog(ComponentTag.class);
 68  
     
 69  
     /** This is a converter that might normally be used through the 
 70  
      * BeanUtils product. However, it only applies to one Component
 71  
      * property and not to all ints, so it's not registered with BeanUtils.
 72  
      */
 73  4
     private static final DebugGraphicsConverter debugGraphicsConverter = new DebugGraphicsConverter();
 74  
     
 75  
     /** the factory of widgets */
 76  
     private Factory factory;
 77  
 
 78  0
     public ComponentTag() {
 79  0
     }
 80  
 
 81  0
     public ComponentTag(Factory factory) {
 82  0
         this.factory = factory;
 83  0
     }
 84  
 
 85  
     public String toString() {
 86  0
 		Component comp = getComponent();
 87  0
         String componentName = (comp!=null) ? comp.getName() : class="keyword">null;
 88  0
         if (comp!=null && (componentName == class="keyword">null || componentName.length() == 0))
 89  0
             componentName = getComponent().toString();
 90  0
         return "ComponentTag with bean " + componentName;
 91  
     }
 92  
 
 93  
     /**
 94  
      * Sets the Action of this component
 95  
      */
 96  
     public void setAction(Action action) throws JellyTagException {
 97  0
         Component component = getComponent();
 98  0
         if ( component != null ) {
 99  
             // lets just try set the 'action' property
 100  
             try {
 101  0
                 BeanUtils.setProperty( component, "action", action );
 102  0
             } catch (IllegalAccessException e) {
 103  0
                 throw new JellyTagException(e);
 104  0
             } catch (InvocationTargetException e) {
 105  0
                 throw new JellyTagException(e);
 106  0
             }
 107  
         }
 108  0
     }
 109  
 
 110  
     /**
 111  
      * Sets the Font of this component
 112  
      */
 113  
     public void setFont(Font font) throws JellyTagException {
 114  0
         Component component = getComponent();
 115  0
         if ( component != null ) {
 116  
             // lets just try set the 'font' property
 117  
             try {
 118  0
                 BeanUtils.setProperty( component, "font", font );
 119  
             }
 120  0
             catch (IllegalAccessException e) {
 121  0
                 throw new JellyTagException(e);
 122  
             }
 123  0
             catch (InvocationTargetException e) {
 124  0
                 throw new JellyTagException(e);
 125  0
             }
 126  
         }
 127  0
     }
 128  
 
 129  
     /**
 130  
      * Sets the Border of this component
 131  
      */
 132  
     public void setBorder(Border border) throws JellyTagException {
 133  0
         Component component = getComponent();
 134  0
         if ( component != null ) {
 135  
             try {
 136  
                 // lets just try set the 'border' property
 137  0
                 BeanUtils.setProperty( component, "border", border );
 138  
             }
 139  0
             catch (IllegalAccessException e) {
 140  0
                 throw new JellyTagException(e);
 141  
             }
 142  0
             catch (InvocationTargetException e) {
 143  0
                 throw new JellyTagException(e);
 144  0
             }
 145  
         }
 146  0
     }
 147  
 
 148  
     /**
 149  
      * Sets the LayoutManager of this component
 150  
      */
 151  
     public void setLayout(LayoutManager layout) throws JellyTagException {
 152  0
         Component component = getComponent();
 153  0
         if ( component != null ) {
 154  0
             if ( component instanceof RootPaneContainer ) {
 155  0
                 RootPaneContainer rpc = (RootPaneContainer) component;
 156  0
                 component = rpc.getContentPane();
 157  
             }
 158  
 
 159  
             try {
 160  
                 // lets just try set the 'layout' property
 161  0
                 BeanUtils.setProperty( component, "layout", layout );
 162  
             }
 163  0
             catch (IllegalAccessException e) {
 164  0
                 throw new JellyTagException(e);
 165  
             }
 166  0
             catch (InvocationTargetException e) {
 167  0
                 throw new JellyTagException(e);
 168  0
             }
 169  
         }
 170  0
     }
 171  
 	
 172  
     
 173  0
 	private String tagName = null;
 174  
 	
 175  0
 	private XMLOutput currentOutput = null;
 176  
 	
 177  
 	/** Puts this tag into the context under the given name
 178  
 	 * allowing later calls to {@link #rerun()}.
 179  
 	 * For example, it makes sense to use ${myTag.rerun()} as a child
 180  
 	 * of an <code>action</code> element.
 181  
 	 *
 182  
 	 * @param the name to be used
 183  
 	 */
 184  
 	public void setTagName(String name) {
 185  0
 		this.tagName = name;
 186  0
 	}
 187  
 
 188  
     /**
 189  
      * Adds a WindowListener to this component
 190  
      */
 191  
     public void addWindowListener(WindowListener listener) throws JellyTagException {
 192  0
         Component component = getComponent();
 193  0
         if ( component instanceof Window ) {
 194  0
             Window window = (Window) component;
 195  0
             window.addWindowListener(listener);
 196  
         }
 197  0
     }
 198  
 
 199  
     /**
 200  
      * Adds a FocusListener to this component
 201  
      */
 202  
     public void addFocusListener(FocusListener listener) throws JellyTagException {
 203  0
         Component component = getComponent();
 204  0
         component.addFocusListener(listener);
 205  0
     }
 206  
 
 207  
     /**
 208  
      * Adds a KeyListener to this component
 209  
      */
 210  
     public void addKeyListener(KeyListener listener) throws JellyTagException {
 211  0
         Component component = getComponent();
 212  0
         component.addKeyListener(listener);
 213  0
     }
 214  
 
 215  
     // Properties
 216  
     //-------------------------------------------------------------------------
 217  
 
 218  
     /**
 219  
      * @return the visible component, if there is one.
 220  
      */
 221  
     public Component getComponent() {
 222  0
         Object bean = getBean();
 223  0
         if ( bean instanceof Component ) {
 224  0
             return (Component) bean;
 225  
         }
 226  0
         return null;
 227  
     }
 228  
 
 229  
 
 230  
     // ContainerTag interface
 231  
     //-------------------------------------------------------------------------
 232  
 
 233  
     /**
 234  
      * Adds a child component to this parent
 235  
      */
 236  
     public void addChild(Component component, Object constraints) throws JellyTagException {
 237  0
         Object parent = getBean();
 238  0
         if ( parent instanceof JFrame && component instanceof JMenuBar ) {
 239  0
             JFrame frame = (JFrame) parent;
 240  0
             frame.setJMenuBar( (JMenuBar) component );
 241  
         }
 242  0
         else if ( parent instanceof RootPaneContainer ) {
 243  0
             RootPaneContainer rpc = (RootPaneContainer) parent;
 244  0
             if (constraints != null) {
 245  0
                 rpc.getContentPane().add( component, constraints );
 246  
             }
 247  
             else {
 248  0
                 rpc.getContentPane().add( component);
 249  
             }
 250  
         }
 251  0
         else if ( parent instanceof JScrollPane ) {
 252  0
             JScrollPane scrollPane = (JScrollPane) parent;
 253  0
             scrollPane.setViewportView( component );
 254  
         }
 255  0
         else if ( parent instanceof JSplitPane) {
 256  0
             JSplitPane splitPane = (JSplitPane) parent;
 257  0
             if ( splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT ) {
 258  0
                 if ( splitPane.getTopComponent() == null ) {
 259  0
                     splitPane.setTopComponent( component );
 260  
                 }
 261  
                 else {
 262  0
                     splitPane.setBottomComponent( component );
 263  
                 }
 264  
             }
 265  
             else {
 266  0
                 if ( splitPane.getLeftComponent() == null ) {
 267  0
                     splitPane.setLeftComponent( component );
 268  
                 }
 269  
                 else {
 270  0
                     splitPane.setRightComponent( component );
 271  
                 }
 272  
             }
 273  
         }
 274  0
         else if ( parent instanceof JMenuBar && component instanceof JMenu ) {
 275  0
             JMenuBar menuBar = (JMenuBar) parent;
 276  0
             menuBar.add( (JMenu) component );
 277  
         }
 278  0
         else if ( parent instanceof Container ) {
 279  0
             Container container = (Container) parent;
 280  0
             if (constraints != null) {
 281  0
                 container.add( component, constraints );
 282  
             }
 283  
             else {
 284  0
                 container.add( component );
 285  
             }
 286  
         }
 287  0
     }
 288  
 
 289  
 
 290  
     // Implementation methods
 291  
     //-------------------------------------------------------------------------
 292  
 
 293  
     /**
 294  
      * A class may be specified otherwise the Factory will be used.
 295  
      */
 296  
     protected Class convertToClass(Object classObject) throws MissingAttributeException, ClassNotFoundException {
 297  0
         if (classObject == null) {
 298  0
             return null;
 299  
         }
 300  
         else {
 301  0
             return super.convertToClass(classObject);
 302  
         }
 303  
     }
 304  
 
 305  
     /**
 306  
      * A class may be specified otherwise the Factory will be used.
 307  
      */
 308  
     protected Object newInstance(Class theClass, Map attributes, XMLOutput output) throws JellyTagException {
 309  0
 		if (attributes.containsKey("tagName")) {
 310  0
 			this.setTagName((String)attributes.get("tagName"));
 311  0
 			addIgnoreProperty("tagName");
 312  
 		}
 313  0
 		if(tagName!=null) {
 314  0
 			context.setVariable(tagName,this);
 315  0
 			currentOutput = output;
 316  
 		}
 317  
         try {
 318  0
             if (theClass != null ) {
 319  0
                 return theClass.newInstance();
 320  
             } else {
 321  0
                 return factory.newInstance();
 322  
             }
 323  0
         } catch (IllegalAccessException e) {
 324  0
             throw new JellyTagException(e);
 325  0
         } catch (InstantiationException e) {
 326  0
             throw new JellyTagException(e);
 327  
         }
 328  
     }
 329  
 
 330  
 
 331  
     /**
 332  
      * Either defines a variable or adds the current component to the parent
 333  
      */
 334  
     protected void processBean(String var, Object bean) throws JellyTagException {
 335  0
         if (var != null) {
 336  0
             context.setVariable(var, bean);
 337  
         }
 338  0
         Component component = getComponent();
 339  0
         if ( component != null ) {
 340  0
             ContainerTag parentTag = (ContainerTag) findAncestorWithClass( ContainerTag.class );
 341  0
             if ( parentTag != null ) {
 342  0
                 parentTag.addChild(component, getConstraint());
 343  
             }
 344  
             else {
 345  0
                 if (var == null) {
 346  0
                     throw new JellyTagException( "The 'var' attribute must be specified or this tag must be nested inside a JellySwing container tag like a widget or a layout" );
 347  
                 }
 348  
             }
 349  
         }
 350  0
     }
 351  
 
 352  
     /**
 353  
      * Handles wierd properties that don't quite match the Java Beans contract
 354  
      */
 355  
     protected void setBeanProperties(Object bean, Map attributes) throws JellyTagException {
 356  
             
 357  0
             Component component = getComponent();
 358  0
             if (component != null) {
 359  0
                 if (attributes.containsKey("location")) {
 360  0
                     Object value = attributes.get("location");
 361  0
                     Point p = null;
 362  0
                     if (value instanceof Point) {
 363  0
                         p = (Point) value;
 364  
                     }
 365  0
                     else if (value != null) {
 366  0
                         p =
 367  
                             (Point) ConvertUtils.convert(
 368  
                                 value.toString(),
 369  
                                 Point.class);
 370  
                     }
 371  0
                     component.setLocation(p);
 372  0
                     addIgnoreProperty("location");
 373  
                 }
 374  
 
 375  0
                 if (attributes.containsKey("size")) {
 376  0
                     Object value = attributes.get("size");
 377  0
                     Dimension d = null;
 378  0
                     if (value instanceof Dimension) {
 379  0
                         d = (Dimension) value;
 380  
                     }
 381  0
                     else if (value != null) {
 382  0
                         d =
 383  
                             (Dimension) ConvertUtils.convert(
 384  
                                 value.toString(),
 385  
                                 Dimension.class);
 386  
                     }
 387  0
                     component.setSize(d);
 388  0
                     addIgnoreProperty("size");
 389  
                 }
 390  
 				
 391  
                 
 392  0
                 if (attributes.containsKey("debugGraphicsOptions")) {
 393  
                     try {
 394  0
                         Object o = debugGraphicsConverter.convert(attributes.get("debugGraphicsOptions"));
 395  0
                         attributes.put("debugGraphicsOptions", o);
 396  0
                     } catch (IllegalArgumentException e) {
 397  0
                         throw new JellyTagException(e);
 398  0
                     }
 399  
                 }
 400  
                 
 401  0
                 if (attributes.containsKey("debugGraphics")) {
 402  
                     try {
 403  0
                         Object o = debugGraphicsConverter.convert(attributes.get("debugGraphics"));
 404  0
                         attributes.put("debugGraphicsOptions", o);
 405  0
                     } catch (IllegalArgumentException e) {
 406  0
                         throw new JellyTagException(e);
 407  0
                     }
 408  
                     
 409  0
                     addIgnoreProperty("debugGraphics");
 410  
                 }
 411  
                 
 412  0
              super.setBeanProperties(bean, attributes);
 413  
         }
 414  0
     }
 415  
 
 416  
     protected Object getConstraint() {
 417  0
         return null;
 418  
     }
 419  
 
 420  
     /**Overrides the default UseBean functionality to clear the bean after the
 421  
      * tag runs. This prevents us from keeping references to heavy Swing objects
 422  
      * around for longer than they are needed.
 423  
      * @see org.apache.commons.jelly.Tag#doTag(org.apache.commons.jelly.XMLOutput)
 424  
      */
 425  
     public void doTag(XMLOutput output) throws JellyTagException {
 426  0
         super.doTag(output);
 427  0
         clearBean();
 428  0
     }
 429  
 
 430  
     /** Sets the bean to null, to prevent it from
 431  
      * sticking around in the event that this tag instance is
 432  
      * cached. This method is called at the end of doTag.
 433  
      *
 434  
      */
 435  
     protected void clearBean() {
 436  0
         setBean(null);
 437  0
     }
 438  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.