blob: 4e70b4f021dbfa7e7a0538c8bd35ce55e0fd5412 [file] [log] [blame]
/*
* 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);
}
}