View Javadoc

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  import java.awt.Component;
19  import java.awt.GridBagConstraints;
20  import java.awt.Insets;
21  import java.util.Map;
22  
23  import org.apache.commons.jelly.JellyTagException;
24  import org.apache.commons.jelly.MissingAttributeException;
25  import org.apache.commons.jelly.Tag;
26  import org.apache.commons.jelly.XMLOutput;
27  import org.apache.commons.jelly.tags.core.UseBeanTag;
28  import org.apache.commons.jelly.tags.swing.impl.GridBagConstraintBean;
29  import org.apache.commons.lang.StringUtils;
30  
31  /***
32   * This class represents a {@link GridBagConstraints} constraints as passed in
33   * the second argument of {@link Container#add(Component,Object)}.
34   * It supports inheritence between such tags in the following fashion:
35   * <ul>
36   *     <li>either using a <code>basedOn</code> attribute which is
37   *         supposed to provide a reference to another {@link GbcTag}.</li>
38   *     <li>either using a parent {@link GbcTag}.</li>
39   * </ul>
40   * The first version takes precedence.
41   * A Grid-bag-constraint inherits from another simply by setting other attributes
42   * as is done in {@link GridBagConstraintBean#setBasedOn}.
43   * <p>
44   * In essence, it looks really like nothing else than a bean-class...
45   * with {@link #getConstraints}.
46   * Probably a shorter java-source is do-able.
47   * <p>
48   * TODO: this class should probably be extended with special treatment for dimensions
49   * using the converter package.
50   *
51   * @author <a href="mailto:paul@activemath.org">Paul Libbrecht</a>
52   * @version $Revision: 155420 $
53   */
54  public class GbcTag extends UseBeanTag implements ContainerTag {
55  
56      public GridBagConstraints getConstraints() {
57          return (GridBagConstraints) getBean();
58      }
59  
60  
61      // ContainerTag interface
62      //-------------------------------------------------------------------------
63  
64      /***
65       * Adds a child component to this parent
66       * @param component the child to add
67       * @param constraints the constraints to use
68       * @TODO constraints looks like it's ignored
69       */
70      public void addChild(Component component, Object constraints) throws JellyTagException {
71          GridBagLayoutTag tag = (GridBagLayoutTag) findAncestorWithClass( GridBagLayoutTag.class );
72          if (tag == null) {
73              throw new JellyTagException( "this tag must be nested within a <gridBagLayout> tag" );
74          }
75          tag.addLayoutComponent(component, getConstraints());
76      }
77  
78      // Implementation methods
79      //-------------------------------------------------------------------------
80  
81      /***
82       * A class may be specified otherwise the Factory will be used.
83       * @param classObject the object to be converted
84       */
85      protected Class convertToClass(Object classObject)
86      throws MissingAttributeException, ClassNotFoundException {
87          if (classObject == null) {
88              return null;
89          }
90          else {
91              return super.convertToClass(classObject);
92          }
93      }
94  
95      /***
96       * A class may be specified otherwise the Factory will be used.
97       */
98      protected Object newInstance(Class theClass, Map attributes, XMLOutput output) throws JellyTagException {
99          if (theClass != null ) {
100             try {
101                 return theClass.newInstance();
102             } catch (IllegalAccessException e) {
103                 throw new JellyTagException(e);
104             } catch (InstantiationException e) {
105                 throw new JellyTagException(e);
106             }
107         }
108         else {
109             return new GridBagConstraintBean();
110         }
111     }
112 
113     protected void setBeanProperties(Object bean, Map attributes)
114         throws JellyTagException {
115 
116         Insets ins = null;
117         Object insetString = attributes.get("insets");
118         if (insetString instanceof String) {
119             attributes.remove("insets");
120 
121 
122             String[] parts = StringUtils.split((String) insetString, ",");
123 
124             if (parts.length != 4) {
125                 throw new JellyTagException(
126                     "insets must be specified"
127                         + "as four comma - separated integers.");
128             }
129 
130             ins =
131                 new Insets(
132                     Integer.parseInt(parts[0].trim()),
133                     Integer.parseInt(parts[1].trim()),
134                     Integer.parseInt(parts[2].trim()),
135                     Integer.parseInt(parts[3].trim()));
136         }
137 
138         super.setBeanProperties(bean, attributes);
139 
140         // set basedOn info of the bean if we have a parent gbc tag
141         // in the context of the closest gridbaglayout tag
142 
143         if (bean instanceof GridBagConstraintBean) {
144             GridBagConstraintBean gbc = (GridBagConstraintBean) bean;
145 
146             if (ins != null) {
147                 gbc.setInsets(ins);
148             }
149 
150             GridBagLayoutTag parentLayoutTag =
151                 (GridBagLayoutTag) (findAncestorWithClass(GridBagLayoutTag
152                     .class));
153             if (parentLayoutTag != null) {
154                 GbcTag parentGbcTag =
155                     (GbcTag) (findAncestorWithClass(getParent(),
156                         GbcTag.class,
157                         parentLayoutTag));
158                 if (parentGbcTag != null) {
159                     GridBagConstraints parentGbc =
160                         parentGbcTag.getConstraints();
161 
162                     if (parentGbc != null
163                         && parentGbc instanceof GridBagConstraintBean) {
164                         gbc.setBasedOn((GridBagConstraintBean) parentGbc);
165                         if (insetString == null) {
166                             gbc.setInsets(parentGbc.insets);
167                         }
168                     }
169                 }
170             }
171         }
172     }
173 
174     public static Tag findAncestorWithClass(
175         Tag from,
176         Class tagClass,
177         Tag parent) {
178         while (from != null && from != parent) {
179             if (tagClass.isInstance(from)) {
180                 return from;
181             }
182             from = from.getParent();
183         }
184         return null;
185     }
186 }
187