/** @version 1.00 2001-09-06 @author Cay Horstmann */ import java.awt.*; import java.beans.*; import java.io.*; import java.lang.reflect.*; import javax.swing.*; import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.*; /** This panel uses an XML file to describe its components and their grid bag layout positions. */ public class GridBagPane extends JPanel { /** Constructs a grid bag pane. @param filename the name of the XML file that describes the pane's components and their positions */ public GridBagPane(String filename) { setLayout(new GridBagLayout()); constraints = new GridBagConstraints(); try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); factory.setIgnoringElementContentWhitespace(true); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new File(filename)); parseGridbag(doc.getDocumentElement()); } catch (ParserConfigurationException exception) { exception.printStackTrace(); } catch (SAXException exception) { exception.printStackTrace(); } catch (IOException exception) { exception.printStackTrace(); } } /** Gets a component with a given name @param name a component name @return the component with the given name, or null if no component in this grid bag pane has the given name */ public Component get(String name) { Component[] components = getComponents(); for (int i = 0; i < components.length; i++) { if (components[i].getName().equals(name)) return components[i]; } return null; } /** Parses a gridbag element. @param e a gridbag element */ private void parseGridbag(Element e) { NodeList rows = e.getChildNodes(); for (int i = 0; i < rows.getLength(); i++) { Element row = (Element)rows.item(i); NodeList cells = row.getChildNodes(); for (int j = 0; j < cells.getLength(); j++) { Element cell = (Element)cells.item(j); parseCell(cell, i, j); } } } /** Parses a cell element. @param e a cell element @param r the row of the cell @param c the column of the cell */ private void parseCell(Element e, int r, int c) { // get attributes String value = e.getAttribute("gridx"); if (value.length() == 0) // use default { if (c == 0) constraints.gridx = 0; else constraints.gridx += constraints.gridwidth; } else constraints.gridx = Integer.parseInt(value); value = e.getAttribute("gridy"); if (value.length() == 0) // use default constraints.gridy = r; else constraints.gridx = Integer.parseInt(value); constraints.gridwidth = Integer.parseInt(e.getAttribute("gridwidth")); constraints.gridheight = Integer.parseInt(e.getAttribute("gridheight")); constraints.weightx = Integer.parseInt(e.getAttribute("weightx")); constraints.weighty = Integer.parseInt(e.getAttribute("weighty")); constraints.ipadx = Integer.parseInt(e.getAttribute("ipadx")); constraints.ipady = Integer.parseInt(e.getAttribute("ipady")); // use reflection to get integer values of static fields Class cl = GridBagConstraints.class; try { String name = e.getAttribute("fill"); Field f = cl.getField(name); constraints.fill = f.getInt(cl); } catch(Exception ex) { } try { String name = e.getAttribute("anchor"); Field f = cl.getField(name); constraints.anchor = f.getInt(cl); } catch(Exception ex) { } Component comp = (Component)parseBean( (Element)e.getFirstChild()); add(comp, constraints); } /** Parses a bean element. @param e a bean element */ private Object parseBean(Element e) { try { NodeList children = e.getChildNodes(); Element classElement = (Element)children.item(0); String className = ((Text)classElement.getFirstChild()).getData(); Class cl = Class.forName(className); Object obj = cl.newInstance(); if (obj instanceof Component) ((Component)obj).setName(e.getAttribute("id")); for (int i = 1; i < children.getLength(); i++) { Node propertyElement = children.item(i); Element nameElement = (Element)propertyElement.getFirstChild(); String propertyName = ((Text)nameElement.getFirstChild()).getData(); Element valueElement = (Element)propertyElement.getLastChild(); Object value = parseValue(valueElement); BeanInfo beanInfo = Introspector.getBeanInfo(cl); PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors(); boolean done = false; for (int j = 0; !done && j < descriptors.length; j++) { if (descriptors[j].getName().equals(propertyName)) { descriptors[j].getWriteMethod().invoke(obj, new Object[] { value }); done = true; } } } return obj; } catch (Exception ex) { // the reflection methods can throw various exceptions ex.printStackTrace(); return null; } } /** Parses a value element. @param e a value element */ private Object parseValue(Element e) { Element child = (Element)e.getFirstChild(); if (child.getTagName().equals("bean")) return parseBean(child); String text = ((Text)child.getFirstChild()).getData(); if (child.getTagName().equals("int")) return new Integer(text); else if (child.getTagName().equals("boolean")) return new Boolean(text); else if (child.getTagName().equals("string")) return text; else return null; } private GridBagConstraints constraints; }