/* * Copyright 2000-2009 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.uiDesigner.lw; import com.intellij.uiDesigner.UIFormXmlConstants; import com.intellij.uiDesigner.compiler.UnexpectedFormElementException; import com.intellij.uiDesigner.core.GridLayoutManager; import com.intellij.uiDesigner.shared.BorderType; import com.intellij.uiDesigner.shared.XYLayoutManager; import org.jdom.Element; import java.awt.*; import java.util.ArrayList; import java.util.Iterator; /** * @author Anton Katilin * @author Vladimir Kondratyev */ public class LwContainer extends LwComponent implements IContainer{ // PLEASE DO NOT USE GENERICS IN THIS FILE AS IT IS USED IN JAVAC2 ANT TASK THAT SHOULD BE RUNNABLE WITH JDK 1.3 /** * Children components */ private final ArrayList myComponents; /** * Describes border's type. This member is never <code>null</code> */ private BorderType myBorderType; /** * Border's title. If border doesn't have any title then * this member is <code>null</code>. */ private StringDescriptor myBorderTitle; private int myBorderTitleJustification; private int myBorderTitlePosition; private FontDescriptor myBorderTitleFont; private ColorDescriptor myBorderTitleColor; private Insets myBorderSize; private ColorDescriptor myBorderColor; private LayoutManager myLayout; private String myLayoutManager; protected LayoutSerializer myLayoutSerializer; public LwContainer(final String className){ super(className); myComponents = new ArrayList(); // By default container doesn't have any special border setBorderType(BorderType.NONE); myLayout = createInitialLayout(); } protected LayoutManager createInitialLayout(){ return new XYLayoutManager(); } public final LayoutManager getLayout() { return myLayout; } public final void setLayout(final LayoutManager layout) { myLayout = layout; } public String getLayoutManager() { return myLayoutManager; } public final boolean isGrid(){ return getLayout() instanceof GridLayoutManager; } public final boolean isXY(){ return getLayout() instanceof XYLayoutManager; } /** * @param component component to be added. * * @exception IllegalArgumentException if <code>component</code> is <code>null</code> * @exception IllegalArgumentException if <code>component</code> already exist in the * container */ public final void addComponent(final LwComponent component){ if (component == null) { throw new IllegalArgumentException("component cannot be null"); } if (myComponents.contains(component)) { throw new IllegalArgumentException("component is already added: " + component); } if (component.getParent() != null) { throw new IllegalArgumentException("component already added to another container"); } // Attach to new parent myComponents.add(component); component.setParent(this); } public final IComponent getComponent(final int index) { return (IComponent)myComponents.get(index); } public final int getComponentCount() { return myComponents.size(); } public int indexOfComponent(final IComponent lwComponent) { return myComponents.indexOf(lwComponent); } /** * @return border's type. The method never return <code>null</code>. * * @see BorderType */ public final BorderType getBorderType(){ return myBorderType; } public boolean accept(ComponentVisitor visitor) { if (!super.accept(visitor)) { return false; } for (int i = 0; i < getComponentCount(); i++) { final IComponent c = getComponent(i); if (!c.accept(visitor)) { return false; } } return true; } /** * @see BorderType * * @exception IllegalArgumentException if <code>type</code> * is <code>null</code> */ public final void setBorderType(final BorderType type){ if(type==null){ throw new IllegalArgumentException("type cannot be null"); } myBorderType=type; } /** * @return border's title. If the container doesn't have any title then the * method returns <code>null</code>. */ public final StringDescriptor getBorderTitle(){ return myBorderTitle; } /** * @param title new border's title. <code>null</code> means that * the containr doesn't have have titled border. */ public final void setBorderTitle(final StringDescriptor title){ myBorderTitle=title; } public int getBorderTitleJustification() { return myBorderTitleJustification; } public int getBorderTitlePosition() { return myBorderTitlePosition; } public FontDescriptor getBorderTitleFont() { return myBorderTitleFont; } public ColorDescriptor getBorderTitleColor() { return myBorderTitleColor; } public Insets getBorderSize() { return myBorderSize; } public ColorDescriptor getBorderColor() { return myBorderColor; } /** * TODO[anton,vova] looks like it is better to pass contraints tag * * @param element XML element which should contains 'constraints' tag */ protected void readConstraintsForChild(final Element element, final LwComponent component){ if (myLayoutSerializer != null) { final Element constraintsElement = LwXmlReader.getRequiredChild(element, "constraints"); myLayoutSerializer.readChildConstraints(constraintsElement, component); } } /** * 'border' is required subtag */ protected final void readBorder(final Element element) { final Element borderElement = LwXmlReader.getRequiredChild(element, UIFormXmlConstants.ELEMENT_BORDER); setBorderType(BorderType.valueOf(LwXmlReader.getRequiredString(borderElement, UIFormXmlConstants.ATTRIBUTE_TYPE))); StringDescriptor descriptor = LwXmlReader.getStringDescriptor(borderElement, UIFormXmlConstants.ATTRIBUTE_TITLE, UIFormXmlConstants.ATTRIBUTE_TITLE_RESOURCE_BUNDLE, UIFormXmlConstants.ATTRIBUTE_TITLE_KEY); if (descriptor != null) { setBorderTitle(descriptor); } myBorderTitleJustification = LwXmlReader.getOptionalInt(borderElement, UIFormXmlConstants.ATTRIBUTE_TITLE_JUSTIFICATION, 0); myBorderTitlePosition = LwXmlReader.getOptionalInt(borderElement, UIFormXmlConstants.ATTRIBUTE_TITLE_POSITION, 0); Element fontElement = LwXmlReader.getChild(borderElement, UIFormXmlConstants.ELEMENT_FONT); if (fontElement != null) { myBorderTitleFont = LwXmlReader.getFontDescriptor(fontElement); } myBorderTitleColor = LwXmlReader.getOptionalColorDescriptor(LwXmlReader.getChild(borderElement, UIFormXmlConstants.ELEMENT_TITLE_COLOR)); myBorderColor = LwXmlReader.getOptionalColorDescriptor(LwXmlReader.getChild(borderElement, UIFormXmlConstants.ELEMENT_COLOR)); Element sizeElement = LwXmlReader.getChild(borderElement, UIFormXmlConstants.ELEMENT_SIZE); if (sizeElement != null) { try { myBorderSize = LwXmlReader.readInsets(sizeElement); } catch(Exception e) { myBorderSize = null; } } } /** * 'children' is required attribute */ protected final void readChildren(final Element element, final PropertiesProvider provider) throws Exception{ final Element childrenElement = LwXmlReader.getRequiredChild(element, "children"); for(Iterator i=childrenElement.getChildren().iterator(); i.hasNext();){ final Element child = (Element)i.next(); final LwComponent component = createComponentFromTag(child); addComponent(component); component.read(child, provider); } } public static LwComponent createComponentFromTag(final Element child) throws Exception { final String name = child.getName(); final LwComponent component; if("component".equals(name)){ final String className = LwXmlReader.getRequiredString(child, UIFormXmlConstants.ATTRIBUTE_CLASS); component = new LwAtomicComponent(className); } else if (UIFormXmlConstants.ELEMENT_NESTED_FORM.equals(name)) { component = new LwNestedForm(); } else if("vspacer".equals(name)){ component = new LwVSpacer(); } else if("hspacer".equals(name)){ component = new LwHSpacer(); } else if("xy".equals(name) || "grid".equals(name)){ String className = LwXmlReader.getOptionalString(child, UIFormXmlConstants.ATTRIBUTE_CLASS, "javax.swing.JPanel"); component = new LwContainer(className); } else if(UIFormXmlConstants.ELEMENT_SCROLLPANE.equals(name)) { String className = LwXmlReader.getOptionalString(child, UIFormXmlConstants.ATTRIBUTE_CLASS, "javax.swing.JScrollPane"); component = new LwScrollPane(className); } else if(UIFormXmlConstants.ELEMENT_TABBEDPANE.equals(name)){ String className = LwXmlReader.getOptionalString(child, UIFormXmlConstants.ATTRIBUTE_CLASS, "javax.swing.JTabbedPane"); component = new LwTabbedPane(className); } else if(UIFormXmlConstants.ELEMENT_SPLITPANE.equals(name)){ String className = LwXmlReader.getOptionalString(child, UIFormXmlConstants.ATTRIBUTE_CLASS, "javax.swing.JSplitPane"); component = new LwSplitPane(className); } else if (UIFormXmlConstants.ELEMENT_TOOLBAR.equals(name)) { String className = LwXmlReader.getOptionalString(child, UIFormXmlConstants.ATTRIBUTE_CLASS, "javax.swing.JToolBar"); component = new LwToolBar(className); } else{ throw new UnexpectedFormElementException("unexpected element: "+child); } return component; } /** * 'xy' or 'grid' */ protected final void readLayout(final Element element){ myLayoutManager = element.getAttributeValue("layout-manager"); if("xy".equals(element.getName())){ myLayoutSerializer = XYLayoutSerializer.INSTANCE; } else if("grid".equals(element.getName())){ createLayoutSerializer(); } else{ throw new UnexpectedFormElementException("unexpected element: "+element); } myLayoutSerializer.readLayout(element, this); } public void setLayoutManager(final String layoutManager) { myLayoutManager = layoutManager; createLayoutSerializer(); } private void createLayoutSerializer() { if (UIFormXmlConstants.LAYOUT_BORDER.equals(myLayoutManager)) { myLayoutSerializer = BorderLayoutSerializer.INSTANCE; } else if (UIFormXmlConstants.LAYOUT_FLOW.equals(myLayoutManager)) { myLayoutSerializer = FlowLayoutSerializer.INSTANCE; } else if (UIFormXmlConstants.LAYOUT_CARD.equals(myLayoutManager)) { myLayoutSerializer = CardLayoutSerializer.INSTANCE; } else if (UIFormXmlConstants.LAYOUT_XY.equals(myLayoutManager)) { myLayoutSerializer = XYLayoutSerializer.INSTANCE; } else if (UIFormXmlConstants.LAYOUT_FORM.equals(myLayoutManager)) { myLayoutSerializer = FormLayoutSerializer.INSTANCE; } else if (UIFormXmlConstants.LAYOUT_GRIDBAG.equals(myLayoutManager)) { myLayoutSerializer = GridBagLayoutSerializer.INSTANCE; } else { myLayoutSerializer = GridLayoutSerializer.INSTANCE; } } public void read(final Element element, final PropertiesProvider provider) throws Exception { readBase(element); // Layout readLayout(element); // Constraints and properties readConstraints(element); readProperties(element, provider); // Border readBorder(element); readChildren(element, provider); } protected void readNoLayout(final Element element, final PropertiesProvider provider) throws Exception { readBase(element); // Constraints and properties readConstraints(element); readProperties(element, provider); // Border readBorder(element); readChildren(element, provider); } public boolean areChildrenExclusive() { return UIFormXmlConstants.LAYOUT_CARD.equals(myLayoutManager); } }