001    /**
002     * Java Gui Builder - A library to build GUIs using an XML file.
003     * Copyright 2002, 2003 (C) François Beausoleil
004     *
005     * This library is free software; you can redistribute it and/or
006     * modify it under the terms of the GNU Lesser General Public
007     * License as published by the Free Software Foundation; either
008     * version 2.1 of the License, or (at your option) any later version.
009     *
010     * This library is distributed in the hope that it will be useful,
011     * but WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013     * Lesser General Public License for more details.
014     *
015     * You should have received a copy of the GNU Lesser General Public
016     * License along with this library; if not, write to the Free Software
017     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018     */
019    
020    package jgb.handlers.swing;
021    
022    import jgb.builder.TagHandler;
023    import org.xml.sax.SAXException;
024    
025    import java.awt.*;
026    import java.lang.reflect.Field;
027    import java.util.Iterator;
028    import java.util.Map;
029    import java.util.StringTokenizer;
030    
031    /**
032     * @author Francois Beausoleil, <a href="mailto:fbos@users.sourceforge.net">fbos@users.sourceforge.net</a>
033     */
034    public class GridbagTagHandler extends AbstractTagHandler {
035        protected void enterElement(Map atts) throws SAXException {
036            final GridBagConstraints constraints;
037            if (tagContext.containsKey(TagHandler.CURRENT_CONSTRAINTS_KEY)) {
038                Object hisConstraints = tagContext.get(TagHandler.CURRENT_CONSTRAINTS_KEY);
039                if (hisConstraints instanceof GridBagConstraints) {
040                    constraints = (GridBagConstraints)hisConstraints;
041                } else {
042                    constraints = new GridBagConstraints();
043                }
044            } else {
045                constraints = new GridBagConstraints();
046            }
047    
048            for (Iterator iterator = atts.entrySet().iterator(); iterator.hasNext();) {
049                Map.Entry entry = (Map.Entry)iterator.next();
050    
051                Class constraintsClass = constraints.getClass();
052                String name = entry.getKey().toString();
053                String value = entry.getValue().toString();
054    
055                try {
056                    Field constraintField = constraintsClass.getField(name);
057    
058                    if (constraintField.getType().equals(Integer.TYPE)) {
059                        constraintField.setInt(constraints, parseInt(value));
060                    } else if (constraintField.getType().equals(Double.TYPE)) {
061                        constraintField.setDouble(constraints, parseDouble(value));
062                    } else if (constraintField.getType().equals(Insets.class)) {
063                        Insets insets = parseInsets(value);
064                        constraintField.set(constraints, insets);
065                    } else {
066                        throwParsingException("Unhandled field type: " + constraintField.getType().getName());
067                    }
068                } catch (NoSuchFieldException e) {
069                    throwParsingException("Could not find GridBagConstraints field "
070                            + "named " + name, e);
071                } catch (SAXException e) {
072                    throw e;
073                } catch (Exception e) {
074                    throwParsingException("Could not set value of GridBagConstraints "
075                            + "field named " + name + " to value " + value, e);
076                }
077            }
078    
079            tagContext.put(TagHandler.PARAMETER_CLASS_KEY, GridBagConstraints.class);
080            tagContext.put(TagHandler.PARAMETER_VALUE_KEY, constraints);
081        }
082    
083        private int parseInt(String value) throws SAXException {
084            try {
085                return Integer.parseInt(value);
086            } catch (NumberFormatException e) {
087                Field field = null;
088                try {
089                    field = GridBagConstraints.class.getField(value.toUpperCase());
090                } catch (NoSuchFieldException e1) {
091                    throwParsingException("Could not find GridBagConstraints "
092                            + "constant named " + value.toUpperCase(), e1);
093                }
094    
095                try {
096                    return field.getInt(null);
097                } catch (Exception e1) {
098                    throwParsingException("Could not access GridBagConstraints "
099                            + "value for constant named " + value.toUpperCase(), e1);
100                }
101            }
102    
103            throw new RuntimeException("Should never reach this point");
104        }
105    
106        private double parseDouble(String value) throws SAXException {
107            try {
108                return Double.parseDouble(value);
109            } catch (NumberFormatException e) {
110                Field field = null;
111                try {
112                    field = GridBagConstraints.class.getField(value.toUpperCase());
113                } catch (NoSuchFieldException e1) {
114                    throwParsingException("Could not find GridBagConstraints "
115                            + "constant named " + value.toUpperCase(), e1);
116                }
117    
118                try {
119                    return field.getDouble(null);
120                } catch (Exception e1) {
121                    throwParsingException("Could not access GridBagConstraints "
122                            + "value for constant named " + value.toUpperCase(), e1);
123                }
124            }
125    
126            throw new RuntimeException("Should never reach this point");
127        }
128    
129        public Insets parseInsets(String value) throws SAXException {
130            StringTokenizer st = new StringTokenizer(value, ",");
131            if (st.countTokens() < 1
132                    || st.countTokens() > 4
133                    || st.countTokens() == 3) {
134                throw new IllegalArgumentException("Wrong number of arguments in "
135                        + "insets value list.  Must be 1, 2 or 4.");
136            }
137    
138            int[] insetsSize = new int[st.countTokens()];
139            for (int i = 0; i < insetsSize.length; i++) {
140                insetsSize[i] = parseInt(st.nextToken());
141            }
142    
143            Insets insets = null;
144    
145            switch (insetsSize.length) {
146                case 1:
147                    insets = new Insets(insetsSize[0], insetsSize[0], insetsSize[0], insetsSize[0]);
148                    break;
149                case 2:
150                    insets = new Insets(insetsSize[0], insetsSize[1], insetsSize[0], insetsSize[1]);
151                    break;
152                case 4:
153                    insets = new Insets(insetsSize[0], insetsSize[3], insetsSize[2], insetsSize[1]);
154                    break;
155                default:
156                    throw new RuntimeException("Wrong number of insets not filtered - Should never reach this point");
157            }
158    
159            return insets;
160        }
161    
162        protected void exitElement() throws SAXException {
163        }
164    }