UIDesignerCore -> forms-compiler

This commit is contained in:
Dmitry Jemerov
2009-09-03 17:23:15 +04:00
parent 1a9b2b6ce0
commit a77fed15c2
102 changed files with 20 additions and 2 deletions
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<module relativePaths="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="JDOM" level="project" />
<orderEntry type="module" module-name="forms_rt" />
<orderEntry type="library" name="asm" level="project" />
<orderEntry type="library" scope="TEST" name="JUnit3" level="project" />
<orderEntry type="library" name="jgoodies-forms" level="project" />
</component>
</module>
@@ -0,0 +1,22 @@
/*
* Copyright 2000-2005 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.compiler;
public final class AlienFormFileException extends Exception{
public AlienFormFileException(){
super("Not IntelliJ IDEA GUI Designer form file");
}
}
@@ -0,0 +1,937 @@
/*
* Copyright 2000-2005 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.compiler;
import com.intellij.uiDesigner.UIFormXmlConstants;
import com.intellij.uiDesigner.lw.*;
import com.intellij.uiDesigner.shared.BorderType;
import org.objectweb.asm.*;
import org.objectweb.asm.Label;
import org.objectweb.asm.commons.EmptyVisitor;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.*;
/**
* @author yole
*/
public class AsmCodeGenerator {
private final LwRootContainer myRootContainer;
private final ClassLoader myLoader;
private final ArrayList myErrors;
private final ArrayList myWarnings;
private final Map myIdToLocalMap = new HashMap();
private static final String CONSTRUCTOR_NAME = "<init>";
private String myClassToBind;
private byte[] myPatchedData;
private static final Map myContainerLayoutCodeGenerators = new HashMap();
private static final Map myComponentLayoutCodeGenerators = new HashMap();
private static final Map myPropertyCodeGenerators = new HashMap();
public static final String SETUP_METHOD_NAME = "$$$setupUI$$$";
public static final String GET_ROOT_COMPONENT_METHOD_NAME = "$$$getRootComponent$$$";
public static final String CREATE_COMPONENTS_METHOD_NAME = "createUIComponents";
public static final String LOAD_LABEL_TEXT_METHOD = "$$$loadLabelText$$$";
public static final String LOAD_BUTTON_TEXT_METHOD = "$$$loadButtonText$$$";
private static final Type ourButtonGroupType = Type.getType(ButtonGroup.class);
private static final Type ourBorderFactoryType = Type.getType(BorderFactory.class);
private static final Type ourBorderType = Type.getType(Border.class);
private static final Method ourCreateTitledBorderMethod = Method.getMethod(
"javax.swing.border.TitledBorder createTitledBorder(javax.swing.border.Border,java.lang.String,int,int,java.awt.Font,java.awt.Color)");
private final NestedFormLoader myFormLoader;
private final boolean myIgnoreCustomCreation;
private final ClassWriter myClassWriter;
static {
myContainerLayoutCodeGenerators.put(UIFormXmlConstants.LAYOUT_INTELLIJ, new GridLayoutCodeGenerator());
myContainerLayoutCodeGenerators.put(UIFormXmlConstants.LAYOUT_GRIDBAG, new GridBagLayoutCodeGenerator());
myContainerLayoutCodeGenerators.put(UIFormXmlConstants.LAYOUT_BORDER, new SimpleLayoutCodeGenerator(Type.getType(BorderLayout.class)));
myContainerLayoutCodeGenerators.put(UIFormXmlConstants.LAYOUT_CARD, new SimpleLayoutCodeGenerator(Type.getType(CardLayout.class)));
myContainerLayoutCodeGenerators.put(UIFormXmlConstants.LAYOUT_FLOW, new FlowLayoutCodeGenerator());
myComponentLayoutCodeGenerators.put(LwSplitPane.class, new SplitPaneLayoutCodeGenerator());
myComponentLayoutCodeGenerators.put(LwTabbedPane.class, new TabbedPaneLayoutCodeGenerator());
myComponentLayoutCodeGenerators.put(LwScrollPane.class, new ScrollPaneLayoutCodeGenerator());
myComponentLayoutCodeGenerators.put(LwToolBar.class, new ToolBarLayoutCodeGenerator());
myPropertyCodeGenerators.put(String.class.getName(), new StringPropertyCodeGenerator());
myPropertyCodeGenerators.put(Dimension.class.getName(), new DimensionPropertyCodeGenerator());
myPropertyCodeGenerators.put(Insets.class.getName(), new InsetsPropertyCodeGenerator());
myPropertyCodeGenerators.put(Rectangle.class.getName(), new RectanglePropertyCodeGenerator());
myPropertyCodeGenerators.put(Color.class.getName(), new ColorPropertyCodeGenerator());
myPropertyCodeGenerators.put(Font.class.getName(), new FontPropertyCodeGenerator());
myPropertyCodeGenerators.put(Icon.class.getName(), new IconPropertyCodeGenerator());
myPropertyCodeGenerators.put(ListModel.class.getName(), new ListModelPropertyCodeGenerator(DefaultListModel.class));
myPropertyCodeGenerators.put(ComboBoxModel.class.getName(), new ListModelPropertyCodeGenerator(DefaultComboBoxModel.class));
myPropertyCodeGenerators.put("java.lang.Enum", new EnumPropertyCodeGenerator());
}
public AsmCodeGenerator(LwRootContainer rootContainer,
ClassLoader loader,
NestedFormLoader formLoader,
final boolean ignoreCustomCreation,
final ClassWriter classWriter) {
myFormLoader = formLoader;
myIgnoreCustomCreation = ignoreCustomCreation;
if (loader == null){
throw new IllegalArgumentException("loader cannot be null");
}
if (rootContainer == null){
throw new IllegalArgumentException("rootContainer cannot be null");
}
myRootContainer = rootContainer;
myLoader = loader;
myErrors = new ArrayList();
myWarnings = new ArrayList();
myClassWriter = classWriter;
}
public void patchFile(final File classFile) {
if (!classFile.exists()) {
myErrors.add(new FormErrorInfo(null, "Class to bind does not exist: " + myRootContainer.getClassToBind()));
return;
}
FileInputStream fis;
try {
byte[] patchedData;
fis = new FileInputStream(classFile);
try {
patchedData = patchClass(fis);
if (patchedData == null) {
return;
}
}
finally {
fis.close();
}
FileOutputStream fos = new FileOutputStream(classFile);
try {
fos.write(patchedData);
}
finally {
fos.close();
}
}
catch (IOException e) {
myErrors.add(new FormErrorInfo(null, "Cannot read or write class file " + classFile.getPath() + ": " + e.toString()));
}
catch(IllegalStateException e) {
myErrors.add(new FormErrorInfo(null, "Unexpected data in form file when patching class " + classFile.getPath() + ": " + e.toString()));
}
}
public byte[] patchClass(InputStream classStream) {
myClassToBind = myRootContainer.getClassToBind();
if (myClassToBind == null){
myWarnings.add(new FormErrorInfo(null, "No class to bind specified"));
return null;
}
if (myRootContainer.getComponentCount() != 1) {
myErrors.add(new FormErrorInfo(null, "There should be only one component at the top level"));
return null;
}
String nonEmptyPanel = Utils.findNotEmptyPanelWithXYLayout(myRootContainer.getComponent(0));
if (nonEmptyPanel != null) {
myErrors.add(new FormErrorInfo(nonEmptyPanel,
"There are non empty panels with XY layout. Please lay them out in a grid."));
return null;
}
ClassReader reader;
try {
reader = new ClassReader(classStream);
}
catch (IOException e) {
myErrors.add(new FormErrorInfo(null, "Error reading class data stream"));
return null;
}
FirstPassClassVisitor visitor = new FirstPassClassVisitor();
reader.accept(visitor, 0);
reader.accept(new FormClassVisitor(myClassWriter, visitor.isExplicitSetupCall()), 0);
myPatchedData = myClassWriter.toByteArray();
return myPatchedData;
}
public FormErrorInfo[] getErrors() {
return (FormErrorInfo[])myErrors.toArray(new FormErrorInfo[myErrors.size()]);
}
public FormErrorInfo[] getWarnings() {
return (FormErrorInfo[])myWarnings.toArray(new FormErrorInfo[myWarnings.size()]);
}
public byte[] getPatchedData() {
return myPatchedData;
}
static void pushPropValue(GeneratorAdapter generator, String propertyClass, Object value) {
PropertyCodeGenerator codeGen = (PropertyCodeGenerator)myPropertyCodeGenerators.get(propertyClass);
if (codeGen == null) {
throw new RuntimeException("Unknown property class " + propertyClass);
}
codeGen.generatePushValue(generator, value);
}
static Class getComponentClass(String className, final ClassLoader classLoader) throws CodeGenerationException {
try {
return Class.forName(className, false, classLoader);
}
catch (ClassNotFoundException e) {
throw new CodeGenerationException(null, "Class not found: " + className);
}
catch(UnsupportedClassVersionError e) {
throw new CodeGenerationException(null, "Unsupported class version error: " + className);
}
}
public static Type typeFromClassName(final String className) {
return Type.getType("L" + className.replace('.', '/') + ";");
}
class FormClassVisitor extends ClassAdapter {
private String myClassName;
private String mySuperName;
private final Map myFieldDescMap = new HashMap();
private final Map myFieldAccessMap = new HashMap();
private boolean myHaveCreateComponentsMethod = false;
private int myCreateComponentsAccess;
private final boolean myExplicitSetupCall;
public FormClassVisitor(final ClassVisitor cv, final boolean explicitSetupCall) {
super(cv);
myExplicitSetupCall = explicitSetupCall;
}
public void visit(final int version,
final int access,
final String name,
final String signature,
final String superName,
final String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
myClassName = name;
mySuperName = superName;
for (Iterator iterator = myPropertyCodeGenerators.values().iterator(); iterator.hasNext();) {
PropertyCodeGenerator propertyCodeGenerator = (PropertyCodeGenerator)iterator.next();
propertyCodeGenerator.generateClassStart(this, name, myLoader);
}
}
public String getClassName() {
return myClassName;
}
public MethodVisitor visitMethod(final int access,
final String name,
final String desc,
final String signature,
final String[] exceptions) {
if (name.equals(SETUP_METHOD_NAME) || name.equals(GET_ROOT_COMPONENT_METHOD_NAME) ||
name.equals(LOAD_BUTTON_TEXT_METHOD) || name.equals(LOAD_LABEL_TEXT_METHOD)) {
return null;
}
if (name.equals(CREATE_COMPONENTS_METHOD_NAME) && desc.equals("()V")) {
myHaveCreateComponentsMethod = true;
myCreateComponentsAccess = access;
}
final MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions);
if (name.equals(CONSTRUCTOR_NAME) && !myExplicitSetupCall) {
return new FormConstructorVisitor(methodVisitor, myClassName, mySuperName);
}
return methodVisitor;
}
MethodVisitor visitNewMethod(final int access,
final String name,
final String desc,
final String signature,
final String[] exceptions) {
return super.visitMethod(access, name, desc, signature, exceptions);
}
public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) {
myFieldDescMap.put(name, desc);
myFieldAccessMap.put(name, new Integer(access));
return super.visitField(access, name, desc, signature, value);
}
public void visitEnd() {
final boolean haveCustomCreateComponents = Utils.getCustomCreateComponentCount(myRootContainer) > 0 &&
!myIgnoreCustomCreation;
if (haveCustomCreateComponents && !myHaveCreateComponentsMethod) {
myErrors.add(new FormErrorInfo(null, "Form contains components with Custom Create option but no createUIComponents() method"));
}
Method method = Method.getMethod("void " + SETUP_METHOD_NAME + " ()");
GeneratorAdapter generator = new GeneratorAdapter(Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC, method, null, null, cv);
if (haveCustomCreateComponents && myHaveCreateComponentsMethod) {
generator.visitVarInsn(Opcodes.ALOAD, 0);
int opcode = myCreateComponentsAccess == Opcodes.ACC_PRIVATE ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL;
generator.visitMethodInsn(opcode, myClassName, CREATE_COMPONENTS_METHOD_NAME, "()V");
}
buildSetupMethod(generator);
final String rootBinding = myRootContainer.getComponent(0).getBinding();
if (rootBinding != null && myFieldDescMap.containsKey(rootBinding)) {
buildGetRootComponenMethod();
}
for (Iterator iterator = myPropertyCodeGenerators.values().iterator(); iterator.hasNext();) {
PropertyCodeGenerator propertyCodeGenerator = (PropertyCodeGenerator)iterator.next();
propertyCodeGenerator.generateClassEnd(this);
}
super.visitEnd();
}
private void buildGetRootComponenMethod() {
final Type componentType = Type.getType(JComponent.class);
final Method method = new Method(GET_ROOT_COMPONENT_METHOD_NAME, componentType, new Type[0]);
GeneratorAdapter generator = new GeneratorAdapter(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, method, null, null, cv);
final LwComponent topComponent = (LwComponent)myRootContainer.getComponent(0);
final String binding = topComponent.getBinding();
generator.loadThis();
generator.getField(typeFromClassName(myClassName), binding,
Type.getType((String) myFieldDescMap.get(binding)));
generator.returnValue();
generator.endMethod();
}
private void buildSetupMethod(final GeneratorAdapter generator) {
try {
final LwComponent topComponent = (LwComponent)myRootContainer.getComponent(0);
generateSetupCodeForComponent(topComponent, generator, -1);
generateComponentReferenceProperties(topComponent, generator);
generateButtonGroups(myRootContainer, generator);
}
catch (CodeGenerationException e) {
myErrors.add(new FormErrorInfo(e.getComponentId(), e.getMessage()));
}
generator.returnValue();
generator.endMethod();
}
private void generateSetupCodeForComponent(final LwComponent lwComponent,
final GeneratorAdapter generator,
final int parentLocal) throws CodeGenerationException {
String className;
if (lwComponent instanceof LwNestedForm) {
LwRootContainer nestedFormContainer;
LwNestedForm nestedForm = (LwNestedForm) lwComponent;
if (myFormLoader == null) {
throw new CodeGenerationException(null, "Attempt to compile nested form with no nested form loader specified");
}
try {
nestedFormContainer = myFormLoader.loadForm(nestedForm.getFormFileName());
}
catch (Exception e) {
throw new CodeGenerationException(lwComponent.getId(), e.getMessage());
}
// if nested form is empty, ignore
if (nestedFormContainer.getComponentCount() == 0) {
return;
}
if (nestedFormContainer.getComponent(0).getBinding() == null) {
throw new CodeGenerationException(lwComponent.getId(), "No binding on root component of nested form " + nestedForm.getFormFileName());
}
try {
Utils.validateNestedFormLoop(nestedForm.getFormFileName(), myFormLoader);
}
catch (RecursiveFormNestingException e) {
throw new CodeGenerationException(lwComponent.getId(), "Recursive form nesting is not allowed");
}
className = myFormLoader.getClassToBindName(nestedFormContainer);
}
else {
className = getComponentCodeGenerator(lwComponent.getParent()).mapComponentClass(lwComponent.getComponentClassName());
}
Type componentType = typeFromClassName(className);
int componentLocal = generator.newLocal(componentType);
myIdToLocalMap.put(lwComponent.getId(), new Integer(componentLocal));
Class componentClass = getComponentClass(className, myLoader);
validateFieldBinding(lwComponent, componentClass);
if (myIgnoreCustomCreation) {
boolean creatable = true;
if ((componentClass.getModifiers() & (Modifier.PRIVATE | Modifier.ABSTRACT)) != 0) {
creatable = false;
}
else {
try {
final Constructor constructor = componentClass.getConstructor(new Class[0]);
if ((constructor.getModifiers() & Modifier.PUBLIC) == 0) {
creatable = false;
}
}
catch(NoSuchMethodException ex) {
creatable = false;
}
}
if (!creatable) {
componentClass = Utils.suggestReplacementClass(componentClass);
componentType = Type.getType(componentClass);
}
}
if (!lwComponent.isCustomCreate() || myIgnoreCustomCreation) {
generator.newInstance(componentType);
generator.dup();
generator.invokeConstructor(componentType, Method.getMethod("void <init>()"));
generator.storeLocal(componentLocal);
generateFieldBinding(lwComponent, generator, componentLocal);
}
else {
final String binding = lwComponent.getBinding();
if (binding == null) {
throw new CodeGenerationException(lwComponent.getId(),
"Only components bound to fields can have custom creation code");
}
generator.loadThis();
generator.getField(getMainClassType(), binding,
Type.getType((String)myFieldDescMap.get(binding)));
generator.storeLocal(componentLocal);
}
if (lwComponent instanceof LwContainer) {
LwContainer lwContainer = (LwContainer) lwComponent;
if (!lwContainer.isCustomCreate() || lwContainer.getComponentCount() > 0) {
getComponentCodeGenerator(lwContainer).generateContainerLayout(lwContainer, generator, componentLocal);
}
}
generateComponentProperties(lwComponent, componentClass, generator, componentLocal);
// add component to parent
if (!(lwComponent.getParent() instanceof LwRootContainer)) {
final LayoutCodeGenerator parentCodeGenerator = getComponentCodeGenerator(lwComponent.getParent());
if (lwComponent instanceof LwNestedForm) {
componentLocal = getNestedFormComponent(generator, componentClass, componentLocal);
}
parentCodeGenerator.generateComponentLayout(lwComponent, generator, componentLocal, parentLocal);
}
if (lwComponent instanceof LwContainer) {
LwContainer container = (LwContainer) lwComponent;
generateBorder(container, generator, componentLocal);
for(int i=0; i<container.getComponentCount(); i++) {
generateSetupCodeForComponent((LwComponent) container.getComponent(i), generator, componentLocal);
}
}
}
private int getNestedFormComponent(GeneratorAdapter generator, Class componentClass, int formLocal) throws CodeGenerationException {
final Type componentType = Type.getType(JComponent.class);
int componentLocal = generator.newLocal(componentType);
generator.loadLocal(formLocal);
generator.invokeVirtual(Type.getType(componentClass),
new Method(GET_ROOT_COMPONENT_METHOD_NAME, componentType, new Type[0]));
generator.storeLocal(componentLocal);
return componentLocal;
}
private LayoutCodeGenerator getComponentCodeGenerator(final LwContainer container) {
LayoutCodeGenerator generator = (LayoutCodeGenerator) myComponentLayoutCodeGenerators.get(container.getClass());
if (generator != null) {
return generator;
}
LwContainer parent = container;
while(parent != null) {
final String layoutManager = parent.getLayoutManager();
if (layoutManager != null && layoutManager.length() > 0) {
if (layoutManager.equals(UIFormXmlConstants.LAYOUT_FORM) &&
!myContainerLayoutCodeGenerators.containsKey(UIFormXmlConstants.LAYOUT_FORM)) {
myContainerLayoutCodeGenerators.put(UIFormXmlConstants.LAYOUT_FORM, new FormLayoutCodeGenerator());
}
generator = (LayoutCodeGenerator) myContainerLayoutCodeGenerators.get(layoutManager);
if (generator != null) {
return generator;
}
}
parent = parent.getParent();
}
return GridLayoutCodeGenerator.INSTANCE;
}
private void generateComponentProperties(final LwComponent lwComponent,
final Class componentClass,
final GeneratorAdapter generator,
final int componentLocal) throws CodeGenerationException {
// introspected properties
final LwIntrospectedProperty[] introspectedProperties = lwComponent.getAssignedIntrospectedProperties();
for (int i = 0; i < introspectedProperties.length; i++) {
final LwIntrospectedProperty property = introspectedProperties[i];
if (property instanceof LwIntroComponentProperty) {
continue;
}
final String propertyClass = property.getCodeGenPropertyClassName();
if (myIgnoreCustomCreation) {
try {
Class setterClass;
if (propertyClass.equals(Integer.class.getName())) {
setterClass = int.class;
}
else if (propertyClass.equals(Boolean.class.getName())) {
setterClass = boolean.class;
}
else if (propertyClass.equals(Double.class.getName())) {
setterClass = double.class;
}
else if (propertyClass.equals(Float.class.getName())) {
setterClass = float.class;
}
else if (propertyClass.equals(Long.class.getName())) {
setterClass = long.class;
}
else if (propertyClass.equals(Byte.class.getName())) {
setterClass = byte.class;
}
else if (propertyClass.equals(Short.class.getName())) {
setterClass = short.class;
}
else if (propertyClass.equals(Character.class.getName())) {
setterClass = char.class;
}
else {
setterClass = Class.forName(propertyClass);
}
componentClass.getMethod(property.getWriteMethodName(), new Class[] { setterClass } );
}
catch (Exception e) {
continue;
}
}
final PropertyCodeGenerator propGen = (PropertyCodeGenerator) myPropertyCodeGenerators.get(propertyClass);
if (propGen != null && propGen.generateCustomSetValue(lwComponent, componentClass, property,
generator, componentLocal, myClassName)) {
continue;
}
generator.loadLocal(componentLocal);
Object value = lwComponent.getPropertyValue(property);
Type setterArgType;
if (propertyClass.equals(Integer.class.getName())) {
generator.push(((Integer) value).intValue());
setterArgType = Type.INT_TYPE;
}
else if (propertyClass.equals(Boolean.class.getName())) {
generator.push(((Boolean) value).booleanValue());
setterArgType = Type.BOOLEAN_TYPE;
}
else if (propertyClass.equals(Double.class.getName())) {
generator.push(((Double) value).doubleValue());
setterArgType = Type.DOUBLE_TYPE;
}
else if (propertyClass.equals(Float.class.getName())) {
generator.push(((Float) value).floatValue());
setterArgType = Type.FLOAT_TYPE;
}
else if (propertyClass.equals(Long.class.getName())) {
generator.push(((Long) value).longValue());
setterArgType = Type.LONG_TYPE;
}
else if (propertyClass.equals(Short.class.getName())) {
generator.push(((Short) value).intValue());
setterArgType = Type.SHORT_TYPE;
}
else if (propertyClass.equals(Byte.class.getName())) {
generator.push(((Byte) value).intValue());
setterArgType = Type.BYTE_TYPE;
}
else if (propertyClass.equals(Character.class.getName())) {
generator.push(((Character) value).charValue());
setterArgType = Type.CHAR_TYPE;
}
else {
if (propGen == null) {
continue;
}
propGen.generatePushValue(generator, value);
setterArgType = typeFromClassName(property.getPropertyClassName());
}
Type declaringType = (property.getDeclaringClassName() != null)
? typeFromClassName(property.getDeclaringClassName())
: Type.getType(componentClass);
generator.invokeVirtual(declaringType, new Method(property.getWriteMethodName(),
Type.VOID_TYPE, new Type[] { setterArgType } ));
}
generateClientProperties(lwComponent, componentClass, generator, componentLocal);
}
private void generateClientProperties(final LwComponent lwComponent,
final Class componentClass,
final GeneratorAdapter generator,
final int componentLocal) throws CodeGenerationException {
HashMap props = lwComponent.getDelegeeClientProperties();
for (Iterator iterator = props.entrySet().iterator(); iterator.hasNext();) {
Map.Entry e = (Map.Entry) iterator.next();
generator.loadLocal(componentLocal);
generator.push((String) e.getKey());
Object value = e.getValue();
if (value instanceof StringDescriptor) {
generator.push(((StringDescriptor) value).getValue());
}
else {
Type valueType = Type.getType(value.getClass());
generator.newInstance(valueType);
generator.dup();
if (value instanceof Boolean) {
generator.push(((Boolean) value).booleanValue());
generator.invokeConstructor(valueType, Method.getMethod("void <init>(boolean)"));
}
else if (value instanceof Integer) {
generator.push(((Integer) value).intValue());
generator.invokeConstructor(valueType, Method.getMethod("void <init>(int)"));
}
else if (value instanceof Double) {
generator.push(((Double) value).doubleValue());
generator.invokeConstructor(valueType, Method.getMethod("void <init>(double)"));
}
else {
throw new CodeGenerationException(lwComponent.getId(), "Unknown client property value type");
}
}
Type componentType = Type.getType(componentClass);
Type objectType = Type.getType(Object.class);
generator.invokeVirtual(componentType, new Method("putClientProperty",
Type.VOID_TYPE, new Type[] { objectType, objectType } ));
}
}
private void generateComponentReferenceProperties(final LwComponent component,
final GeneratorAdapter generator) throws CodeGenerationException {
if (component instanceof LwNestedForm) return;
int componentLocal = ((Integer) myIdToLocalMap.get(component.getId())).intValue();
final LayoutCodeGenerator layoutCodeGenerator = getComponentCodeGenerator(component.getParent());
Class componentClass = getComponentClass(layoutCodeGenerator.mapComponentClass(component.getComponentClassName()), myLoader);
final LwIntrospectedProperty[] introspectedProperties = component.getAssignedIntrospectedProperties();
for (int i = 0; i < introspectedProperties.length; i++) {
final LwIntrospectedProperty property = introspectedProperties[i];
if (property instanceof LwIntroComponentProperty) {
String targetId = (String) component.getPropertyValue(property);
if (targetId != null && targetId.length() > 0) {
// we may have a reference property pointing to a component which is
// no longer valid
final Integer targetLocalInt = (Integer)myIdToLocalMap.get(targetId);
if (targetLocalInt != null) {
int targetLocal = targetLocalInt.intValue();
generator.loadLocal(componentLocal);
generator.loadLocal(targetLocal);
Type declaringType = (property.getDeclaringClassName() != null)
? typeFromClassName(property.getDeclaringClassName())
: Type.getType(componentClass);
generator.invokeVirtual(declaringType,
new Method(property.getWriteMethodName(),
Type.VOID_TYPE, new Type[] { typeFromClassName(property.getPropertyClassName()) } ));
}
}
}
}
if (component instanceof LwContainer) {
LwContainer container = (LwContainer) component;
for(int i=0; i<container.getComponentCount(); i++) {
generateComponentReferenceProperties((LwComponent) container.getComponent(i), generator);
}
}
}
private void generateButtonGroups(final LwRootContainer rootContainer, final GeneratorAdapter generator) throws CodeGenerationException {
IButtonGroup[] groups = rootContainer.getButtonGroups();
if (groups.length > 0) {
int groupLocal = generator.newLocal(ourButtonGroupType);
for(int groupIndex=0; groupIndex<groups.length; groupIndex++) {
String[] ids = groups [groupIndex].getComponentIds();
if (ids.length > 0) {
generator.newInstance(ourButtonGroupType);
generator.dup();
generator.invokeConstructor(ourButtonGroupType, Method.getMethod("void <init>()"));
generator.storeLocal(groupLocal);
if (groups [groupIndex].isBound() && !myIgnoreCustomCreation) {
validateFieldClass(groups [groupIndex].getName(), ButtonGroup.class, null);
generator.loadThis();
generator.loadLocal(groupLocal);
generator.putField(getMainClassType(), groups [groupIndex].getName(), ourButtonGroupType);
}
for(int i = 0; i<ids.length; i++) {
Integer localInt = (Integer) myIdToLocalMap.get(ids [i]);
if (localInt != null) {
generator.loadLocal(groupLocal);
generator.loadLocal(localInt.intValue());
generator.invokeVirtual(ourButtonGroupType, Method.getMethod("void add(javax.swing.AbstractButton)"));
}
}
}
}
}
}
private void generateFieldBinding(final LwComponent lwComponent,
final GeneratorAdapter generator,
final int componentLocal) throws CodeGenerationException {
final String binding = lwComponent.getBinding();
if (binding != null) {
Integer access = (Integer) myFieldAccessMap.get(binding);
if ((access.intValue() & Opcodes.ACC_STATIC) != 0) {
throw new CodeGenerationException(lwComponent.getId(), "Cannot bind: field is static: " + myClassToBind + "." + binding);
}
if ((access.intValue() & Opcodes.ACC_FINAL) != 0) {
throw new CodeGenerationException(lwComponent.getId(), "Cannot bind: field is final: " + myClassToBind + "." + binding);
}
generator.loadThis();
generator.loadLocal(componentLocal);
generator.putField(getMainClassType(), binding,
Type.getType((String)myFieldDescMap.get(binding)));
}
}
private Type getMainClassType() {
return Type.getType("L" + myClassName + ";");
}
private void validateFieldBinding(LwComponent component, final Class componentClass) throws CodeGenerationException {
String binding = component.getBinding();
if (binding == null) return;
validateFieldClass(binding, componentClass, component.getId());
}
private void validateFieldClass(String binding, Class componentClass, String componentId) throws CodeGenerationException {
if (!myFieldDescMap.containsKey(binding)) {
throw new CodeGenerationException(componentId, "Cannot bind: field does not exist: " + myClassToBind + "." + binding);
}
final Type fieldType = Type.getType((String)myFieldDescMap.get(binding));
if (fieldType.getSort() != Type.OBJECT) {
throw new CodeGenerationException(componentId, "Cannot bind: field is of primitive type: " + myClassToBind + "." + binding);
}
Class fieldClass;
try {
fieldClass = myLoader.loadClass(fieldType.getClassName());
}
catch (ClassNotFoundException e) {
throw new CodeGenerationException(componentId, "Class not found: " + fieldType.getClassName());
}
if (!fieldClass.isAssignableFrom(componentClass)) {
throw new CodeGenerationException(componentId, "Cannot bind: Incompatible types. Cannot assign " + componentClass.getName() + " to field " + myClassToBind + "." + binding);
}
}
private void generateBorder(final LwContainer container, final GeneratorAdapter generator, final int componentLocal) {
final BorderType borderType = container.getBorderType();
final StringDescriptor borderTitle = container.getBorderTitle();
final String borderFactoryMethodName = borderType.getBorderFactoryMethodName();
final boolean borderNone = borderType.equals(BorderType.NONE);
if (!borderNone || borderTitle != null) {
// object to invoke setBorder
generator.loadLocal(componentLocal);
if (!borderNone) {
if (borderType.equals(BorderType.LINE)) {
if (container.getBorderColor() == null) {
Type colorType = Type.getType(Color.class);
generator.getStatic(colorType, "black", colorType);
}
else {
pushPropValue(generator, Color.class.getName(), container.getBorderColor());
}
generator.invokeStatic(ourBorderFactoryType,
new Method(borderFactoryMethodName, ourBorderType,
new Type[] { Type.getType(Color.class) } ));
}
else if (borderType.equals(BorderType.EMPTY) && container.getBorderSize() != null) {
Insets size = container.getBorderSize();
generator.push(size.top);
generator.push(size.left);
generator.push(size.bottom);
generator.push(size.right);
generator.invokeStatic(ourBorderFactoryType,
new Method(borderFactoryMethodName, ourBorderType,
new Type[] { Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE }));
}
else {
generator.invokeStatic(ourBorderFactoryType,
new Method(borderFactoryMethodName, ourBorderType, new Type[0]));
}
}
else {
generator.push((String) null);
}
pushBorderProperties(container, generator, borderTitle, componentLocal);
generator.invokeStatic(ourBorderFactoryType, ourCreateTitledBorderMethod);
// set border
generator.invokeVirtual(Type.getType(JComponent.class),
Method.getMethod("void setBorder(javax.swing.border.Border)"));
}
}
private void pushBorderProperties(final LwContainer container, final GeneratorAdapter generator, final StringDescriptor borderTitle,
final int componentLocal) {
pushPropValue(generator, "java.lang.String", borderTitle);
generator.push(container.getBorderTitleJustification());
generator.push(container.getBorderTitlePosition());
final FontDescriptor font = container.getBorderTitleFont();
if (font == null) {
generator.push((String) null);
}
else {
FontPropertyCodeGenerator.generatePushFont(generator, componentLocal, container, font, "getFont");
}
if (container.getBorderTitleColor() == null) {
generator.push((String) null);
}
else {
pushPropValue(generator, Color.class.getName(), container.getBorderTitleColor());
}
}
}
private class FormConstructorVisitor extends MethodAdapter {
private final String myClassName;
private final String mySuperName;
private boolean callsSelfConstructor = false;
private boolean mySetupCalled = false;
private boolean mySuperCalled = false;
public FormConstructorVisitor(final MethodVisitor mv, final String className, final String superName) {
super(mv);
myClassName = className;
mySuperName = superName;
}
public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) {
if (opcode == Opcodes.GETFIELD && !mySetupCalled && !callsSelfConstructor && Utils.isBoundField(myRootContainer, name)) {
callSetupUI();
}
super.visitFieldInsn(opcode, owner, name, desc);
}
public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
if (opcode == Opcodes.INVOKESPECIAL && name.equals(CONSTRUCTOR_NAME)) {
if (owner.equals(myClassName)) {
callsSelfConstructor = true;
}
else if (owner.equals(mySuperName)) {
mySuperCalled = true;
}
else if (mySuperCalled) {
callSetupUI();
}
}
else if (mySuperCalled) {
callSetupUI();
}
super.visitMethodInsn(opcode, owner, name, desc);
}
public void visitJumpInsn(final int opcode, final Label label) {
if (mySuperCalled) {
callSetupUI();
}
super.visitJumpInsn(opcode, label);
}
private void callSetupUI() {
if (!mySetupCalled) {
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, myClassName, SETUP_METHOD_NAME, "()V");
mySetupCalled = true;
}
}
public void visitInsn(final int opcode) {
if (opcode == Opcodes.RETURN && !mySetupCalled && !callsSelfConstructor) {
callSetupUI();
}
super.visitInsn(opcode);
}
}
private static class FirstPassClassVisitor extends ClassAdapter {
private boolean myExplicitSetupCall = false;
public FirstPassClassVisitor() {
super(new EmptyVisitor());
}
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (name.equals(CONSTRUCTOR_NAME)) {
return new FirstPassConstructorVisitor();
}
return null;
}
public boolean isExplicitSetupCall() {
return myExplicitSetupCall;
}
private class FirstPassConstructorVisitor extends MethodAdapter {
public FirstPassConstructorVisitor() {
super(new EmptyVisitor());
}
public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
if (name.equals(SETUP_METHOD_NAME)) {
myExplicitSetupCall = true;
}
}
}
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2000-2005 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.compiler;
public final class ClassToBindNotFoundException extends CodeGenerationException{
public ClassToBindNotFoundException(final String message) {
super(null, message);
}
}
@@ -0,0 +1,29 @@
/*
* Copyright 2000-2005 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.compiler;
public class CodeGenerationException extends Exception{
private final String myComponentId;
public CodeGenerationException(final String componentId, final String message) {
super(message);
myComponentId = componentId;
}
public String getComponentId() {
return myComponentId;
}
}
@@ -0,0 +1,60 @@
/*
* Copyright 2000-2005 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.compiler;
import com.intellij.uiDesigner.lw.ColorDescriptor;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import java.awt.*;
/**
* @author yole
* @noinspection HardCodedStringLiteral
*/
public class ColorPropertyCodeGenerator extends PropertyCodeGenerator {
private static final Type ourColorType = Type.getType(Color.class);
private static final Type ourObjectType = Type.getType(Object.class);
private static final Type ourUIManagerType = Type.getType("Ljavax/swing/UIManager;");
private static final Type ourSystemColorType = Type.getType(SystemColor.class);
private static final Method ourInitMethod = Method.getMethod("void <init>(int)");
private static final Method ourGetColorMethod = new Method("getColor", ourColorType, new Type[] { ourObjectType } );
public void generatePushValue(final GeneratorAdapter generator, final Object value) {
ColorDescriptor descriptor = (ColorDescriptor) value;
if (descriptor.getColor() != null) {
generator.newInstance(ourColorType);
generator.dup();
generator.push(descriptor.getColor().getRGB());
generator.invokeConstructor(ourColorType, ourInitMethod);
}
else if (descriptor.getSwingColor() != null) {
generator.push(descriptor.getSwingColor());
generator.invokeStatic(ourUIManagerType, ourGetColorMethod);
}
else if (descriptor.getSystemColor() != null) {
generator.getStatic(ourSystemColorType, descriptor.getSystemColor(), ourSystemColorType);
}
else if (descriptor.getAWTColor() != null) {
generator.getStatic(ourColorType, descriptor.getAWTColor(), ourColorType);
}
else if (descriptor.isColorSet()) {
throw new IllegalStateException("Unknown color type");
}
}
}
@@ -0,0 +1,25 @@
package com.intellij.uiDesigner.compiler;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import org.objectweb.asm.Type;
import java.awt.*;
/**
* @author yole
* @noinspection HardCodedStringLiteral
*/
public class DimensionPropertyCodeGenerator extends PropertyCodeGenerator {
private static final Type myDimensionType = Type.getType(Dimension.class);
private static final Method myInitMethod = Method.getMethod("void <init>(int,int)");
public void generatePushValue(final GeneratorAdapter generator, final Object value) {
Dimension dimension = (Dimension) value;
generator.newInstance(myDimensionType);
generator.dup();
generator.push(dimension.width);
generator.push(dimension.height);
generator.invokeConstructor(myDimensionType, myInitMethod);
}
}
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2006 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.compiler;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.Type;
/**
* @author yole
*/
public class EnumPropertyCodeGenerator extends PropertyCodeGenerator {
public void generatePushValue(final GeneratorAdapter generator, final Object value) {
final Type enumType = Type.getType(value.getClass());
generator.getStatic(enumType, value.toString(), enumType);
}
}
@@ -0,0 +1,55 @@
/*
* Copyright 2000-2006 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.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwContainer;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import java.awt.FlowLayout;
/**
* @author yole
*/
public class FlowLayoutCodeGenerator extends LayoutCodeGenerator {
private static final Type ourFlowLayoutType = Type.getType(FlowLayout.class);
private static final Method ourConstructor = Method.getMethod("void <init>(int,int,int)");
public void generateContainerLayout(final LwContainer lwContainer, final GeneratorAdapter generator, final int componentLocal) {
generator.loadLocal(componentLocal);
FlowLayout flowLayout = (FlowLayout) lwContainer.getLayout();
generator.newInstance(ourFlowLayoutType);
generator.dup();
generator.push(flowLayout.getAlignment());
generator.push(flowLayout.getHgap());
generator.push(flowLayout.getVgap());
generator.invokeConstructor(ourFlowLayoutType, ourConstructor);
generator.invokeVirtual(ourContainerType, ourSetLayoutMethod);
}
public void generateComponentLayout(final LwComponent lwComponent,
final GeneratorAdapter generator,
final int componentLocal,
final int parentLocal) {
generator.loadLocal(parentLocal);
generator.loadLocal(componentLocal);
generator.invokeVirtual(ourContainerType, ourAddNoConstraintMethod);
}
}
@@ -0,0 +1,118 @@
/*
* Copyright 2000-2005 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.compiler;
import com.intellij.uiDesigner.lw.FontDescriptor;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwIntrospectedProperty;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import java.awt.*;
/**
* @author yole
* @noinspection HardCodedStringLiteral
*/
public class FontPropertyCodeGenerator extends PropertyCodeGenerator {
private static final Type ourFontType = Type.getType(Font.class);
private static final Type ourUIManagerType = Type.getType("Ljavax/swing/UIManager;");
private static final Type ourObjectType = Type.getType(Object.class);
private static final Type ourStringType = Type.getType(String.class);
private static final Method ourInitMethod = Method.getMethod("void <init>(java.lang.String,int,int)");
private static final Method ourUIManagerGetFontMethod = new Method("getFont", ourFontType, new Type[] { ourObjectType } );
private static final Method ourGetNameMethod = new Method("getName", ourStringType, new Type[0] );
private static final Method ourGetSizeMethod = new Method("getSize", Type.INT_TYPE, new Type[0] );
private static final Method ourGetStyleMethod = new Method("getStyle", Type.INT_TYPE, new Type[0] );
public boolean generateCustomSetValue(final LwComponent lwComponent,
final Class componentClass,
final LwIntrospectedProperty property,
final GeneratorAdapter generator,
final int componentLocal, final String formClassName) {
FontDescriptor descriptor = (FontDescriptor) property.getPropertyValue(lwComponent);
if (descriptor.isFixedFont() && !descriptor.isFullyDefinedFont()) {
generator.loadLocal(componentLocal);
generatePushFont(generator, componentLocal, lwComponent, descriptor, property.getReadMethodName());
Method setFontMethod = new Method(property.getWriteMethodName(), Type.VOID_TYPE, new Type[] { ourFontType } );
Type componentType = AsmCodeGenerator.typeFromClassName(lwComponent.getComponentClassName());
generator.invokeVirtual(componentType, setFontMethod);
return true;
}
return false;
}
public static void generatePushFont(final GeneratorAdapter generator, final int componentLocal, final LwComponent lwComponent,
final FontDescriptor descriptor, final String readMethodName) {
final int fontLocal = generator.newLocal(ourFontType);
generator.loadLocal(componentLocal);
Type componentType = AsmCodeGenerator.typeFromClassName(lwComponent.getComponentClassName());
Method getFontMethod = new Method(readMethodName, ourFontType, new Type[0] );
generator.invokeVirtual(componentType, getFontMethod);
generator.storeLocal(fontLocal);
generator.newInstance(ourFontType);
generator.dup();
if (descriptor.getFontName() != null) {
generator.push(descriptor.getFontName());
}
else {
generator.loadLocal(fontLocal);
generator.invokeVirtual(ourFontType, ourGetNameMethod);
}
if (descriptor.getFontStyle() >= 0) {
generator.push(descriptor.getFontStyle());
}
else {
generator.loadLocal(fontLocal);
generator.invokeVirtual(ourFontType, ourGetStyleMethod);
}
if (descriptor.getFontSize() >= 0) {
generator.push(descriptor.getFontSize());
}
else {
generator.loadLocal(fontLocal);
generator.invokeVirtual(ourFontType, ourGetSizeMethod);
}
generator.invokeConstructor(ourFontType, ourInitMethod);
}
public void generatePushValue(final GeneratorAdapter generator, final Object value) {
FontDescriptor descriptor = (FontDescriptor) value;
if (descriptor.isFixedFont()) {
if (!descriptor.isFullyDefinedFont()) throw new IllegalStateException("Unexpected font state");
generator.newInstance(ourFontType);
generator.dup();
generator.push(descriptor.getFontName());
generator.push(descriptor.getFontStyle());
generator.push(descriptor.getFontSize());
generator.invokeConstructor(ourFontType, ourInitMethod);
}
else if (descriptor.getSwingFont() != null) {
generator.push(descriptor.getSwingFont());
generator.invokeStatic(ourUIManagerType, ourUIManagerGetFontMethod);
}
else {
throw new IllegalStateException("Unknown font type");
}
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 2000-2006 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.compiler;
/**
* @author yole
*/
public class FormErrorInfo {
private String myComponentId;
private String myErrorMessage;
public FormErrorInfo(final String componentId, final String errorMessage) {
myComponentId = componentId;
myErrorMessage = errorMessage;
}
public String getComponentId() {
return myComponentId;
}
public void setComponentId(final String componentId) {
myComponentId = componentId;
}
public String getErrorMessage() {
return myErrorMessage;
}
public void setErrorMessage(final String errorMessage) {
myErrorMessage = errorMessage;
}
}
@@ -0,0 +1,125 @@
/*
* Copyright 2000-2006 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.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwContainer;
import com.intellij.uiDesigner.core.GridConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.CellConstraints;
import org.objectweb.asm.Type;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import java.awt.Insets;
/**
* @author yole
*/
public class FormLayoutCodeGenerator extends LayoutCodeGenerator {
private static final Type ourFormLayoutType = Type.getType(FormLayout.class);
private static final Type ourCellConstraintsType = Type.getType(CellConstraints.class);
private static final Type ourCellAlignmentType = Type.getType(CellConstraints.Alignment.class);
private static final Method ourFormLayoutConstructor = Method.getMethod("void <init>(java.lang.String,java.lang.String)");
private static final Method ourCellConstraintsConstructor = Method.getMethod("void <init>(int,int,int,int,com.jgoodies.forms.layout.CellConstraints$Alignment,com.jgoodies.forms.layout.CellConstraints$Alignment,java.awt.Insets)");
private static final Method ourSetRowGroupsMethod = Method.getMethod("void setRowGroups(int[][])");
private static final Method ourSetColumnGroupsMethod = Method.getMethod("void setColumnGroups(int[][])");
public static String[] HORZ_ALIGN_FIELDS = new String[] { "LEFT", "CENTER", "RIGHT", "FILL" };
public static String[] VERT_ALIGN_FIELDS = new String[] { "TOP", "CENTER", "BOTTOM", "FILL" };
public void generateContainerLayout(final LwContainer lwContainer, final GeneratorAdapter generator, final int componentLocal) {
FormLayout formLayout = (FormLayout) lwContainer.getLayout();
generator.loadLocal(componentLocal);
generator.newInstance(ourFormLayoutType);
generator.dup();
generator.push(FormLayoutUtils.getEncodedColumnSpecs(formLayout));
generator.push(FormLayoutUtils.getEncodedRowSpecs(formLayout));
generator.invokeConstructor(ourFormLayoutType, ourFormLayoutConstructor);
generateGroups(generator, formLayout.getRowGroups(), ourSetRowGroupsMethod);
generateGroups(generator, formLayout.getColumnGroups(), ourSetColumnGroupsMethod);
generator.invokeVirtual(ourContainerType, ourSetLayoutMethod);
}
private static void generateGroups(final GeneratorAdapter generator, final int[][] groups, final Method setGroupsMethod) {
if (groups.length == 0) return;
int groupLocal = generator.newLocal(Type.getType("[I"));
generator.dup(); // duplicate FormLayout reference
generator.push(groups.length);
generator.newArray(Type.getType("[I"));
for(int i=0; i<groups.length; i++) {
generator.dup();
generator.push(groups [i].length);
generator.newArray(Type.INT_TYPE);
generator.storeLocal(groupLocal);
for(int j=0; j<groups [i].length; j++) {
generator.loadLocal(groupLocal);
generator.push(j);
generator.push(groups [i][j]);
generator.visitInsn(Opcodes.IASTORE);
}
generator.push(i);
generator.loadLocal(groupLocal);
generator.visitInsn(Opcodes.AASTORE);
}
generator.invokeVirtual(ourFormLayoutType, setGroupsMethod);
}
public void generateComponentLayout(final LwComponent lwComponent, final GeneratorAdapter generator, final int componentLocal, final int parentLocal) {
generator.loadLocal(parentLocal);
generator.loadLocal(componentLocal);
addNewCellConstraints(generator, lwComponent);
generator.invokeVirtual(ourContainerType, ourAddMethod);
}
private static void addNewCellConstraints(final GeneratorAdapter generator, final LwComponent lwComponent) {
final GridConstraints constraints = lwComponent.getConstraints();
final CellConstraints cc = (CellConstraints) lwComponent.getCustomLayoutConstraints();
generator.newInstance(ourCellConstraintsType);
generator.dup();
generator.push(constraints.getColumn()+1);
generator.push(constraints.getRow()+1);
generator.push(constraints.getColSpan());
generator.push(constraints.getRowSpan());
if (cc.hAlign == CellConstraints.DEFAULT) {
generator.getStatic(ourCellConstraintsType, "DEFAULT", ourCellAlignmentType);
}
else {
int hAlign = Utils.alignFromConstraints(constraints, true);
generator.getStatic(ourCellConstraintsType, HORZ_ALIGN_FIELDS[hAlign], ourCellAlignmentType);
}
if (cc.vAlign == CellConstraints.DEFAULT) {
generator.getStatic(ourCellConstraintsType, "DEFAULT", ourCellAlignmentType);
}
else {
int vAlign = Utils.alignFromConstraints(constraints, false);
generator.getStatic(ourCellConstraintsType, VERT_ALIGN_FIELDS[vAlign], ourCellAlignmentType);
}
AsmCodeGenerator.pushPropValue(generator, Insets.class.getName(), cc.insets);
generator.invokeConstructor(ourCellConstraintsType, ourCellConstraintsConstructor);
}
}
@@ -0,0 +1,70 @@
/*
* Copyright 2000-2006 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.
*/
/*
* Created by IntelliJ IDEA.
* User: yole
* Date: 25.07.2006
* Time: 18:27:54
*/
package com.intellij.uiDesigner.compiler;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.FormSpec;
public class FormLayoutUtils {
private FormLayoutUtils() {
}
public static String getEncodedRowSpecs(final FormLayout formLayout) {
StringBuffer result = new StringBuffer();
for(int i=1; i<=formLayout.getRowCount(); i++) {
if (result.length() > 0) {
result.append(",");
}
result.append(getEncodedSpec(formLayout.getRowSpec(i)));
}
return result.toString();
}
public static String getEncodedColumnSpecs(final FormLayout formLayout) {
StringBuffer result = new StringBuffer();
for(int i=1; i<=formLayout.getColumnCount(); i++) {
if (result.length() > 0) {
result.append(",");
}
result.append(getEncodedSpec(formLayout.getColumnSpec(i)));
}
return result.toString();
}
public static String getEncodedSpec(final FormSpec formSpec) {
String result = formSpec.toString();
while(true) {
int pos = result.indexOf("dluX");
if (pos < 0) {
pos = result.indexOf("dluY");
}
if (pos < 0) {
break;
}
result = result.substring(0, pos+3) + result.substring(pos+4);
}
return result;
}
}
@@ -0,0 +1,323 @@
/*
* Copyright 2000-2005 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.compiler;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.AbstractLayout;
import com.intellij.uiDesigner.core.Util;
import com.intellij.uiDesigner.lw.*;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
/**
* @author yole
*/
public class GridBagConverter {
private final Insets myInsets;
private int myHGap;
private int myVGap;
private boolean mySameSizeHorz;
private boolean mySameSizeVert;
private final ArrayList myComponents = new ArrayList();
private final ArrayList myConstraints = new ArrayList();
private int myLastRow = -1;
private int myLastCol = -1;
public GridBagConverter() {
myInsets = new Insets(0, 0, 0, 0);
}
public GridBagConverter(final Insets insets, final int hgap, final int vgap, final boolean sameSizeHorz, final boolean sameSizeVert) {
myInsets = insets;
myHGap = hgap;
myVGap = vgap;
mySameSizeHorz = sameSizeHorz;
mySameSizeVert = sameSizeVert;
}
public void addComponent(final JComponent component, final GridConstraints constraints) {
myComponents.add(component);
myConstraints.add(constraints);
}
public static void prepareConstraints(final LwContainer container, final Map idToConstraintsMap) {
GridLayoutManager gridLayout = (GridLayoutManager) container.getLayout();
GridBagConverter converter = new GridBagConverter(gridLayout.getMargin(),
getGap(container, true),
getGap(container, false),
gridLayout.isSameSizeHorizontally(),
gridLayout.isSameSizeVertically());
for(int i=0; i<container.getComponentCount(); i++) {
final LwComponent component = (LwComponent)container.getComponent(i);
if (component instanceof LwHSpacer || component instanceof LwVSpacer) {
GridConstraints constraints = component.getConstraints().store();
constraints.setHSizePolicy(constraints.getHSizePolicy() & ~GridConstraints.SIZEPOLICY_WANT_GROW);
constraints.setVSizePolicy(constraints.getVSizePolicy() & ~GridConstraints.SIZEPOLICY_WANT_GROW);
converter.addComponent(null, constraints);
}
else {
converter.addComponent(null, component.getConstraints());
}
}
Result[] results = converter.convert();
int componentIndex = 0;
for(int i=0; i<results.length; i++) {
if (!results [i].isFillerPanel) {
final LwComponent component = (LwComponent)container.getComponent(componentIndex++);
idToConstraintsMap.put(component.getId(), results [i]);
}
// else generateFillerPanel(generator, componentLocal, results [i]);
}
}
private static int getGap(LwContainer container, final boolean horizontal) {
while(container != null) {
final LayoutManager layout = container.getLayout();
if (layout instanceof AbstractLayout) {
AbstractLayout aLayout = (AbstractLayout) layout;
final int gap = horizontal ? aLayout.getHGap() : aLayout.getVGap();
if (gap >= 0) {
return gap;
}
}
container = container.getParent();
}
return horizontal ? AbstractLayout.DEFAULT_HGAP : AbstractLayout.DEFAULT_VGAP;
}
public static class Result {
public JComponent component;
public boolean isFillerPanel;
public GridBagConstraints constraints;
public Dimension preferredSize;
public Dimension minimumSize;
public Dimension maximumSize;
public Result(final JComponent component) {
this.component = component;
constraints = new GridBagConstraints();
}
}
public Result[] convert() {
ArrayList results = new ArrayList();
for(int i=0; i<myComponents.size(); i++) {
results.add(convert((JComponent) myComponents.get(i), (GridConstraints) myConstraints.get(i)));
}
//addFillerPanels(results);
final Result[] resultArray = (Result[])results.toArray(new Result[results.size()]);
if (myHGap > 0 || myVGap > 0) {
applyGaps(resultArray);
}
if (mySameSizeHorz) {
makeSameSizes(resultArray, true);
}
if (mySameSizeVert) {
makeSameSizes(resultArray, false);
}
return resultArray;
}
private void applyGaps(final Result[] resultArray) {
int leftGap = myHGap/2;
int rightGap = myHGap - myHGap/2;
int topGap = myVGap / 2;
int bottomGap = myVGap - myVGap/2;
for(int i=0; i<resultArray.length; i++) {
Result result = resultArray [i];
if (result.constraints.gridx > 0) {
result.constraints.insets.left += leftGap;
}
if (result.constraints.gridx + result.constraints.gridwidth-1 < myLastCol) {
result.constraints.insets.right += rightGap;
}
if (result.constraints.gridy > 0) {
result.constraints.insets.top += topGap;
}
if (result.constraints.gridy + result.constraints.gridheight-1 < myLastRow) {
result.constraints.insets.bottom += bottomGap;
}
}
}
private static void makeSameSizes(final Result[] resultArray, boolean horizontal) {
int minimum = -1;
int preferred = -1;
for(int i=0; i<resultArray.length; i++) {
Result result = resultArray [i];
Dimension minSize = result.minimumSize != null || result.component == null
? result.minimumSize
: result.component.getMinimumSize();
Dimension prefSize = result.preferredSize != null || result.component == null
? result.preferredSize
: result.component.getPreferredSize();
if (minSize != null) {
minimum = Math.max(minimum, horizontal ? minSize.width : minSize.height);
}
if (prefSize != null) {
preferred = Math.max(preferred, horizontal ? prefSize.width : prefSize.height);
}
}
if (minimum >= 0 || preferred >= 0) {
for(int i=0; i<resultArray.length; i++) {
Result result = resultArray [i];
if ((result.minimumSize != null || result.component != null) && minimum >= 0) {
if (result.minimumSize == null) {
result.minimumSize = result.component.getMinimumSize();
}
if (horizontal) {
result.minimumSize.width = minimum;
}
else {
result.minimumSize.height = minimum;
}
}
if ((result.preferredSize != null || result.component != null) && preferred >= 0) {
if (result.preferredSize == null) {
result.preferredSize = result.component.getPreferredSize();
}
if (horizontal) {
result.preferredSize.width = preferred;
}
else {
result.preferredSize.height = preferred;
}
}
}
}
}
private Result convert(final JComponent component, final GridConstraints constraints) {
final Result result = new Result(component);
int endRow = constraints.getRow() + constraints.getRowSpan()-1;
myLastRow = Math.max(myLastRow, endRow);
int endCol = constraints.getColumn() + constraints.getColSpan()-1;
myLastCol = Math.max(myLastCol, endCol);
int indent = Util.DEFAULT_INDENT * constraints.getIndent();
constraintsToGridBag(constraints, result.constraints);
result.constraints.weightx = getWeight(constraints, true);
result.constraints.weighty = getWeight(constraints, false);
result.constraints.insets = new Insets(myInsets.top, myInsets.left + indent, myInsets.bottom, myInsets.right);
Dimension minSize = constraints.myMinimumSize;
if (component != null && minSize.width <= 0 && minSize.height <= 0) {
minSize = component.getMinimumSize();
}
if ((constraints.getHSizePolicy() & GridConstraints.SIZEPOLICY_CAN_SHRINK) == 0) {
minSize.width = constraints.myPreferredSize.width > 0 || component == null
? constraints.myPreferredSize.width
: component.getPreferredSize().width;
}
if ((constraints.getVSizePolicy() & GridConstraints.SIZEPOLICY_CAN_SHRINK) == 0) {
minSize.height = constraints.myPreferredSize.height > 0 || component == null
? constraints.myPreferredSize.height
: component.getPreferredSize().height;
}
if (minSize.width != -1 || minSize.height != -1) {
result.minimumSize = minSize;
}
if (constraints.myPreferredSize.width > 0 && constraints.myPreferredSize.height > 0) {
result.preferredSize = constraints.myPreferredSize;
}
if (constraints.myMaximumSize.width > 0 && constraints.myMaximumSize.height > 0) {
result.maximumSize = constraints.myMaximumSize;
}
return result;
}
public static GridBagConstraints getGridBagConstraints(IComponent component) {
final GridBagConstraints gbc;
if (component.getCustomLayoutConstraints() instanceof GridBagConstraints) {
gbc = (GridBagConstraints) component.getCustomLayoutConstraints();
}
else {
gbc = new GridBagConstraints();
}
constraintsToGridBag(component.getConstraints(), gbc);
return gbc;
}
public static void constraintsToGridBag(final GridConstraints constraints, final GridBagConstraints result) {
result.gridx = constraints.getColumn();
result.gridy = constraints.getRow();
result.gridwidth = constraints.getColSpan();
result.gridheight = constraints.getRowSpan();
switch(constraints.getFill()) {
case GridConstraints.FILL_HORIZONTAL: result.fill = GridBagConstraints.HORIZONTAL; break;
case GridConstraints.FILL_VERTICAL: result.fill = GridBagConstraints.VERTICAL; break;
case GridConstraints.FILL_BOTH: result.fill = GridBagConstraints.BOTH; break;
default: result.fill = GridBagConstraints.NONE; break;
}
switch(constraints.getAnchor()) {
case GridConstraints.ANCHOR_NORTHWEST: result.anchor = GridBagConstraints.NORTHWEST; break;
case GridConstraints.ANCHOR_NORTH: result.anchor = GridBagConstraints.NORTH; break;
case GridConstraints.ANCHOR_NORTHEAST: result.anchor = GridBagConstraints.NORTHEAST; break;
case GridConstraints.ANCHOR_EAST: result.anchor = GridBagConstraints.EAST; break;
case GridConstraints.ANCHOR_SOUTHEAST: result.anchor = GridBagConstraints.SOUTHEAST; break;
case GridConstraints.ANCHOR_SOUTH: result.anchor = GridBagConstraints.SOUTH; break;
case GridConstraints.ANCHOR_SOUTHWEST: result.anchor = GridBagConstraints.SOUTHWEST; break;
case GridConstraints.ANCHOR_WEST: result.anchor = GridBagConstraints.WEST; break;
}
}
private double getWeight(final GridConstraints constraints, final boolean horizontal) {
int policy = horizontal ? constraints.getHSizePolicy() : constraints.getVSizePolicy();
if ((policy & GridConstraints.SIZEPOLICY_WANT_GROW) != 0) {
return 1.0;
}
boolean canGrow = ((policy & GridConstraints.SIZEPOLICY_CAN_GROW) != 0);
for (Iterator iterator = myConstraints.iterator(); iterator.hasNext();) {
GridConstraints otherConstraints = (GridConstraints)iterator.next();
if (!constraintsIntersect(horizontal, constraints, otherConstraints)) {
int otherPolicy = horizontal ? otherConstraints.getHSizePolicy() : otherConstraints.getVSizePolicy();
if ((otherPolicy & GridConstraints.SIZEPOLICY_WANT_GROW) != 0) {
return 0.0;
}
if (!canGrow && ((otherPolicy & GridConstraints.SIZEPOLICY_CAN_GROW) != 0)) {
return 0.0;
}
}
}
return 1.0;
}
private boolean constraintsIntersect(final boolean horizontal,
final GridConstraints constraints,
final GridConstraints otherConstraints) {
int start = constraints.getCell(!horizontal);
int end = start + constraints.getSpan(!horizontal) - 1;
int otherStart = otherConstraints.getCell(!horizontal);
int otherEnd = otherStart + otherConstraints.getSpan(!horizontal) - 1;
return start <= otherEnd && otherStart <= end;
}
}
@@ -0,0 +1,166 @@
/*
* Copyright 2000-2005 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.compiler;
import com.intellij.uiDesigner.core.Spacer;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwContainer;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import javax.swing.*;
import java.awt.*;
/**
* @author yole
*/
public class GridBagLayoutCodeGenerator extends LayoutCodeGenerator {
private static final Type ourGridBagLayoutType = Type.getType(GridBagLayout.class);
private static final Type ourGridBagConstraintsType = Type.getType(GridBagConstraints.class);
private static final Method ourDefaultConstructor = Method.getMethod("void <init> ()");
private static final Type myPanelType = Type.getType(JPanel.class);
public String mapComponentClass(final String componentClassName) {
if (componentClassName.equals(Spacer.class.getName())) {
return JPanel.class.getName();
}
return super.mapComponentClass(componentClassName);
}
public void generateContainerLayout(final LwContainer lwContainer, final GeneratorAdapter generator, final int componentLocal) {
generator.loadLocal(componentLocal);
generator.newInstance(ourGridBagLayoutType);
generator.dup();
generator.invokeConstructor(ourGridBagLayoutType, ourDefaultConstructor);
generator.invokeVirtual(ourContainerType, ourSetLayoutMethod);
}
private void generateFillerPanel(final GeneratorAdapter generator, final int parentLocal, final GridBagConverter.Result result) {
int panelLocal = generator.newLocal(myPanelType);
generator.newInstance(myPanelType);
generator.dup();
generator.invokeConstructor(myPanelType, ourDefaultConstructor);
generator.storeLocal(panelLocal);
generateConversionResult(generator, result, panelLocal, parentLocal);
}
public void generateComponentLayout(final LwComponent component,
final GeneratorAdapter generator,
final int componentLocal,
final int parentLocal) {
GridBagConstraints gbc;
if (component.getCustomLayoutConstraints() instanceof GridBagConstraints) {
gbc = (GridBagConstraints) component.getCustomLayoutConstraints();
}
else {
gbc = new GridBagConstraints();
}
GridBagConverter.constraintsToGridBag(component.getConstraints(), gbc);
generateGridBagConstraints(generator, gbc, componentLocal, parentLocal);
}
private static void generateConversionResult(final GeneratorAdapter generator, final GridBagConverter.Result result,
final int componentLocal, final int parentLocal) {
checkSetSize(generator, componentLocal, "setMinimumSize", result.minimumSize);
checkSetSize(generator, componentLocal, "setPreferredSize", result.preferredSize);
checkSetSize(generator, componentLocal, "setMaximumSize", result.maximumSize);
generateGridBagConstraints(generator, result.constraints, componentLocal, parentLocal);
}
private static void generateGridBagConstraints(final GeneratorAdapter generator, GridBagConstraints constraints, final int componentLocal,
final int parentLocal) {
int gbcLocal = generator.newLocal(ourGridBagConstraintsType);
generator.newInstance(ourGridBagConstraintsType);
generator.dup();
generator.invokeConstructor(ourGridBagConstraintsType, ourDefaultConstructor);
generator.storeLocal(gbcLocal);
GridBagConstraints defaults = new GridBagConstraints();
if (defaults.gridx != constraints.gridx) {
setIntField(generator, gbcLocal, "gridx", constraints.gridx);
}
if (defaults.gridy != constraints.gridy) {
setIntField(generator, gbcLocal, "gridy", constraints.gridy);
}
if (defaults.gridwidth != constraints.gridwidth) {
setIntField(generator, gbcLocal, "gridwidth", constraints.gridwidth);
}
if (defaults.gridheight != constraints.gridheight) {
setIntField(generator, gbcLocal, "gridheight", constraints.gridheight);
}
if (defaults.weightx != constraints.weightx) {
setDoubleField(generator, gbcLocal, "weightx", constraints.weightx);
}
if (defaults.weighty != constraints.weighty) {
setDoubleField(generator, gbcLocal, "weighty", constraints.weighty);
}
if (defaults.anchor != constraints.anchor) {
setIntField(generator, gbcLocal, "anchor", constraints.anchor);
}
if (defaults.fill != constraints.fill) {
setIntField(generator, gbcLocal, "fill", constraints.fill);
}
if (defaults.ipadx != constraints.ipadx) {
setIntField(generator, gbcLocal, "ipadx", constraints.ipadx);
}
if (defaults.ipady != constraints.ipady) {
setIntField(generator, gbcLocal, "ipady", constraints.ipady);
}
if (!defaults.insets.equals(constraints.insets)) {
generator.loadLocal(gbcLocal);
AsmCodeGenerator.pushPropValue(generator, Insets.class.getName(), constraints.insets);
generator.putField(ourGridBagConstraintsType, "insets", Type.getType(Insets.class));
}
generator.loadLocal(parentLocal);
generator.loadLocal(componentLocal);
generator.loadLocal(gbcLocal);
generator.invokeVirtual(ourContainerType, ourAddMethod);
}
private static void checkSetSize(final GeneratorAdapter generator, final int componentLocal, final String methodName, final Dimension dimension) {
if (dimension != null) {
generator.loadLocal(componentLocal);
AsmCodeGenerator.pushPropValue(generator, "java.awt.Dimension", dimension);
generator.invokeVirtual(Type.getType(Component.class),
new Method(methodName, Type.VOID_TYPE, new Type[] { Type.getType(Dimension.class) }));
}
}
private static void setIntField(final GeneratorAdapter generator, final int local, final String fieldName, final int value) {
generator.loadLocal(local);
generator.push(value);
generator.putField(ourGridBagConstraintsType, fieldName, Type.INT_TYPE);
}
private static void setDoubleField(final GeneratorAdapter generator, final int local, final String fieldName, final double value) {
generator.loadLocal(local);
generator.push(value);
generator.putField(ourGridBagConstraintsType, fieldName, Type.DOUBLE_TYPE);
}
}
@@ -0,0 +1,103 @@
/*
* Copyright 2000-2005 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.compiler;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwContainer;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
/**
* @author yole
* @noinspection HardCodedStringLiteral
*/
public class GridLayoutCodeGenerator extends LayoutCodeGenerator {
private static final Method myInitConstraintsMethod = Method.getMethod("void <init> (int,int,int,int,int,int,int,int,java.awt.Dimension,java.awt.Dimension,java.awt.Dimension)");
private static final Method myInitConstraintsIndentMethod = Method.getMethod("void <init> (int,int,int,int,int,int,int,int,java.awt.Dimension,java.awt.Dimension,java.awt.Dimension,int)");
private static final Method myInitConstraintsIndentParentMethod = Method.getMethod("void <init> (int,int,int,int,int,int,int,int,java.awt.Dimension,java.awt.Dimension,java.awt.Dimension,int,boolean)");
private static final Method ourGridLayoutManagerConstructor = Method.getMethod("void <init> (int,int,java.awt.Insets,int,int,boolean,boolean)");
private static final Type myGridLayoutManagerType = Type.getType(GridLayoutManager.class);
private static final Type myGridConstraintsType = Type.getType(GridConstraints.class);
public static GridLayoutCodeGenerator INSTANCE = new GridLayoutCodeGenerator();
public void generateContainerLayout(final LwContainer lwContainer, final GeneratorAdapter generator, final int componentLocal) {
if (lwContainer.isGrid()) {
// arg 0: object
generator.loadLocal(componentLocal);
// arg 1: layout
final GridLayoutManager layout = (GridLayoutManager)lwContainer.getLayout();
generator.newInstance(myGridLayoutManagerType);
generator.dup();
generator.push(layout.getRowCount());
generator.push(layout.getColumnCount());
AsmCodeGenerator.pushPropValue(generator, "java.awt.Insets", layout.getMargin());
generator.push(layout.getHGap());
generator.push(layout.getVGap());
generator.push(layout.isSameSizeHorizontally());
generator.push(layout.isSameSizeVertically());
generator.invokeConstructor(myGridLayoutManagerType, ourGridLayoutManagerConstructor);
generator.invokeVirtual(ourContainerType, ourSetLayoutMethod);
}
}
public void generateComponentLayout(final LwComponent lwComponent,
final GeneratorAdapter generator,
final int componentLocal,
final int parentLocal) {
generator.loadLocal(parentLocal);
generator.loadLocal(componentLocal);
addNewGridConstraints(generator, lwComponent);
generator.invokeVirtual(ourContainerType, ourAddMethod);
}
private static void addNewGridConstraints(final GeneratorAdapter generator, final LwComponent lwComponent) {
final GridConstraints constraints = lwComponent.getConstraints();
generator.newInstance(myGridConstraintsType);
generator.dup();
generator.push(constraints.getRow());
generator.push(constraints.getColumn());
generator.push(constraints.getRowSpan());
generator.push(constraints.getColSpan());
generator.push(constraints.getAnchor());
generator.push(constraints.getFill());
generator.push(constraints.getHSizePolicy());
generator.push(constraints.getVSizePolicy());
newDimensionOrNull(generator, constraints.myMinimumSize);
newDimensionOrNull(generator, constraints.myPreferredSize);
newDimensionOrNull(generator, constraints.myMaximumSize);
if (constraints.isUseParentLayout()) {
generator.push(constraints.getIndent());
generator.push(constraints.isUseParentLayout());
generator.invokeConstructor(myGridConstraintsType, myInitConstraintsIndentParentMethod);
}
else if (constraints.getIndent() != 0) {
generator.push(constraints.getIndent());
generator.invokeConstructor(myGridConstraintsType, myInitConstraintsIndentMethod);
}
else {
generator.invokeConstructor(myGridConstraintsType, myInitConstraintsMethod);
}
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2000-2005 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.compiler;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import org.objectweb.asm.Type;
import com.intellij.uiDesigner.lw.IconDescriptor;
import javax.swing.*;
/**
* @author yole
*/
public class IconPropertyCodeGenerator extends PropertyCodeGenerator {
private static final Type ourImageIconType = Type.getType(ImageIcon.class);
private static final Method ourInitMethod = Method.getMethod("void <init>(java.net.URL)");
private static final Method ourGetResourceMethod = Method.getMethod("java.net.URL getResource(java.lang.String)");
private static final Method ourGetClassMethod = new Method("getClass", "()Ljava/lang/Class;");
private static final Type ourObjectType = Type.getType(Object.class);
private static final Type ourClassType = Type.getType(Class.class);
public void generatePushValue(final GeneratorAdapter generator, final Object value) {
IconDescriptor descriptor = (IconDescriptor) value;
generator.newInstance(ourImageIconType);
generator.dup();
generator.loadThis();
generator.invokeVirtual(ourObjectType, ourGetClassMethod);
generator.push("/" + descriptor.getIconPath());
generator.invokeVirtual(ourClassType, ourGetResourceMethod);
generator.invokeConstructor(ourImageIconType, ourInitMethod);
}
}
@@ -0,0 +1,29 @@
package com.intellij.uiDesigner.compiler;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import org.objectweb.asm.Type;
import java.awt.*;
/**
* Created by IntelliJ IDEA.
* User: yole
* Date: 22.11.2005
* Time: 17:46:41
* To change this template use File | Settings | File Templates.
*/
public class InsetsPropertyCodeGenerator extends PropertyCodeGenerator {
private final Type myInsetsType = Type.getType(Insets.class);
public void generatePushValue(final GeneratorAdapter generator, final Object value) {
final Insets insets = (Insets) value;
generator.newInstance(myInsetsType);
generator.dup();
generator.push(insets.top);
generator.push(insets.left);
generator.push(insets.bottom);
generator.push(insets.right);
generator.invokeConstructor(myInsetsType, Method.getMethod("void <init>(int,int,int,int)"));
}
}
@@ -0,0 +1,55 @@
/*
* Copyright 2000-2005 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.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwContainer;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import java.awt.*;
/**
* @author yole
* @noinspection HardCodedStringLiteral
*/
public abstract class LayoutCodeGenerator {
protected static final Method ourSetLayoutMethod = Method.getMethod("void setLayout(java.awt.LayoutManager)");
protected static final Type ourContainerType = Type.getType(Container.class);
protected static final Method ourAddMethod = Method.getMethod("void add(java.awt.Component,java.lang.Object)");
protected static final Method ourAddNoConstraintMethod = Method.getMethod("java.awt.Component add(java.awt.Component)");
public void generateContainerLayout(final LwContainer lwContainer, final GeneratorAdapter generator, final int componentLocal) {
}
public abstract void generateComponentLayout(final LwComponent lwComponent, final GeneratorAdapter generator, final int componentLocal,
final int parentLocal);
protected static void newDimensionOrNull(final GeneratorAdapter generator, final Dimension dimension) {
if (dimension.width == -1 && dimension.height == -1) {
generator.visitInsn(Opcodes.ACONST_NULL);
}
else {
AsmCodeGenerator.pushPropValue(generator, "java.awt.Dimension", dimension);
}
}
public String mapComponentClass(final String componentClassName) {
return componentClassName;
}
}
@@ -0,0 +1,52 @@
/*
* Copyright 2000-2006 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.compiler;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
/**
* @author yole
*/
public class ListModelPropertyCodeGenerator extends PropertyCodeGenerator {
private final Type myListModelType;
private static final Method ourInitMethod = Method.getMethod("void <init>()");
private static final Method ourAddElementMethod = Method.getMethod("void addElement(java.lang.Object)");
public ListModelPropertyCodeGenerator(final Class aClass) {
myListModelType = Type.getType(aClass);
}
public void generatePushValue(final GeneratorAdapter generator, final Object value) {
String[] items = (String[]) value;
int listModelLocal = generator.newLocal(myListModelType);
generator.newInstance(myListModelType);
generator.dup();
generator.invokeConstructor(myListModelType, ourInitMethod);
generator.storeLocal(listModelLocal);
for(int i=0; i<items.length; i++) {
generator.loadLocal(listModelLocal);
generator.push(items [i]);
generator.invokeVirtual(myListModelType, ourAddElementMethod);
}
generator.loadLocal(listModelLocal);
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2000-2006 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.compiler;
import com.intellij.uiDesigner.lw.LwRootContainer;
/**
* @author yole
*/
public interface NestedFormLoader {
LwRootContainer loadForm(String formFileName) throws Exception;
String getClassToBindName(LwRootContainer container);
}
@@ -0,0 +1,25 @@
package com.intellij.uiDesigner.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwIntrospectedProperty;
import org.objectweb.asm.commons.GeneratorAdapter;
/**
* @author yole
*/
public abstract class PropertyCodeGenerator {
public abstract void generatePushValue(final GeneratorAdapter generator, final Object value);
public boolean generateCustomSetValue(final LwComponent lwComponent,
final Class componentClass, final LwIntrospectedProperty property,
final GeneratorAdapter generator,
final int componentLocal, final String formClassName) {
return false;
}
public void generateClassStart(AsmCodeGenerator.FormClassVisitor visitor, final String name, final ClassLoader loader) {
}
public void generateClassEnd(AsmCodeGenerator.FormClassVisitor visitor) {
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2005 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.compiler;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import org.objectweb.asm.Type;
import java.awt.*;
/**
* @author yole
*/
public class RectanglePropertyCodeGenerator extends PropertyCodeGenerator {
private static final Type myRectangleType = Type.getType(Rectangle.class);
private static final Method myInitMethod = Method.getMethod("void <init>(int,int,int,int)");
public void generatePushValue(final GeneratorAdapter generator, final Object value) {
final Rectangle rc = (Rectangle) value;
generator.newInstance(myRectangleType);
generator.dup();
generator.push(rc.x);
generator.push(rc.y);
generator.push(rc.width);
generator.push(rc.height);
generator.invokeConstructor(myRectangleType, myInitMethod);
}
}
@@ -0,0 +1,26 @@
/*
* Copyright 2000-2006 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.compiler;
/**
* @author yole
*/
public class RecursiveFormNestingException extends Exception {
public RecursiveFormNestingException() {
super("Recursive form nesting is not allowed");
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2005 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.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import javax.swing.*;
/**
* @author yole
*/
public class ScrollPaneLayoutCodeGenerator extends LayoutCodeGenerator {
private final Type myScrollPaneType = Type.getType(JScrollPane.class);
private final Method mySetViewportViewMethod = Method.getMethod("void setViewportView(java.awt.Component)");
public void generateComponentLayout(final LwComponent lwComponent,
final GeneratorAdapter generator,
final int componentLocal,
final int parentLocal) {
generator.loadLocal(parentLocal);
generator.loadLocal(componentLocal);
generator.invokeVirtual(myScrollPaneType, mySetViewportViewMethod);
}
}
@@ -0,0 +1,60 @@
/*
* Copyright 2000-2006 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.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwContainer;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
/**
* Layout code generator shared between BorderLayout and CardLayout.
*
* @author yole
*/
public class SimpleLayoutCodeGenerator extends LayoutCodeGenerator {
private final Type myLayoutType;
private static final Method ourConstructor = Method.getMethod("void <init>(int,int)");
public SimpleLayoutCodeGenerator(final Type layoutType) {
myLayoutType = layoutType;
}
public void generateContainerLayout(final LwContainer lwContainer, final GeneratorAdapter generator, final int componentLocal) {
generator.loadLocal(componentLocal);
generator.newInstance(myLayoutType);
generator.dup();
generator.push(Utils.getHGap(lwContainer.getLayout()));
generator.push(Utils.getVGap(lwContainer.getLayout()));
generator.invokeConstructor(myLayoutType, ourConstructor);
generator.invokeVirtual(ourContainerType, ourSetLayoutMethod);
}
public void generateComponentLayout(final LwComponent lwComponent,
final GeneratorAdapter generator,
final int componentLocal,
final int parentLocal) {
generator.loadLocal(parentLocal);
generator.loadLocal(componentLocal);
generator.push((String) lwComponent.getCustomLayoutConstraints());
generator.invokeVirtual(ourContainerType, ourAddMethod);
}
}
@@ -0,0 +1,47 @@
/*
* Copyright 2000-2005 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.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwSplitPane;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import javax.swing.*;
/**
* @author yole
*/
public class SplitPaneLayoutCodeGenerator extends LayoutCodeGenerator {
private final Type mySplitPaneType = Type.getType(JSplitPane.class);
private final Method mySetLeftMethod = Method.getMethod("void setLeftComponent(java.awt.Component)");
private final Method mySetRightMethod = Method.getMethod("void setRightComponent(java.awt.Component)");
public void generateComponentLayout(final LwComponent lwComponent,
final GeneratorAdapter generator,
final int componentLocal,
final int parentLocal) {
generator.loadLocal(parentLocal);
generator.loadLocal(componentLocal);
if (LwSplitPane.POSITION_LEFT.equals(lwComponent.getCustomLayoutConstraints())) {
generator.invokeVirtual(mySplitPaneType, mySetLeftMethod);
}
else {
generator.invokeVirtual(mySplitPaneType, mySetRightMethod);
}
}
}
@@ -0,0 +1,225 @@
package com.intellij.uiDesigner.compiler;
import com.intellij.uiDesigner.core.SupportCode;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwIntrospectedProperty;
import com.intellij.uiDesigner.lw.StringDescriptor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import javax.swing.*;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.HashSet;
/**
* @author yole
*/
public class StringPropertyCodeGenerator extends PropertyCodeGenerator implements Opcodes {
private static final Type myResourceBundleType = Type.getType(ResourceBundle.class);
private final Method myGetBundleMethod = Method.getMethod("java.util.ResourceBundle getBundle(java.lang.String)");
private final Method myGetStringMethod = Method.getMethod("java.lang.String getString(java.lang.String)");
private static final Method myLoadLabelTextMethod = new Method(AsmCodeGenerator.LOAD_LABEL_TEXT_METHOD, Type.VOID_TYPE,
new Type[] { Type.getType(JLabel.class), Type.getType(String.class) } );
private static final Method myLoadButtonTextMethod = new Method(AsmCodeGenerator.LOAD_BUTTON_TEXT_METHOD, Type.VOID_TYPE,
new Type[] { Type.getType(AbstractButton.class), Type.getType(String.class) } );
private final Set myClassesRequiringLoadLabelText = new HashSet();
private final Set myClassesRequiringLoadButtonText = new HashSet();
private boolean myHaveSetDisplayedMnemonicIndex = false;
public void generateClassStart(AsmCodeGenerator.FormClassVisitor visitor, final String name, final ClassLoader loader) {
myClassesRequiringLoadLabelText.remove(name);
myClassesRequiringLoadButtonText.remove(name);
try {
Class c = loader.loadClass(AbstractButton.class.getName());
if (c.getMethod("getDisplayedMnemonicIndex", new Class[0]) != null) {
myHaveSetDisplayedMnemonicIndex = true;
}
}
catch (Exception e) {
// ignore
}
}
public boolean generateCustomSetValue(final LwComponent lwComponent,
final Class componentClass,
final LwIntrospectedProperty property,
final GeneratorAdapter generator,
final int componentLocal,
final String formClassName) {
if ("text".equals(property.getName()) &&
(AbstractButton.class.isAssignableFrom(componentClass) || JLabel.class.isAssignableFrom(componentClass))) {
final StringDescriptor propertyValue = (StringDescriptor)lwComponent.getPropertyValue(property);
if (propertyValue.getValue() != null) {
final SupportCode.TextWithMnemonic textWithMnemonic = SupportCode.parseText(propertyValue.getValue());
if (textWithMnemonic.myMnemonicIndex >= 0) {
generator.loadLocal(componentLocal);
generator.push(textWithMnemonic.myText);
generator.invokeVirtual(Type.getType(componentClass),
new Method(property.getWriteMethodName(),
Type.VOID_TYPE, new Type[] { Type.getType(String.class) } ));
String setMnemonicMethodName;
if (AbstractButton.class.isAssignableFrom(componentClass)) {
setMnemonicMethodName = "setMnemonic";
}
else {
setMnemonicMethodName = "setDisplayedMnemonic";
}
generator.loadLocal(componentLocal);
generator.push(textWithMnemonic.getMnemonicChar());
generator.invokeVirtual(Type.getType(componentClass),
new Method(setMnemonicMethodName,
Type.VOID_TYPE, new Type[] { Type.CHAR_TYPE } ));
if (myHaveSetDisplayedMnemonicIndex) {
generator.loadLocal(componentLocal);
generator.push(textWithMnemonic.myMnemonicIndex);
generator.invokeVirtual(Type.getType(componentClass),
new Method("setDisplayedMnemonicIndex",
Type.VOID_TYPE, new Type[] { Type.INT_TYPE } ));
}
return true;
}
}
else {
Method method;
if (AbstractButton.class.isAssignableFrom(componentClass)) {
myClassesRequiringLoadButtonText.add(formClassName);
method = myLoadButtonTextMethod;
}
else {
myClassesRequiringLoadLabelText.add(formClassName);
method = myLoadLabelTextMethod;
}
generator.loadThis();
generator.loadLocal(componentLocal);
generator.push(propertyValue.getBundleName());
generator.invokeStatic(myResourceBundleType, myGetBundleMethod);
generator.push(propertyValue.getKey());
generator.invokeVirtual(myResourceBundleType, myGetStringMethod);
generator.invokeVirtual(Type.getType("L" + formClassName + ";"), method);
return true;
}
}
return false;
}
public void generatePushValue(final GeneratorAdapter generator, final Object value) {
StringDescriptor descriptor = (StringDescriptor) value;
if (descriptor == null) {
generator.push((String)null);
}
else if (descriptor.getValue() !=null) {
generator.push(descriptor.getValue());
}
else {
generator.push(descriptor.getBundleName());
generator.invokeStatic(myResourceBundleType, myGetBundleMethod);
generator.push(descriptor.getKey());
generator.invokeVirtual(myResourceBundleType, myGetStringMethod);
}
}
public void generateClassEnd(AsmCodeGenerator.FormClassVisitor visitor) {
if (myClassesRequiringLoadLabelText.contains(visitor.getClassName())) {
generateLoadTextMethod(visitor, AsmCodeGenerator.LOAD_LABEL_TEXT_METHOD, "javax/swing/JLabel", "setDisplayedMnemonic");
myClassesRequiringLoadLabelText.remove(visitor.getClassName());
}
if (myClassesRequiringLoadButtonText.contains(visitor.getClassName())) {
generateLoadTextMethod(visitor, AsmCodeGenerator.LOAD_BUTTON_TEXT_METHOD, "javax/swing/AbstractButton", "setMnemonic");
myClassesRequiringLoadButtonText.remove(visitor.getClassName());
}
}
private void generateLoadTextMethod(final AsmCodeGenerator.FormClassVisitor visitor, final String methodName, final String componentClass,
final String setMnemonicMethodName) {
MethodVisitor mv = visitor.visitNewMethod(ACC_PRIVATE | ACC_SYNTHETIC, methodName, "(L" + componentClass + ";Ljava/lang/String;)V", null, null);
mv.visitCode();
mv.visitTypeInsn(NEW, "java/lang/StringBuffer");
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "()V");
mv.visitVarInsn(ASTORE, 3);
mv.visitInsn(ICONST_0);
mv.visitVarInsn(ISTORE, 4);
mv.visitInsn(ICONST_0);
mv.visitVarInsn(ISTORE, 5);
mv.visitInsn(ICONST_M1);
mv.visitVarInsn(ISTORE, 6);
mv.visitInsn(ICONST_0);
mv.visitVarInsn(ISTORE, 7);
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitVarInsn(ILOAD, 7);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I");
Label l1 = new Label();
mv.visitJumpInsn(IF_ICMPGE, l1);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ILOAD, 7);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
mv.visitIntInsn(BIPUSH, 38);
Label l2 = new Label();
mv.visitJumpInsn(IF_ICMPNE, l2);
mv.visitIincInsn(7, 1);
mv.visitVarInsn(ILOAD, 7);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I");
Label l3 = new Label();
mv.visitJumpInsn(IF_ICMPNE, l3);
mv.visitJumpInsn(GOTO, l1);
mv.visitLabel(l3);
mv.visitVarInsn(ILOAD, 4);
mv.visitJumpInsn(IFNE, l2);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ILOAD, 7);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
mv.visitIntInsn(BIPUSH, 38);
mv.visitJumpInsn(IF_ICMPEQ, l2);
mv.visitInsn(ICONST_1);
mv.visitVarInsn(ISTORE, 4);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ILOAD, 7);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
mv.visitVarInsn(ISTORE, 5);
mv.visitVarInsn(ALOAD, 3);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "length", "()I");
mv.visitVarInsn(ISTORE, 6);
mv.visitLabel(l2);
mv.visitVarInsn(ALOAD, 3);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ILOAD, 7);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(C)Ljava/lang/StringBuffer;");
mv.visitInsn(POP);
mv.visitIincInsn(7, 1);
mv.visitJumpInsn(GOTO, l0);
mv.visitLabel(l1);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 3);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;");
mv.visitMethodInsn(INVOKEVIRTUAL, componentClass, "setText", "(Ljava/lang/String;)V");
mv.visitVarInsn(ILOAD, 4);
Label l4 = new Label();
mv.visitJumpInsn(IFEQ, l4);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ILOAD, 5);
mv.visitMethodInsn(INVOKEVIRTUAL, componentClass, setMnemonicMethodName, "(C)V");
if (myHaveSetDisplayedMnemonicIndex) {
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ILOAD, 6);
mv.visitMethodInsn(INVOKEVIRTUAL, componentClass, "setDisplayedMnemonicIndex", "(I)V");
}
mv.visitLabel(l4);
mv.visitInsn(RETURN);
mv.visitMaxs(3, 8);
mv.visitEnd();
}
}
@@ -0,0 +1,74 @@
/*
* Copyright 2000-2005 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.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
import com.intellij.uiDesigner.lw.LwTabbedPane;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
import javax.swing.*;
/**
* @author yole
*/
public class TabbedPaneLayoutCodeGenerator extends LayoutCodeGenerator {
private final Type myTabbedPaneType = Type.getType(JTabbedPane.class);
private final Method myAddTabMethod = Method.getMethod("void addTab(java.lang.String,javax.swing.Icon,java.awt.Component,java.lang.String)");
private final Method mySetDisabledIconAtMethod = Method.getMethod("void setDisabledIconAt(int,javax.swing.Icon)");
private final Method mySetEnabledAtMethod = Method.getMethod("void setEnabledAt(int,boolean)");
public void generateComponentLayout(final LwComponent lwComponent,
final GeneratorAdapter generator,
final int componentLocal,
final int parentLocal) {
generator.loadLocal(parentLocal);
final LwTabbedPane.Constraints tabConstraints = (LwTabbedPane.Constraints)lwComponent.getCustomLayoutConstraints();
if (tabConstraints == null){
throw new IllegalArgumentException("tab constraints cannot be null: " + lwComponent.getId());
}
AsmCodeGenerator.pushPropValue(generator, String.class.getName(), tabConstraints.myTitle);
if (tabConstraints.myIcon == null) {
generator.push((String) null);
}
else {
AsmCodeGenerator.pushPropValue(generator, Icon.class.getName(), tabConstraints.myIcon);
}
generator.loadLocal(componentLocal);
if (tabConstraints.myToolTip == null) {
generator.push((String) null);
}
else {
AsmCodeGenerator.pushPropValue(generator, String.class.getName(), tabConstraints.myToolTip);
}
generator.invokeVirtual(myTabbedPaneType, myAddTabMethod);
int index = lwComponent.getParent().indexOfComponent(lwComponent);
if (tabConstraints.myDisabledIcon != null) {
generator.loadLocal(parentLocal);
generator.push(index);
AsmCodeGenerator.pushPropValue(generator, Icon.class.getName(), tabConstraints.myDisabledIcon);
generator.invokeVirtual(myTabbedPaneType, mySetDisabledIconAtMethod);
}
if (!tabConstraints.myEnabled) {
generator.loadLocal(parentLocal);
generator.push(index);
generator.push(tabConstraints.myEnabled);
generator.invokeVirtual(myTabbedPaneType, mySetEnabledAtMethod);
}
}
}
@@ -0,0 +1,37 @@
/*
* Copyright 2000-2006 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.compiler;
import com.intellij.uiDesigner.lw.LwComponent;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
/**
* @author yole
*/
public class ToolBarLayoutCodeGenerator extends LayoutCodeGenerator {
private final static Method ourAddMethod = Method.getMethod("java.awt.Component add(java.awt.Component)");
public void generateComponentLayout(final LwComponent lwComponent,
final GeneratorAdapter generator,
final int componentLocal,
final int parentLocal) {
generator.loadLocal(parentLocal);
generator.loadLocal(componentLocal);
generator.invokeVirtual(ourContainerType, ourAddMethod);
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2000-2006 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.compiler;
/**
* @author yole
*/
public class UnexpectedFormElementException extends RuntimeException {
public UnexpectedFormElementException(String message) {
super(message);
}
}
@@ -0,0 +1,348 @@
/*
* Copyright 2000-2005 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.compiler;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.lw.*;
import org.jdom.Document;
import org.jdom.input.SAXBuilder;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.swing.*;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.awt.*;
import java.io.InputStream;
import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
* <p/>
* NOTE: the class must be compilable with JDK 1.3, so any methods and filds introduced in 1.4 or later must not be used
*/
public final class Utils {
public static final String FORM_NAMESPACE = "http://www.intellij.com/uidesigner/form/";
private static final SAXParser SAX_PARSER = createParser();
private Utils() {
}
private static SAXParser createParser() {
try {
return SAXParserFactory.newInstance().newSAXParser();
}
catch (Exception e) {
return null;
}
}
/**
* @param provider if null, no classes loaded and no properties read
*/
public static LwRootContainer getRootContainer(final String formFileContent, final PropertiesProvider provider) throws Exception {
if (formFileContent.indexOf(FORM_NAMESPACE) == -1) {
throw new AlienFormFileException();
}
final Document document = new SAXBuilder().build(new StringReader(formFileContent), "UTF-8");
return getRootContainerFromDocument(document, provider);
}
/**
* Get root from the url
*
* @param formFile the document URL
* @param provider the provider
* @return the root container
* @throws Exception if there is a problem with parsing DOM
*/
public static LwRootContainer getRootContainer(final URL formFile, final PropertiesProvider provider) throws Exception {
final Document document = new SAXBuilder().build(formFile);
return getRootContainerFromDocument(document, provider);
}
/**
* Get root from the document
*
* @param document the parsed document
* @param provider the provider
* @return the root container
* @throws Exception if there is a problem with parsing DOM
*/
private static LwRootContainer getRootContainerFromDocument(Document document, PropertiesProvider provider) throws Exception {
final LwRootContainer root = new LwRootContainer();
root.read(document.getRootElement(), provider);
return root;
}
public static LwRootContainer getRootContainer(final InputStream stream, final PropertiesProvider provider) throws Exception {
final Document document = new SAXBuilder().build(stream, "UTF-8");
return getRootContainerFromDocument(document, provider);
}
public synchronized static String getBoundClassName(final String formFileContent) throws Exception {
if (formFileContent.indexOf(FORM_NAMESPACE) == -1) {
throw new AlienFormFileException();
}
final String[] className = new String[]{null};
try {
SAX_PARSER.parse(new InputSource(new StringReader(formFileContent)), new DefaultHandler() {
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if ("form".equals(qName)) {
className[0] = attributes.getValue("", "bind-to-class");
throw new SAXException("stop parsing");
}
}
});
}
catch (Exception e) {
// Do nothing.
}
return className[0];
}
/**
* Validates that specified class represents {@link javax.swing.JComponent} with
* empty constructor.
*
* @return descriptive human readable error message or <code>null</code> if
* no errors were detected.
*/
public static String validateJComponentClass(final ClassLoader loader, final String className, final boolean validateConstructor) {
if (loader == null) {
throw new IllegalArgumentException("loader cannot be null");
}
if (className == null) {
throw new IllegalArgumentException("className cannot be null");
}
// These classes are not visible for passed class loader!
if ("com.intellij.uiDesigner.HSpacer".equals(className) || "com.intellij.uiDesigner.VSpacer".equals(className)) {
return null;
}
final Class aClass;
try {
aClass = Class.forName(className, true, loader);
}
catch (final ClassNotFoundException exc) {
return "Class \"" + className + "\"not found";
}
catch (NoClassDefFoundError exc) {
return "Cannot load class " + className + ": " + exc.getMessage();
}
catch (ExceptionInInitializerError exc) {
return "Cannot initialize class " + className + ": " + exc.getMessage();
}
catch (UnsupportedClassVersionError exc) {
return "Unsupported class version error: " + className;
}
if (validateConstructor) {
try {
final Constructor constructor = aClass.getConstructor(new Class[0]);
if ((constructor.getModifiers() & Modifier.PUBLIC) == 0) {
return "Class \"" + className + "\" does not have default public constructor";
}
}
catch (final Exception exc) {
return "Class \"" + className + "\" does not have default constructor";
}
}
// Check that JComponent is accessible via the loader
if (!JComponent.class.isAssignableFrom(aClass)) {
return "Class \"" + className + "\" is not an instance of javax.swing.JComponent";
}
return null;
}
public static void validateNestedFormLoop(final String formName, final NestedFormLoader nestedFormLoader)
throws CodeGenerationException, RecursiveFormNestingException {
validateNestedFormLoop(formName, nestedFormLoader, null);
}
public static void validateNestedFormLoop(final String formName, final NestedFormLoader nestedFormLoader, final String targetForm)
throws CodeGenerationException, RecursiveFormNestingException {
HashSet usedFormNames = new HashSet();
if (targetForm != null) {
usedFormNames.add(targetForm);
}
validateNestedFormLoop(usedFormNames, formName, nestedFormLoader);
}
private static void validateNestedFormLoop(final Set usedFormNames, final String formName, final NestedFormLoader nestedFormLoader)
throws CodeGenerationException, RecursiveFormNestingException {
if (usedFormNames.contains(formName)) {
throw new RecursiveFormNestingException();
}
usedFormNames.add(formName);
final LwRootContainer rootContainer;
try {
rootContainer = nestedFormLoader.loadForm(formName);
}
catch (Exception e) {
throw new CodeGenerationException(null, "Error loading nested form: " + e.getMessage());
}
final Set thisFormNestedForms = new HashSet();
final CodeGenerationException[] validateExceptions = new CodeGenerationException[1];
final RecursiveFormNestingException[] recursiveNestingExceptions = new RecursiveFormNestingException[1];
rootContainer.accept(new ComponentVisitor() {
public boolean visit(final IComponent component) {
if (component instanceof LwNestedForm) {
LwNestedForm nestedForm = (LwNestedForm)component;
if (!thisFormNestedForms.contains(nestedForm.getFormFileName())) {
thisFormNestedForms.add(nestedForm.getFormFileName());
try {
validateNestedFormLoop(usedFormNames, nestedForm.getFormFileName(), nestedFormLoader);
}
catch (RecursiveFormNestingException e) {
recursiveNestingExceptions[0] = e;
return false;
}
catch (CodeGenerationException e) {
validateExceptions[0] = e;
return false;
}
}
}
return true;
}
});
if (recursiveNestingExceptions[0] != null) {
throw recursiveNestingExceptions[0];
}
if (validateExceptions[0] != null) {
throw validateExceptions[0];
}
}
public static String findNotEmptyPanelWithXYLayout(final IComponent component) {
if (!(component instanceof IContainer)) {
return null;
}
final IContainer container = (IContainer)component;
if (container.getComponentCount() == 0) {
return null;
}
if (container.isXY()) {
return container.getId();
}
for (int i = 0; i < container.getComponentCount(); i++) {
String id = findNotEmptyPanelWithXYLayout(container.getComponent(i));
if (id != null) {
return id;
}
}
return null;
}
public static int getHGap(LayoutManager layout) {
if (layout instanceof BorderLayout) {
return ((BorderLayout)layout).getHgap();
}
if (layout instanceof CardLayout) {
return ((CardLayout)layout).getHgap();
}
return 0;
}
public static int getVGap(LayoutManager layout) {
if (layout instanceof BorderLayout) {
return ((BorderLayout)layout).getVgap();
}
if (layout instanceof CardLayout) {
return ((CardLayout)layout).getVgap();
}
return 0;
}
public static int getCustomCreateComponentCount(final IContainer container) {
final int[] result = new int[1];
result[0] = 0;
container.accept(new ComponentVisitor() {
public boolean visit(IComponent c) {
if (c.isCustomCreate()) {
result[0]++;
}
return true;
}
});
return result[0];
}
public static Class suggestReplacementClass(Class componentClass) {
while (true) {
componentClass = componentClass.getSuperclass();
if (componentClass.equals(JComponent.class)) {
return JPanel.class;
}
if ((componentClass.getModifiers() & (Modifier.ABSTRACT | Modifier.PRIVATE)) != 0) {
continue;
}
try {
componentClass.getConstructor(new Class[]{});
}
catch (NoSuchMethodException ex) {
continue;
}
return componentClass;
}
}
public static int alignFromConstraints(final GridConstraints gc, final boolean horizontal) {
int anchor = gc.getAnchor();
int fill = gc.getFill();
int leftMask = horizontal ? GridConstraints.ANCHOR_WEST : GridConstraints.ANCHOR_NORTH;
int rightMask = horizontal ? GridConstraints.ANCHOR_EAST : GridConstraints.ANCHOR_SOUTH;
int fillMask = horizontal ? GridConstraints.FILL_HORIZONTAL : GridConstraints.FILL_VERTICAL;
if ((fill & fillMask) != 0) return GridConstraints.ALIGN_FILL;
if ((anchor & rightMask) != 0) return GridConstraints.ALIGN_RIGHT;
if ((anchor & leftMask) != 0) return GridConstraints.ALIGN_LEFT;
return GridConstraints.ALIGN_CENTER;
}
public static boolean isBoundField(IComponent component, String fieldName) {
if (fieldName.equals(component.getBinding())) {
return true;
}
if (component instanceof IContainer) {
IContainer container = (IContainer)component;
for (int i = 0; i < container.getComponentCount(); i++) {
if (isBoundField(container.getComponent(i), fieldName)) {
return true;
}
}
}
return false;
}
}
@@ -0,0 +1,43 @@
/*
* Copyright 2000-2006 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 org.jdom.Element;
import com.intellij.uiDesigner.UIFormXmlConstants;
import java.awt.*;
/**
* @author yole
*/
public class BorderLayoutSerializer extends LayoutSerializer {
public static final BorderLayoutSerializer INSTANCE = new BorderLayoutSerializer();
private BorderLayoutSerializer() {
}
void readLayout(Element element, LwContainer container) {
final int hGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_HGAP, 0);
final int vGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_VGAP, 0);
container.setLayout(new BorderLayout(hGap, vGap));
}
void readChildConstraints(final Element constraintsElement, final LwComponent component) {
component.setCustomLayoutConstraints(LwXmlReader.getRequiredString(constraintsElement,
UIFormXmlConstants.ATTRIBUTE_BORDER_CONSTRAINT));
}
}
@@ -0,0 +1,44 @@
/*
* Copyright 2000-2006 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 org.jdom.Element;
import java.awt.CardLayout;
/**
* @author yole
*/
public class CardLayoutSerializer extends LayoutSerializer {
public static final CardLayoutSerializer INSTANCE = new CardLayoutSerializer();
private CardLayoutSerializer() {
}
void readLayout(Element element, LwContainer container) {
final int hGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_HGAP, 0);
final int vGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_VGAP, 0);
container.setLayout(new CardLayout(hGap, vGap));
}
void readChildConstraints(final Element constraintsElement, final LwComponent component) {
final Element cardChild = LwXmlReader.getRequiredChild(constraintsElement, UIFormXmlConstants.ELEMENT_CARD);
final String name = LwXmlReader.getRequiredString(cardChild, UIFormXmlConstants.ATTRIBUTE_NAME);
component.setCustomLayoutConstraints(name);
}
}
@@ -0,0 +1,140 @@
/*
* Copyright 2000-2005 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 javax.swing.*;
import java.awt.*;
import java.lang.reflect.Field;
/**
* @author yole
*/
public class ColorDescriptor {
private Color myColor;
private String mySwingColor;
private String mySystemColor;
private String myAWTColor;
public static ColorDescriptor fromSwingColor(final String swingColor) {
ColorDescriptor result = new ColorDescriptor(null);
result.myColor = null;
result.mySwingColor = swingColor;
return result;
}
public static ColorDescriptor fromSystemColor(final String systemColor) {
ColorDescriptor result = new ColorDescriptor(null);
result.myColor = null;
result.mySystemColor = systemColor;
return result;
}
public static ColorDescriptor fromAWTColor(final String awtColor) {
ColorDescriptor result = new ColorDescriptor(null);
result.myColor = null;
result.myAWTColor = awtColor;
return result;
}
private static Color getColorField(final Class aClass, final String fieldName) {
try {
final Field field = aClass.getDeclaredField(fieldName);
return (Color)field.get(null);
}
catch (NoSuchFieldException e) {
return Color.black;
}
catch (IllegalAccessException e) {
return Color.black;
}
}
public ColorDescriptor(final Color color) {
myColor = color;
}
public Color getResolvedColor() {
if (myColor != null) {
return myColor;
}
if (mySwingColor != null) {
return UIManager.getColor(mySwingColor);
}
if (mySystemColor != null) {
return getColorField(SystemColor.class, mySystemColor);
}
if (myAWTColor != null) {
return getColorField(Color.class, myAWTColor);
}
return null;
}
public Color getColor() {
return myColor;
}
public String getSwingColor() {
return mySwingColor;
}
public String getSystemColor() {
return mySystemColor;
}
public String getAWTColor() {
return myAWTColor;
}
public String toString() {
if (mySwingColor != null) {
return mySwingColor;
}
if (mySystemColor != null) {
return mySystemColor;
}
if (myAWTColor != null) {
return myAWTColor;
}
if (myColor != null) {
return "[" + myColor.getRed() + "," + myColor.getGreen() + "," + myColor.getBlue() + "]";
}
return "null";
}
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof ColorDescriptor)) {
return false;
}
ColorDescriptor rhs = (ColorDescriptor) obj;
if (myColor != null) {
return myColor.equals(rhs.myColor);
}
if (mySwingColor != null) {
return mySwingColor.equals(rhs.mySwingColor);
}
if (mySystemColor != null) {
return mySystemColor.equals(rhs.mySystemColor);
}
if (myAWTColor != null) {
return myAWTColor.equals(rhs.myAWTColor);
}
return false;
}
public boolean isColorSet() {
return myColor != null || mySwingColor != null || mySystemColor != null || myAWTColor != null;
}
}
@@ -0,0 +1,163 @@
/*
* Copyright 2000-2005 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.compiler.Utils;
import javax.swing.*;
import java.awt.*;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public final class CompiledClassPropertiesProvider implements PropertiesProvider {
private final ClassLoader myLoader;
private final HashMap myCache;
public CompiledClassPropertiesProvider(final ClassLoader loader) {
if (loader == null) {
throw new IllegalArgumentException("loader cannot be null");
}
myLoader = loader;
myCache = new HashMap();
}
public HashMap getLwProperties(final String className) {
if (myCache.containsKey(className)) {
return (HashMap)myCache.get(className);
}
if (Utils.validateJComponentClass(myLoader, className, false) != null) {
return null;
}
final Class aClass;
try {
aClass = Class.forName(className, false, myLoader);
}
catch (final ClassNotFoundException exc) {
throw new RuntimeException(exc.toString()); // should never happen
}
final BeanInfo beanInfo;
try {
beanInfo = Introspector.getBeanInfo(aClass);
}
catch (Throwable e) {
return null;
}
final HashMap result = new HashMap();
final PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
for (int i = 0; i < descriptors.length; i++) {
final PropertyDescriptor descriptor = descriptors[i];
final Method readMethod = descriptor.getReadMethod();
final Method writeMethod = descriptor.getWriteMethod();
if (writeMethod == null || readMethod == null) {
continue;
}
final String name = descriptor.getName();
final LwIntrospectedProperty property = propertyFromClass(descriptor.getPropertyType(), name);
if (property != null) {
property.setDeclaringClassName(descriptor.getReadMethod().getDeclaringClass().getName());
result.put(name, property);
}
}
myCache.put(className, result);
return result;
}
public static LwIntrospectedProperty propertyFromClass(final Class propertyType, final String name) {
LwIntrospectedProperty property = propertyFromClassName(propertyType.getName(), name);
if (property == null) {
if (Component.class.isAssignableFrom(propertyType)) {
property = new LwIntroComponentProperty(name, propertyType.getName());
}
else if (ListModel.class.isAssignableFrom(propertyType)) {
property = new LwIntroListModelProperty(name, propertyType.getName());
}
else if (propertyType.getSuperclass() != null && "java.lang.Enum".equals(propertyType.getSuperclass().getName())) {
property = new LwIntroEnumProperty(name, propertyType);
}
}
return property;
}
public static LwIntrospectedProperty propertyFromClassName(final String propertyClassName, final String name) {
final LwIntrospectedProperty property;
if (int.class.getName().equals(propertyClassName)) { // int
property = new LwIntroIntProperty(name);
}
else if (boolean.class.getName().equals(propertyClassName)) { // boolean
property = new LwIntroBooleanProperty(name);
}
else if (double.class.getName().equals(propertyClassName)) { // double
property = new LwIntroPrimitiveTypeProperty(name, Double.class);
}
else if (float.class.getName().equals(propertyClassName)) {
property = new LwIntroPrimitiveTypeProperty(name, Float.class);
}
else if (long.class.getName().equals(propertyClassName)) {
property = new LwIntroPrimitiveTypeProperty(name, Long.class);
}
else if (byte.class.getName().equals(propertyClassName)) {
property = new LwIntroPrimitiveTypeProperty(name, Byte.class);
}
else if (short.class.getName().equals(propertyClassName)) {
property = new LwIntroPrimitiveTypeProperty(name, Short.class);
}
else if (char.class.getName().equals(propertyClassName)) {
property = new LwIntroCharProperty(name);
}
else if (String.class.getName().equals(propertyClassName)) { // java.lang.String
property = new LwRbIntroStringProperty(name);
}
else if ("java.awt.Insets".equals(propertyClassName)) { // java.awt.Insets
property = new LwIntroInsetsProperty(name);
}
else if ("java.awt.Dimension".equals(propertyClassName)) { // java.awt.Dimension
property = new LwIntroDimensionProperty(name);
}
else if ("java.awt.Rectangle".equals(propertyClassName)) { // java.awt.Rectangle
property = new LwIntroRectangleProperty(name);
}
else if ("java.awt.Color".equals(propertyClassName)) {
property = new LwIntroColorProperty(name);
}
else if ("java.awt.Font".equals(propertyClassName)) {
property = new LwIntroFontProperty(name);
}
else if ("javax.swing.Icon".equals(propertyClassName)) {
property = new LwIntroIconProperty(name);
}
else {
property = null;
}
return property;
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2000-2006 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;
/**
* @author yole
*/
public interface ComponentVisitor {
/**
* @return true if iteration should continue
*/
boolean visit(IComponent c);
}
@@ -0,0 +1,42 @@
/*
* Copyright 2000-2006 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 org.jdom.Element;
import java.awt.FlowLayout;
/**
* @author yole
*/
public class FlowLayoutSerializer extends LayoutSerializer {
public static final FlowLayoutSerializer INSTANCE = new FlowLayoutSerializer();
private FlowLayoutSerializer() {
}
void readLayout(Element element, LwContainer container) {
final int hGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_HGAP, 5);
final int vGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_VGAP, 5);
final int flowAlign = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_FLOW_ALIGN, FlowLayout.CENTER);
container.setLayout(new FlowLayout(flowAlign, hGap, vGap));
}
void readChildConstraints(final Element constraintsElement, final LwComponent component) {
}
}
@@ -0,0 +1,97 @@
/*
* Copyright 2000-2005 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 javax.swing.*;
import java.awt.Font;
/**
* @author yole
*/
public class FontDescriptor {
private String myFontName;
private int myFontSize;
private int myFontStyle;
private String mySwingFont;
private FontDescriptor() {
}
public FontDescriptor(final String fontName, final int fontStyle, final int fontSize) {
myFontName = fontName;
myFontSize = fontSize;
myFontStyle = fontStyle;
}
public boolean isFixedFont() {
return mySwingFont == null;
}
public boolean isFullyDefinedFont() {
return myFontName != null && myFontSize >= 0 && myFontStyle >= 0;
}
public static FontDescriptor fromSwingFont(String swingFont) {
FontDescriptor result = new FontDescriptor();
result.mySwingFont = swingFont;
return result;
}
public String getFontName() {
return myFontName;
}
public int getFontSize() {
return myFontSize;
}
public int getFontStyle() {
return myFontStyle;
}
public Font getFont(Font defaultFont) {
return new Font(myFontName != null ? myFontName : defaultFont.getFontName(),
myFontStyle >= 0 ? myFontStyle : defaultFont.getStyle(),
myFontSize >= 0 ? myFontSize : defaultFont.getSize());
}
public String getSwingFont() {
return mySwingFont;
}
public Font getResolvedFont(Font defaultFont) {
if (mySwingFont != null) {
return UIManager.getFont(mySwingFont);
}
return getFont(defaultFont);
}
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof FontDescriptor)) {
return false;
}
FontDescriptor rhs = (FontDescriptor) obj;
if (mySwingFont != null) {
return mySwingFont.equals(rhs.mySwingFont);
}
else {
if (myFontName == null && rhs.myFontName != null) return false;
if (myFontName != null && rhs.myFontName == null) return false;
if (myFontName != null && !myFontName.equals(rhs.myFontName)) return false;
return myFontSize == rhs.myFontSize && myFontStyle == rhs.myFontStyle;
}
}
}
@@ -0,0 +1,105 @@
/*
* Copyright 2000-2006 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 org.jdom.Element;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.CellConstraints;
import com.intellij.uiDesigner.UIFormXmlConstants;
import com.intellij.uiDesigner.compiler.Utils;
import java.util.List;
import java.util.Iterator;
/**
* @author yole
*/
public class FormLayoutSerializer extends GridLayoutSerializer {
private FormLayoutSerializer() {
}
public static FormLayoutSerializer INSTANCE = new FormLayoutSerializer();
public static CellConstraints.Alignment[] ourHorizontalAlignments = new CellConstraints.Alignment[] {
CellConstraints.LEFT, CellConstraints.CENTER, CellConstraints.RIGHT, CellConstraints.FILL
};
public static CellConstraints.Alignment[] ourVerticalAlignments = new CellConstraints.Alignment[] {
CellConstraints.TOP, CellConstraints.CENTER, CellConstraints.BOTTOM, CellConstraints.FILL
};
void readLayout(Element element, LwContainer container) {
FormLayout layout = new FormLayout();
final List rowSpecs = element.getChildren(UIFormXmlConstants.ELEMENT_ROWSPEC, element.getNamespace());
for (Iterator iterator = rowSpecs.iterator(); iterator.hasNext();) {
Element rowSpecElement = (Element) iterator.next();
final String spec = LwXmlReader.getRequiredString(rowSpecElement, UIFormXmlConstants.ATTRIBUTE_VALUE);
layout.appendRow(new RowSpec(spec));
}
final List colSpecs = element.getChildren(UIFormXmlConstants.ELEMENT_COLSPEC, element.getNamespace());
for (Iterator iterator = colSpecs.iterator(); iterator.hasNext();) {
Element colSpecElement = (Element) iterator.next();
final String spec = LwXmlReader.getRequiredString(colSpecElement, UIFormXmlConstants.ATTRIBUTE_VALUE);
layout.appendColumn(new ColumnSpec(spec));
}
int[][] rowGroups = readGroups(element, UIFormXmlConstants.ELEMENT_ROWGROUP);
int[][] colGroups = readGroups(element, UIFormXmlConstants.ELEMENT_COLGROUP);
if (rowGroups != null) {
layout.setRowGroups(rowGroups);
}
if (colGroups != null) {
layout.setColumnGroups(colGroups);
}
container.setLayout(layout);
}
private static int[][] readGroups(final Element element, final String elementName) {
final List groupElements = element.getChildren(elementName, element.getNamespace());
if (groupElements.size() == 0) return null;
int[][] groups = new int[groupElements.size()][];
for(int i=0; i<groupElements.size(); i++) {
Element groupElement = (Element) groupElements.get(i);
List groupMembers = groupElement.getChildren(UIFormXmlConstants.ELEMENT_MEMBER, element.getNamespace());
groups [i] = new int[groupMembers.size()];
for(int j=0; j<groupMembers.size(); j++) {
groups [i][j] = LwXmlReader.getRequiredInt((Element) groupMembers.get(j), UIFormXmlConstants.ATTRIBUTE_INDEX);
}
}
return groups;
}
void readChildConstraints(final Element constraintsElement, final LwComponent component) {
super.readChildConstraints(constraintsElement, component);
CellConstraints cc = new CellConstraints();
final Element formsElement = LwXmlReader.getChild(constraintsElement, UIFormXmlConstants.ELEMENT_FORMS);
if (formsElement != null) {
if (formsElement.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_TOP) != null) {
cc.insets = LwXmlReader.readInsets(formsElement);
}
if (!LwXmlReader.getOptionalBoolean(formsElement, UIFormXmlConstants.ATTRIBUTE_DEFAULTALIGN_HORZ, true)) {
cc.hAlign = ourHorizontalAlignments [Utils.alignFromConstraints(component.getConstraints(), true)];
}
if (!LwXmlReader.getOptionalBoolean(formsElement, UIFormXmlConstants.ATTRIBUTE_DEFAULTALIGN_VERT, true)) {
cc.vAlign = ourVerticalAlignments [Utils.alignFromConstraints(component.getConstraints(), false)];
}
}
component.setCustomLayoutConstraints(cc);
}
}
@@ -0,0 +1,57 @@
/*
* Copyright 2000-2006 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.
*/
/*
* Created by IntelliJ IDEA.
* User: yole
* Date: 30.08.2006
* Time: 13:02:12
*/
package com.intellij.uiDesigner.lw;
import com.intellij.uiDesigner.compiler.GridBagConverter;
import com.intellij.uiDesigner.UIFormXmlConstants;
import org.jdom.Element;
import java.awt.*;
public class GridBagLayoutSerializer extends GridLayoutSerializer {
private GridBagLayoutSerializer() {
}
public static GridBagLayoutSerializer INSTANCE = new GridBagLayoutSerializer();
void readLayout(Element element, LwContainer container) {
container.setLayout(new GridBagLayout());
}
void readChildConstraints(final Element constraintsElement, final LwComponent component) {
super.readChildConstraints(constraintsElement, component);
GridBagConstraints gbc = new GridBagConstraints();
GridBagConverter.constraintsToGridBag(component.getConstraints(), gbc);
final Element gridBagElement = LwXmlReader.getChild(constraintsElement, UIFormXmlConstants.ELEMENT_GRIDBAG);
if (gridBagElement != null) {
if (gridBagElement.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_TOP) != null) {
gbc.insets = LwXmlReader.readInsets(gridBagElement);
}
gbc.weightx = LwXmlReader.getOptionalDouble(gridBagElement, UIFormXmlConstants.ATTRIBUTE_WEIGHTX, 0.0);
gbc.weighty = LwXmlReader.getOptionalDouble(gridBagElement, UIFormXmlConstants.ATTRIBUTE_WEIGHTY, 0.0);
gbc.ipadx = LwXmlReader.getOptionalInt(gridBagElement, UIFormXmlConstants.ATTRIBUTE_IPADX, 0);
gbc.ipady = LwXmlReader.getOptionalInt(gridBagElement, UIFormXmlConstants.ATTRIBUTE_IPADY, 0);
}
component.setCustomLayoutConstraints(gbc);
}
}
@@ -0,0 +1,104 @@
/*
* Copyright 2000-2006 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 org.jdom.Element;
import com.intellij.uiDesigner.UIFormXmlConstants;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.GridConstraints;
import java.awt.*;
/**
* @author yole
*/
public class GridLayoutSerializer extends LayoutSerializer {
protected GridLayoutSerializer() {
}
public static GridLayoutSerializer INSTANCE = new GridLayoutSerializer();
void readLayout(Element element, LwContainer container) {
final int rowCount = LwXmlReader.getRequiredInt(element, UIFormXmlConstants.ATTRIBUTE_ROW_COUNT);
final int columnCount = LwXmlReader.getRequiredInt(element, UIFormXmlConstants.ATTRIBUTE_COLUMN_COUNT);
final int hGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_HGAP, -1);
final int vGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_VGAP, -1);
// attribute is optional for compatibility with IDEA 4.0 forms
final boolean sameSizeHorizontally = LwXmlReader.getOptionalBoolean(element, UIFormXmlConstants.ATTRIBUTE_SAME_SIZE_HORIZONTALLY, false);
final boolean sameSizeVertically = LwXmlReader.getOptionalBoolean(element, UIFormXmlConstants.ATTRIBUTE_SAME_SIZE_VERTICALLY, false);
final Element marginElement = LwXmlReader.getRequiredChild(element, "margin");
final Insets margin = new Insets(
LwXmlReader.getRequiredInt(marginElement,"top"),
LwXmlReader.getRequiredInt(marginElement,"left"),
LwXmlReader.getRequiredInt(marginElement,"bottom"),
LwXmlReader.getRequiredInt(marginElement,"right")
);
final GridLayoutManager layout = new GridLayoutManager(rowCount, columnCount);
layout.setMargin(margin);
layout.setVGap(vGap);
layout.setHGap(hGap);
layout.setSameSizeHorizontally(sameSizeHorizontally);
layout.setSameSizeVertically(sameSizeVertically);
container.setLayout(layout);
}
void readChildConstraints(final Element constraintsElement, final LwComponent component) {
// Read Grid constraints
final Element gridElement = LwXmlReader.getChild(constraintsElement, "grid");
if(gridElement != null){
final GridConstraints constraints=new GridConstraints();
constraints.setRow(LwXmlReader.getRequiredInt(gridElement, "row"));
constraints.setColumn(LwXmlReader.getRequiredInt(gridElement, "column"));
constraints.setRowSpan(LwXmlReader.getRequiredInt(gridElement, "row-span"));
constraints.setColSpan(LwXmlReader.getRequiredInt(gridElement, "col-span"));
constraints.setVSizePolicy(LwXmlReader.getRequiredInt(gridElement, "vsize-policy"));
constraints.setHSizePolicy(LwXmlReader.getRequiredInt(gridElement, "hsize-policy"));
constraints.setAnchor(LwXmlReader.getRequiredInt(gridElement, "anchor"));
constraints.setFill(LwXmlReader.getRequiredInt(gridElement, "fill"));
constraints.setIndent(LwXmlReader.getOptionalInt(gridElement, UIFormXmlConstants.ATTRIBUTE_INDENT, 0));
constraints.setUseParentLayout(LwXmlReader.getOptionalBoolean(gridElement, UIFormXmlConstants.ATTRIBUTE_USE_PARENT_LAYOUT, false));
// minimum size
final Element minSizeElement = LwXmlReader.getChild(gridElement, "minimum-size");
if (minSizeElement != null) {
constraints.myMinimumSize.width = LwXmlReader.getRequiredInt(minSizeElement, "width");
constraints.myMinimumSize.height = LwXmlReader.getRequiredInt(minSizeElement, "height");
}
// preferred size
final Element prefSizeElement = LwXmlReader.getChild(gridElement, "preferred-size");
if (prefSizeElement != null) {
constraints.myPreferredSize.width = LwXmlReader.getRequiredInt(prefSizeElement, "width");
constraints.myPreferredSize.height = LwXmlReader.getRequiredInt(prefSizeElement, "height");
}
// maximum size
final Element maxSizeElement = LwXmlReader.getChild(gridElement, "maximum-size");
if (maxSizeElement != null) {
constraints.myMaximumSize.width = LwXmlReader.getRequiredInt(maxSizeElement, "width");
constraints.myMaximumSize.height = LwXmlReader.getRequiredInt(maxSizeElement, "height");
}
component.getConstraints().restore(constraints);
}
}
}
@@ -0,0 +1,26 @@
/*
* Copyright 2000-2006 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;
/**
* @author yole
*/
public interface IButtonGroup {
String getName();
boolean isBound();
String[] getComponentIds();
}
@@ -0,0 +1,58 @@
/*
* Copyright 2000-2005 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.core.GridConstraints;
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public interface IComponent {
Object getClientProperty(Object key);
void putClientProperty(Object key, Object value);
/**
* @return name of the field (in bound class). Returns <code>null</code>
* if the component is not bound to any field.
*/
String getBinding();
String getComponentClassName();
String getId();
boolean isCustomCreate();
IProperty[] getModifiedProperties();
IContainer getParentContainer();
GridConstraints getConstraints();
Object getCustomLayoutConstraints();
boolean accept(ComponentVisitor visitor);
/**
* Returns true if only one of the children of the component can be visible at a time
* (for example, the component is a tabbed pane or a container with CardLayout).
*
* @return true if children are exclusive, false otherwise.
*/
boolean areChildrenExclusive();
}
@@ -0,0 +1,27 @@
/*
* Copyright 2000-2005 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.shared.BorderType;
public interface IContainer extends IComponent {
int getComponentCount();
IComponent getComponent(int index);
int indexOfComponent(final IComponent lwComponent);
boolean isXY();
StringDescriptor getBorderTitle();
BorderType getBorderType();
}
@@ -0,0 +1,25 @@
/*
* Copyright 2000-2005 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;
/**
* @author yole
*/
public interface IProperty {
String getName();
Object getPropertyValue(final IComponent component);
}
@@ -0,0 +1,24 @@
/*
* Copyright 2000-2005 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;
public interface IRootContainer extends IContainer {
String getClassToBind();
String getButtonGroupName(IComponent component);
String[] getButtonGroupComponentIds(String groupName);
boolean isInspectionSuppressed(final String inspectionId, final String componentId);
IButtonGroup[] getButtonGroups();
}
@@ -0,0 +1,26 @@
/*
* Copyright 2000-2005 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;
/**
* @author yole
*/
public interface ITabbedPane extends IContainer {
String TAB_TITLE_PROPERTY = "Tab Title";
String TAB_TOOLTIP_PROPERTY = "Tab Tooltip";
StringDescriptor getTabProperty(IComponent component, final String propName);
}
@@ -0,0 +1,42 @@
/*
* Copyright 2000-2005 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 javax.swing.*;
/**
* @author yole
*/
public class IconDescriptor {
private final String myIconPath;
private Icon myIcon;
public IconDescriptor(final String iconPath) {
myIconPath = iconPath;
}
public String getIconPath() {
return myIconPath;
}
public Icon getIcon() {
return myIcon;
}
public void setIcon(final Icon icon) {
myIcon = icon;
}
}
@@ -0,0 +1,28 @@
/*
* Copyright 2000-2006 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 org.jdom.Element;
/**
* @author yole
*/
public abstract class LayoutSerializer {
abstract void readLayout(Element element, LwContainer container);
abstract void readChildConstraints(final Element constraintsElement, final LwComponent component);
}
@@ -0,0 +1,34 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public class LwAtomicComponent extends LwComponent {
public LwAtomicComponent(final String className){
super(className);
}
public void read(final Element element, final PropertiesProvider provider) throws Exception{
readBase(element);
readConstraints(element);
readProperties(element, provider);
}
}
@@ -0,0 +1,52 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
import com.intellij.uiDesigner.UIFormXmlConstants;
import java.util.Iterator;
import java.util.ArrayList;
/**
* @author yole
*/
public class LwButtonGroup implements IButtonGroup {
private String myName;
private final ArrayList myComponentIds = new ArrayList();
private boolean myBound;
public void read(final Element element) {
myName = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_NAME);
myBound = LwXmlReader.getOptionalBoolean(element, UIFormXmlConstants.ATTRIBUTE_BOUND, false);
for(Iterator i=element.getChildren().iterator(); i.hasNext();){
final Element child = (Element)i.next();
myComponentIds.add(child.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_ID));
}
}
public String getName() {
return myName;
}
public String[] getComponentIds() {
return (String[])myComponentIds.toArray(new String[myComponentIds.size()]);
}
public boolean isBound() {
return myBound;
}
}
@@ -0,0 +1,327 @@
/*
* Copyright 2000-2005 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.core.GridConstraints;
import com.intellij.uiDesigner.UIFormXmlConstants;
import org.jdom.Element;
import java.awt.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public abstract class LwComponent implements IComponent{
/**
* Component's ID. Cannot be null.
*/
private String myId;
/**
* may be null
*/
private String myBinding;
/**
* Component class
*/
private final String myClassName;
/**
* Parent LwContainer. This field is always not <code>null</code>
* is the component is in hierarchy. But the root of hierarchy
* has <code>null</code> parent indeed.
*/
private LwContainer myParent;
/**
* never <code>null</code>
*/
private final GridConstraints myConstraints;
private Object myCustomLayoutConstraints;
/**
* Bounds in XY layout
*/
private final Rectangle myBounds;
private final HashMap myIntrospectedProperty2Value;
/**
* if class is unknown (cannot be loaded), properties tag is stored as is
*/
private Element myErrorComponentProperties;
protected final HashMap myClientProperties;
protected final HashMap myDelegeeClientProperties;
private boolean myCustomCreate = false;
private boolean myDefaultBinding = false;
public LwComponent(final String className){
if (className == null){
throw new IllegalArgumentException("className cannot be null");
}
myBounds = new Rectangle();
myConstraints = new GridConstraints();
myIntrospectedProperty2Value = new HashMap();
myClassName = className;
myClientProperties = new HashMap();
myDelegeeClientProperties = new HashMap();
}
public final String getId() {
return myId;
}
public final void setId(final String id){
if (id == null) {
throw new IllegalArgumentException("id cannot be null");
}
myId = id;
}
public final String getBinding(){
return myBinding;
}
public final void setBinding(final String binding){
myBinding = binding;
}
public final Object getCustomLayoutConstraints(){
return myCustomLayoutConstraints;
}
public final void setCustomLayoutConstraints(final Object customLayoutConstraints){
myCustomLayoutConstraints = customLayoutConstraints;
}
/**
* @return never null
*/
public final String getComponentClassName(){
return myClassName;
}
public IProperty[] getModifiedProperties() {
return getAssignedIntrospectedProperties();
}
/**
* @return component's constraints in XY layout. This method rever
* returns <code>null</code>.
*/
public final Rectangle getBounds(){
return (Rectangle)myBounds.clone();
}
/**
* @return component's constraints in GridLayoutManager. This method never
* returns <code>null</code>.
*/
public final GridConstraints getConstraints(){
return myConstraints;
}
public boolean isCustomCreate() {
return myCustomCreate;
}
public boolean isDefaultBinding() {
return myDefaultBinding;
}
public boolean accept(ComponentVisitor visitor) {
return visitor.visit(this);
}
public boolean areChildrenExclusive() {
return false;
}
public final LwContainer getParent(){
return myParent;
}
public IContainer getParentContainer() {
return myParent;
}
protected final void setParent(final LwContainer parent){
myParent = parent;
}
public final void setBounds(final Rectangle bounds) {
myBounds.setBounds(bounds);
}
public final Object getPropertyValue(final LwIntrospectedProperty property){
return myIntrospectedProperty2Value.get(property);
}
public final void setPropertyValue(final LwIntrospectedProperty property, final Object value){
myIntrospectedProperty2Value.put(property, value);
}
/**
* @return <code>null</code> only if component class is not valid.
* Class validation is performed with {@link com.intellij.uiDesigner.compiler.Utils#validateJComponentClass(ClassLoader,String,boolean)}
*/
public final Element getErrorComponentProperties(){
return myErrorComponentProperties;
}
public final LwIntrospectedProperty[] getAssignedIntrospectedProperties() {
final LwIntrospectedProperty[] properties = new LwIntrospectedProperty[myIntrospectedProperty2Value.size()];
final Iterator iterator = myIntrospectedProperty2Value.keySet().iterator();
//noinspection ForLoopThatDoesntUseLoopVariable
for (int i=0; iterator.hasNext(); i++) {
properties[i] = (LwIntrospectedProperty)iterator.next();
}
return properties;
}
/**
* 'id' is required attribute
* 'binding' is optional attribute
*/
protected final void readBase(final Element element) {
setId(LwXmlReader.getRequiredString(element, UIFormXmlConstants.ATTRIBUTE_ID));
setBinding(element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_BINDING));
myCustomCreate = LwXmlReader.getOptionalBoolean(element, UIFormXmlConstants.ATTRIBUTE_CUSTOM_CREATE, false);
myDefaultBinding = LwXmlReader.getOptionalBoolean(element, UIFormXmlConstants.ATTRIBUTE_DEFAULT_BINDING, false);
}
/**
* 'properties' is not required subtag
* @param provider can be null if no properties should be read
*/
protected final void readProperties(final Element element, final PropertiesProvider provider) {
if (provider == null) {
// do not read properties
return;
}
Element propertiesElement = LwXmlReader.getChild(element, UIFormXmlConstants.ELEMENT_PROPERTIES);
if(propertiesElement == null){
propertiesElement = new Element(UIFormXmlConstants.ELEMENT_PROPERTIES, element.getNamespace());
}
final HashMap name2property = provider.getLwProperties(getComponentClassName());
if (name2property == null) {
myErrorComponentProperties = (Element)propertiesElement.clone();
return;
}
final List propertyElements = propertiesElement.getChildren();
for (int i = 0; i < propertyElements.size(); i++) {
final Element t = (Element)propertyElements.get(i);
final String name = t.getName();
final LwIntrospectedProperty property = (LwIntrospectedProperty)name2property.get(name);
if (property == null){
continue;
}
try {
final Object value = property.read(t);
setPropertyValue(property, value);
}
catch (final Exception exc) {
// Skip non readable properties
}
}
readClientProperties(element);
}
private void readClientProperties(final Element element) {
Element propertiesElement = LwXmlReader.getChild(element, UIFormXmlConstants.ELEMENT_CLIENT_PROPERTIES);
if (propertiesElement == null) return;
final List clientPropertyList = propertiesElement.getChildren();
for(int i=0; i<clientPropertyList.size(); i++) {
final Element prop = (Element) clientPropertyList.get(i);
final String propName = prop.getName();
final String className = LwXmlReader.getRequiredString(prop, UIFormXmlConstants.ATTRIBUTE_CLASS);
LwIntrospectedProperty lwProp;
if (className.equals(Integer.class.getName())) {
lwProp = new LwIntroIntProperty(propName);
}
else if (className.equals(Boolean.class.getName())) {
lwProp = new LwIntroBooleanProperty(propName);
}
else if (className.equals(Double.class.getName())) {
lwProp = new LwIntroPrimitiveTypeProperty(propName, Double.class);
}
else {
Class propClass;
try {
propClass = Class.forName(className);
}
catch (ClassNotFoundException e) {
continue;
}
lwProp = CompiledClassPropertiesProvider.propertyFromClass(propClass, propName);
}
if (lwProp != null) {
final Object value;
try {
value = lwProp.read(prop);
}
catch (Exception e) {
continue;
}
myDelegeeClientProperties.put(propName, value);
}
}
}
/**
* Delegates reading of constraints to the parent container
*/
protected final void readConstraints(final Element element){
final LwContainer parent = getParent();
if(parent == null){
throw new IllegalStateException("component must be in LW tree: "+this);
}
parent.readConstraintsForChild(element, this);
}
/**
* @param provider can be null if no component classes should not be created
*/
public abstract void read(Element element, PropertiesProvider provider) throws Exception;
/**
* @see javax.swing.JComponent#getClientProperty(Object)
*/
public final Object getClientProperty(final Object key){
if (key == null) {
throw new IllegalArgumentException("key cannot be null");
}
return myClientProperties.get(key);
}
/**
* @see javax.swing.JComponent#putClientProperty(Object, Object)
*/
public final void putClientProperty(final Object key, final Object value){
if (key == null) {
throw new IllegalArgumentException("key cannot be null");
}
myClientProperties.put(key, value);
}
public HashMap getDelegeeClientProperties() {
return myDelegeeClientProperties;
}
}
@@ -0,0 +1,385 @@
/*
* Copyright 2000-2005 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);
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public final class LwHSpacer extends LwAtomicComponent {
public LwHSpacer() throws Exception{
super("com.intellij.uiDesigner.core.Spacer");
}
public void read(final Element element, final PropertiesProvider provider) throws Exception{
readBase(element);
readConstraints(element);
}
}
@@ -0,0 +1,40 @@
/*
* Copyright 2000-2006 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;
/**
* @author yole
*/
public class LwInspectionSuppression {
public static final LwInspectionSuppression[] EMPTY_ARRAY = new LwInspectionSuppression[0];
private final String myInspectionId;
private final String myComponentId;
public LwInspectionSuppression(final String inspectionId, final String componentId) {
myInspectionId = inspectionId;
myComponentId = componentId;
}
public String getInspectionId() {
return myInspectionId;
}
public String getComponentId() {
return myComponentId;
}
}
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
import com.intellij.uiDesigner.UIFormXmlConstants;
public final class LwIntroBooleanProperty extends LwIntrospectedProperty {
public LwIntroBooleanProperty(final String name){
super(name, Boolean.class.getName());
}
public Object read(final Element element) throws Exception{
return Boolean.valueOf(LwXmlReader.getRequiredString(element, UIFormXmlConstants.ATTRIBUTE_VALUE));
}
}
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2007, Your Corporation. All Rights Reserved.
*/
package com.intellij.uiDesigner.lw;
import org.jdom.Element;
import com.intellij.uiDesigner.UIFormXmlConstants;
public final class LwIntroCharProperty extends LwIntrospectedProperty {
public LwIntroCharProperty(final String name){
super(name, Character.class.getName());
}
public Object read(final Element element) throws Exception{
return Character.valueOf(LwXmlReader.getRequiredString(element, UIFormXmlConstants.ATTRIBUTE_VALUE).charAt(0));
}
}
@@ -0,0 +1,31 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
/**
* @author yole
*/
public class LwIntroColorProperty extends LwIntrospectedProperty {
public LwIntroColorProperty(final String name) {
super(name, "java.awt.Color");
}
public Object read(Element element) throws Exception {
return LwXmlReader.getColorDescriptor(element);
}
}
@@ -0,0 +1,32 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
/**
* @author yole
*/
public class LwIntroComponentProperty extends LwIntrospectedProperty {
public LwIntroComponentProperty(final String name, final String propertyClassName) {
super(name, propertyClassName);
}
public Object read(Element element) throws Exception {
return LwXmlReader.getRequiredString(element, UIFormXmlConstants.ATTRIBUTE_VALUE);
}
}
@@ -0,0 +1,35 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
import java.awt.*;
/**
* @author Anton Katilin
*/
public final class LwIntroDimensionProperty extends LwIntrospectedProperty {
public LwIntroDimensionProperty(final String name){
super(name, "java.awt.Dimension");
}
public Object read(final Element element) throws Exception{
final int width = LwXmlReader.getRequiredInt(element, "width");
final int height = LwXmlReader.getRequiredInt(element, "height");
return new Dimension(width, height);
}
}
@@ -0,0 +1,44 @@
/*
* Copyright 2000-2006 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 org.jdom.Element;
import java.lang.reflect.Method;
/**
* @author yole
*/
public class LwIntroEnumProperty extends LwIntrospectedProperty {
private final Class myEnumClass;
public LwIntroEnumProperty(final String name, final Class enumClass) {
super(name, enumClass.getName());
myEnumClass = enumClass;
}
public Object read(Element element) throws Exception {
String value = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_VALUE);
final Method method = myEnumClass.getMethod("valueOf", new Class[] { String.class} );
return method.invoke(null, new Object[] { value } );
}
public String getCodeGenPropertyClassName() {
return "java.lang.Enum";
}
}
@@ -0,0 +1,31 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
/**
* @author yole
*/
public class LwIntroFontProperty extends LwIntrospectedProperty {
public LwIntroFontProperty(final String name) {
super(name, "java.awt.Font");
}
public Object read(Element element) throws Exception {
return LwXmlReader.getFontDescriptor(element);
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
/**
* @author yole
*/
public class LwIntroIconProperty extends LwIntrospectedProperty {
public LwIntroIconProperty(final String name) {
super(name, "javax.swing.Icon");
}
public Object read(Element element) throws Exception {
String value = LwXmlReader.getRequiredString(element, UIFormXmlConstants.ATTRIBUTE_VALUE);
return new IconDescriptor(value);
}
}
@@ -0,0 +1,31 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
/**
* @author Vladimir Kondratyev
*/
public final class LwIntroInsetsProperty extends LwIntrospectedProperty{
public LwIntroInsetsProperty(final String name){
super(name, "java.awt.Insets");
}
public Object read(final Element element) throws Exception{
return LwXmlReader.readInsets(element);
}
}
@@ -0,0 +1,28 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
public final class LwIntroIntProperty extends LwIntrospectedProperty {
public LwIntroIntProperty(final String name){
super(name, Integer.class.getName());
}
public Object read(final Element element) throws Exception{
return new Integer(LwXmlReader.getRequiredInt(element, "value"));
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2006 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 org.jdom.Element;
import java.util.List;
/**
* @author yole
*/
public class LwIntroListModelProperty extends LwIntrospectedProperty {
public LwIntroListModelProperty(final String name, final String propertyClassName) {
super(name, propertyClassName);
}
public Object read(Element element) throws Exception {
final List list = element.getChildren(UIFormXmlConstants.ELEMENT_ITEM, element.getNamespace());
String[] result = new String[list.size()];
for(int i=0; i<list.size(); i++) {
Element itemElement = (Element) list.get(i);
result [i] = LwXmlReader.getRequiredString(itemElement, UIFormXmlConstants.ATTRIBUTE_VALUE);
}
return result;
}
}
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2007, Your Corporation. All Rights Reserved.
*/
package com.intellij.uiDesigner.lw;
import org.jdom.Element;
import com.intellij.uiDesigner.UIFormXmlConstants;
public final class LwIntroPrimitiveTypeProperty extends LwIntrospectedProperty {
private final Class myValueClass;
public LwIntroPrimitiveTypeProperty(final String name, final Class valueClass){
super(name, valueClass.getName());
myValueClass = valueClass;
}
public Object read(final Element element) throws Exception{
return LwXmlReader.getRequiredPrimitiveTypeValue(element, UIFormXmlConstants.ATTRIBUTE_VALUE, myValueClass);
}
}
@@ -0,0 +1,37 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
import java.awt.*;
/**
* @author Vladimir Kondratyev
*/
public final class LwIntroRectangleProperty extends LwIntrospectedProperty{
public LwIntroRectangleProperty(final String name){
super(name, "java.awt.Rectangle");
}
public Object read(final Element element) throws Exception{
final int x = LwXmlReader.getRequiredInt(element, "x");
final int y = LwXmlReader.getRequiredInt(element, "y");
final int width = LwXmlReader.getRequiredInt(element, "width");
final int height = LwXmlReader.getRequiredInt(element, "height");
return new Rectangle(x, y, width, height);
}
}
@@ -0,0 +1,89 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
public abstract class LwIntrospectedProperty implements IProperty {
private final String myName;
private final String myPropertyClassName;
private String myDeclaringClassName;
public LwIntrospectedProperty(
final String name,
final String propertyClassName
){
if (name == null){
throw new IllegalArgumentException("name cannot be null");
}
if (propertyClassName == null){
throw new IllegalArgumentException("propertyClassName cannot be null");
}
myName = name;
myPropertyClassName = propertyClassName;
}
/**
* @return never null
*/
public final String getName(){
return myName;
}
/**
* @return never null
*/
public final String getPropertyClassName(){
return myPropertyClassName;
}
public final String getReadMethodName() {
return "get" + Character.toUpperCase(myName.charAt(0)) + myName.substring(1);
}
public final String getWriteMethodName() {
return "set" + Character.toUpperCase(myName.charAt(0)) + myName.substring(1);
}
public String getDeclaringClassName() {
return myDeclaringClassName;
}
public void setDeclaringClassName(final String definingClassName) {
myDeclaringClassName = definingClassName;
}
/**
* @param element element that contains serialized property data. This element was
* written by {@link com.intellij.uiDesigner.propertyInspector.IntrospectedProperty#write(Object, com.intellij.uiDesigner.XmlWriter)}
* method. So <code>read</code> and <code>write</code> methods should be consistent.
*
* @return property value. Should never return <code>null</code>. For example,
* value can be <code>java.lang.Integer</code> for <code>IntroIntProperty</code>.
*
*/
public abstract Object read(Element element) throws Exception;
public Object getPropertyValue(final IComponent component) {
return ((LwComponent) component).getPropertyValue(this);
}
public String getCodeGenPropertyClassName() {
return getPropertyClassName();
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2006 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 org.jdom.Element;
import com.intellij.uiDesigner.UIFormXmlConstants;
/**
* @author yole
*/
public class LwNestedForm extends LwComponent {
private String myFormFileName;
public LwNestedForm() {
super("");
}
public void read(Element element, PropertiesProvider provider) throws Exception {
myFormFileName = LwXmlReader.getRequiredString(element, UIFormXmlConstants.ATTRIBUTE_FORM_FILE);
readBase(element);
readConstraints(element);
}
public String getFormFileName() {
return myFormFileName;
}
}
@@ -0,0 +1,43 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
import com.intellij.uiDesigner.UIFormXmlConstants;
/**
* @author Vladimir Kondratyev
*/
public final class LwRbIntroStringProperty extends LwIntrospectedProperty {
public LwRbIntroStringProperty(final String name){
super(name, String.class.getName());
}
/**
* @return instance of {@link com.intellij.uiDesigner.lw.StringDescriptor}
*/
public Object read(final Element element) throws Exception{
final StringDescriptor descriptor = LwXmlReader.getStringDescriptor(element,
UIFormXmlConstants.ATTRIBUTE_VALUE,
UIFormXmlConstants.ATTRIBUTE_RESOURCE_BUNDLE,
UIFormXmlConstants.ATTRIBUTE_KEY);
if (descriptor == null) {
throw new IllegalArgumentException("String descriptor value required");
}
return descriptor;
}
}
@@ -0,0 +1,149 @@
/*
* Copyright 2000-2005 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.AlienFormFileException;
import com.intellij.uiDesigner.compiler.UnexpectedFormElementException;
import com.intellij.uiDesigner.compiler.Utils;
import org.jdom.Element;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public final class LwRootContainer extends LwContainer implements IRootContainer{
private String myClassToBind;
private String myMainComponentBinding;
private final ArrayList myButtonGroups = new ArrayList();
private final ArrayList myInspectionSuppressions = new ArrayList();
public LwRootContainer() throws Exception{
super("javax.swing.JPanel");
myLayoutSerializer = XYLayoutSerializer.INSTANCE;
}
public String getMainComponentBinding(){
return myMainComponentBinding;
}
public String getClassToBind(){
return myClassToBind;
}
public void setClassToBind(final String classToBind) {
myClassToBind = classToBind;
}
public void read(final Element element, final PropertiesProvider provider) throws Exception {
if (element == null) {
throw new IllegalArgumentException("element cannot be null");
}
if(!"form".equals(element.getName())){
throw new UnexpectedFormElementException("unexpected element: "+element);
}
if (!Utils.FORM_NAMESPACE.equals(element.getNamespace().getURI())) {
throw new AlienFormFileException();
}
setId("root");
myClassToBind = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_BIND_TO_CLASS);
// Constraints and properties
for(Iterator i=element.getChildren().iterator(); i.hasNext();){
final Element child = (Element)i.next();
if (child.getName().equals(UIFormXmlConstants.ELEMENT_BUTTON_GROUPS)) {
readButtonGroups(child);
}
else if (child.getName().equals(UIFormXmlConstants.ELEMENT_INSPECTION_SUPPRESSIONS)) {
readInspectionSuppressions(child);
}
else {
final LwComponent component = createComponentFromTag(child);
addComponent(component);
component.read(child, provider);
}
}
myMainComponentBinding = element.getAttributeValue("stored-main-component-binding");
}
private void readButtonGroups(final Element element) {
for(Iterator i=element.getChildren().iterator(); i.hasNext();){
final Element child = (Element)i.next();
LwButtonGroup group = new LwButtonGroup();
group.read(child);
myButtonGroups.add(group);
}
}
private void readInspectionSuppressions(final Element element) {
for(Iterator i=element.getChildren().iterator(); i.hasNext();){
final Element child = (Element)i.next();
String inspectionId = LwXmlReader.getRequiredString(child, UIFormXmlConstants.ATTRIBUTE_INSPECTION);
String componentId = LwXmlReader.getString(child, UIFormXmlConstants.ATTRIBUTE_ID);
myInspectionSuppressions.add(new LwInspectionSuppression(inspectionId, componentId));
}
}
public IButtonGroup[] getButtonGroups() {
return (LwButtonGroup[])myButtonGroups.toArray(new LwButtonGroup[myButtonGroups.size()]);
}
public String getButtonGroupName(IComponent component) {
for(int i=0; i<myButtonGroups.size(); i++) {
LwButtonGroup group = (LwButtonGroup) myButtonGroups.get(i);
final String[] ids = group.getComponentIds();
for(int j=0; j<ids.length; j++) {
if (ids [j].equals(component.getId())) {
return group.getName();
}
}
}
return null;
}
public String[] getButtonGroupComponentIds(String groupName) {
for(int i=0; i<myButtonGroups.size(); i++) {
LwButtonGroup group = (LwButtonGroup) myButtonGroups.get(i);
if (group.getName().equals(groupName)) {
return group.getComponentIds();
}
}
throw new IllegalArgumentException("Cannot find group " + groupName);
}
public boolean isInspectionSuppressed(final String inspectionId, final String componentId) {
for (Iterator iterator = myInspectionSuppressions.iterator(); iterator.hasNext();) {
LwInspectionSuppression suppression = (LwInspectionSuppression)iterator.next();
if ((suppression.getComponentId() == null || suppression.getComponentId().equals(componentId)) &&
suppression.getInspectionId().equals(inspectionId)) {
return true;
}
}
return false;
}
public LwInspectionSuppression[] getInspectionSuppressions() {
return (LwInspectionSuppression[]) myInspectionSuppressions.toArray(new LwInspectionSuppression[myInspectionSuppressions.size()]);
}
}
@@ -0,0 +1,40 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
import java.awt.*;
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public final class LwScrollPane extends LwContainer {
public LwScrollPane(String className) {
super(className);
}
protected LayoutManager createInitialLayout(){
return null;
}
public void read(final Element element, final PropertiesProvider provider) throws Exception {
readNoLayout(element, provider);
}
protected void readConstraintsForChild(final Element element, final LwComponent component) {}
}
@@ -0,0 +1,57 @@
/*
* Copyright 2000-2005 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.compiler.UnexpectedFormElementException;
import org.jdom.Element;
import java.awt.*;
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public final class LwSplitPane extends LwContainer{
public static final String POSITION_LEFT = "left";
public static final String POSITION_RIGHT = "right";
public LwSplitPane(String className) {
super(className);
}
protected LayoutManager createInitialLayout(){
return null;
}
public void read(final Element element, final PropertiesProvider provider) throws Exception {
readNoLayout(element, provider);
}
protected void readConstraintsForChild(final Element element, final LwComponent component) {
final Element constraintsElement = LwXmlReader.getRequiredChild(element, "constraints");
final Element splitterChild = LwXmlReader.getRequiredChild(constraintsElement, "splitpane");
final String position = LwXmlReader.getRequiredString(splitterChild, "position");
if ("left".equals(position)) {
component.setCustomLayoutConstraints(POSITION_LEFT);
}
else if ("right".equals(position)) {
component.setCustomLayoutConstraints(POSITION_RIGHT);
}
else {
throw new UnexpectedFormElementException("unexpected position: " + position);
}
}
}
@@ -0,0 +1,114 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
import java.awt.*;
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public final class LwTabbedPane extends LwContainer implements ITabbedPane {
public LwTabbedPane(String className) {
super(className);
}
protected LayoutManager createInitialLayout() {
return null;
}
public void read(final Element element, final PropertiesProvider provider) throws Exception {
readNoLayout(element, provider);
}
protected void readConstraintsForChild(final Element element, final LwComponent component) {
final Element constraintsElement = LwXmlReader.getRequiredChild(element, UIFormXmlConstants.ELEMENT_CONSTRAINTS);
final Element tabbedPaneChild = LwXmlReader.getRequiredChild(constraintsElement, UIFormXmlConstants.ELEMENT_TABBEDPANE);
final StringDescriptor descriptor = LwXmlReader.getStringDescriptor(tabbedPaneChild,
UIFormXmlConstants.ATTRIBUTE_TITLE,
UIFormXmlConstants.ATTRIBUTE_TITLE_RESOURCE_BUNDLE,
UIFormXmlConstants.ATTRIBUTE_TITLE_KEY);
if (descriptor == null) {
throw new IllegalArgumentException("String descriptor value required");
}
final Constraints constraints = new Constraints(descriptor);
final Element tooltipElement = LwXmlReader.getChild(tabbedPaneChild, UIFormXmlConstants.ELEMENT_TOOLTIP);
if (tooltipElement != null) {
constraints.myToolTip = LwXmlReader.getStringDescriptor(tooltipElement,
UIFormXmlConstants.ATTRIBUTE_VALUE,
UIFormXmlConstants.ATTRIBUTE_RESOURCE_BUNDLE,
UIFormXmlConstants.ATTRIBUTE_KEY);
}
String icon = tabbedPaneChild.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_ICON);
if (icon != null) {
constraints.myIcon = new IconDescriptor(icon);
}
icon = tabbedPaneChild.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_DISABLED_ICON);
if (icon != null) {
constraints.myDisabledIcon = new IconDescriptor(icon);
}
constraints.myEnabled = LwXmlReader.getOptionalBoolean(tabbedPaneChild, UIFormXmlConstants.ATTRIBUTE_ENABLED, true);
component.setCustomLayoutConstraints(constraints);
}
public static final class Constraints {
/**
* never null
*/
public StringDescriptor myTitle;
public StringDescriptor myToolTip;
public IconDescriptor myIcon;
public IconDescriptor myDisabledIcon;
public boolean myEnabled = true;
public Constraints(final StringDescriptor title){
if (title == null){
throw new IllegalArgumentException("title cannot be null");
}
myTitle = title;
}
public StringDescriptor getProperty(final String propName) {
if (propName.equals(TAB_TITLE_PROPERTY)) {
return myTitle;
}
if (propName.equals(TAB_TOOLTIP_PROPERTY)) {
return myToolTip;
}
throw new IllegalArgumentException("Unknown property name " + propName);
}
}
public StringDescriptor getTabProperty(IComponent component, final String propName) {
LwComponent lwComponent = (LwComponent) component;
LwTabbedPane.Constraints constraints = (LwTabbedPane.Constraints) lwComponent.getCustomLayoutConstraints();
if (constraints == null) {
return null;
}
return constraints.getProperty(propName);
}
public boolean areChildrenExclusive() {
return true;
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2006 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 org.jdom.Element;
import java.awt.*;
/**
* @author yole
*/
public class LwToolBar extends LwContainer {
public LwToolBar(String className) {
super(className);
}
protected LayoutManager createInitialLayout() {
return null;
}
public void read(final Element element, final PropertiesProvider provider) throws Exception {
readNoLayout(element, provider);
}
protected void readConstraintsForChild(final Element element, final LwComponent component) {
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2005 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 org.jdom.Element;
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public final class LwVSpacer extends LwAtomicComponent {
public LwVSpacer() throws Exception{
super("com.intellij.uiDesigner.core.Spacer");
}
public void read(final Element element, final PropertiesProvider provider) throws Exception{
readBase(element);
readConstraints(element);
}
}
@@ -0,0 +1,220 @@
/*
* Copyright 2000-2005 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 org.jdom.Attribute;
import org.jdom.Element;
import java.awt.*;
import java.lang.reflect.Method;
public final class LwXmlReader {
private LwXmlReader() {
}
/**
* @return can be <code>null</code>.
*/
public static Element getChild(final Element element, final String childName) {
return element.getChild(childName, element.getNamespace());
}
/**
* @return never <code>null</code>.
*/
public static Element getRequiredChild(final Element element, final String childName) {
final Element child = getChild(element, childName);
if(child == null){
throw new IllegalArgumentException("subtag '" + childName + "' is required: "+element);
}
return child;
}
/**
* @return <code>null</code> or trimmed attribute value.
*/
public static String getString(final Element element, final String attributeName){
final String value = element.getAttributeValue(attributeName);
return value != null ? value.trim() : null;
}
/**
* @return never <code>null</code> trimmed attribute value.
*/
public static String getRequiredString(final Element element, final String attributeName) {
final String value = getString(element, attributeName);
if(value != null){
return value;
}
else{
throw new IllegalArgumentException("attribute '" + attributeName + "' is required: "+element);
}
}
public static String getOptionalString(final Element element, final String attributeName, final String defaultValue) {
final String value = element.getAttributeValue(attributeName);
return value != null ? value.trim() : defaultValue;
}
public static int getRequiredInt(final Element element, final String attributeName) {
final String str = getRequiredString(element, attributeName);
try {
return Integer.parseInt(str);
}
catch (NumberFormatException e) {
throw new IllegalArgumentException("attribute '" + attributeName + "' is not a proper integer: " + str);
}
}
public static int getOptionalInt(final Element element, final String attributeName, final int defaultValue) {
final String str = element.getAttributeValue(attributeName);
if (str == null) {
return defaultValue;
}
try {
return Integer.parseInt(str);
}
catch (NumberFormatException e) {
throw new IllegalArgumentException("attribute '" + attributeName + "' is not a proper integer: " + str);
}
}
public static boolean getOptionalBoolean(final Element element, final String attributeName, final boolean defaultValue) {
final String str = element.getAttributeValue(attributeName);
if (str == null) {
return defaultValue;
}
return Boolean.valueOf(str).booleanValue();
}
public static double getRequiredDouble(final Element element, final String attributeName) {
final String str = getRequiredString(element, attributeName);
try {
return Double.parseDouble(str);
}
catch (NumberFormatException e) {
throw new IllegalArgumentException("attribute '" + attributeName + "' is not a proper double: " + str);
}
}
public static double getOptionalDouble(final Element element, final String attributeName, double defaultValue) {
final String str = element.getAttributeValue(attributeName);
if (str == null) {
return defaultValue;
}
try {
return Double.parseDouble(str);
}
catch (NumberFormatException e) {
throw new IllegalArgumentException("attribute '" + attributeName + "' is not a proper double: " + str);
}
}
public static float getRequiredFloat(final Element element, final String attributeName) {
final String str = getRequiredString(element, attributeName);
try {
return Float.parseFloat(str);
}
catch (NumberFormatException e) {
throw new IllegalArgumentException("attribute '" + attributeName + "' is not a proper float: " + str);
}
}
public static Object getRequiredPrimitiveTypeValue(final Element element, final String attributeName, final Class valueClass) {
final String str = getRequiredString(element, attributeName);
try {
final Method method = valueClass.getMethod("valueOf", new Class[]{String.class});
//noinspection unchecked
return method.invoke(null, new Object[]{str});
}
catch (NumberFormatException e) {
throw new IllegalArgumentException("attribute '" + attributeName + "' is not a proper float: " + str);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
public static StringDescriptor getStringDescriptor(final Element element, final String valueAttr,
final String bundleAttr, final String keyAttr) {
final String title = element.getAttributeValue(valueAttr);
if (title != null) {
StringDescriptor descriptor = StringDescriptor.create(title);
descriptor.setNoI18n(getOptionalBoolean(element, UIFormXmlConstants.ATTRIBUTE_NOI18N, false));
return descriptor;
}
else {
final String bundle = element.getAttributeValue(bundleAttr);
if (bundle != null) {
final String key = getRequiredString(element, keyAttr);
return new StringDescriptor(bundle, key);
}
}
return null;
}
public static FontDescriptor getFontDescriptor(final Element element) {
String swingFont = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_SWING_FONT);
if (swingFont != null) {
return FontDescriptor.fromSwingFont(swingFont);
}
String fontName = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_NAME);
int fontStyle = getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_STYLE, -1);
int fontSize = getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_SIZE, -1);
return new FontDescriptor(fontName, fontStyle, fontSize);
}
public static ColorDescriptor getColorDescriptor(final Element element) throws Exception {
Attribute attr = element.getAttribute(UIFormXmlConstants.ATTRIBUTE_COLOR);
if (attr != null) {
return new ColorDescriptor(new Color(attr.getIntValue()));
}
String swingColor = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_SWING_COLOR);
if (swingColor != null) {
return ColorDescriptor.fromSwingColor(swingColor);
}
String systemColor = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_SYSTEM_COLOR);
if (systemColor != null) {
return ColorDescriptor.fromSystemColor(systemColor);
}
String awtColor = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_AWT_COLOR);
if (awtColor != null) {
return ColorDescriptor.fromAWTColor(awtColor);
}
return new ColorDescriptor(null);
}
public static ColorDescriptor getOptionalColorDescriptor(final Element element) {
if (element == null) return null;
try {
return getColorDescriptor(element);
}
catch(Exception ex) {
return null;
}
}
public static Insets readInsets(final Element element) {
final int top = getRequiredInt(element, UIFormXmlConstants.ATTRIBUTE_TOP);
final int left = getRequiredInt(element, UIFormXmlConstants.ATTRIBUTE_LEFT);
final int bottom = getRequiredInt(element, UIFormXmlConstants.ATTRIBUTE_BOTTOM);
final int right = getRequiredInt(element, UIFormXmlConstants.ATTRIBUTE_RIGHT);
return new Insets(top, left, bottom, right);
}
}
@@ -0,0 +1,31 @@
/*
* Copyright 2000-2005 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 java.util.HashMap;
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public interface PropertiesProvider {
/**
* @return key - property name (String), value - LwProperty. If class cannot be inspected for some reason,
* returns null
*/
HashMap getLwProperties(String className);
}
@@ -0,0 +1,150 @@
/*
* Copyright 2000-2005 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;
/**
* @author Vladimir Kondratyev
*/
public final class StringDescriptor {
/**
* Name of resource bundle
*/
private final String myBundleName;
/**
* Key in the resource bundle
*/
private final String myKey;
/**
* Value has sense if it's calculated not via resource bundle
*/
private final String myValue;
/**
* Cached resolved value. We need it here to speed up property inspector
* painting.
*/
private String myResolvedValue;
/**
* Marker for string values which do not need internationalization
*/
private boolean myNoI18n;
private StringDescriptor(final String value){
if (value == null) {
throw new IllegalArgumentException("value cannot be null");
}
myBundleName = null;
myKey = null;
myValue = value;
}
public StringDescriptor(final String bundleName, final String key) {
if (bundleName == null) {
throw new IllegalArgumentException("bundleName cannot be null");
}
if (key == null) {
throw new IllegalArgumentException("key cannot be null");
}
myBundleName = bundleName.replace('.', '/');
myKey = key;
myValue = null;
}
/**
* Creates "trivial" StringDescriptor.
*/
public static StringDescriptor create(final String value){
return value != null ? new StringDescriptor(value) : null;
}
/**
* @return not <code>null</code> value if this is "trivial" StringDescriptor.
* If StringDescriptor is "trivial" then {@link #getBundleName()} and {@link #getKey()}
* return <code>null</code>.
*/
public String getValue(){
return myValue;
}
/**
* @return not <code>null</code> value if this is non "trivial" StringDescriptor.
*/
public String getBundleName() {
return myBundleName;
}
public String getDottedBundleName() {
return myBundleName == null ? null : myBundleName.replace('/', '.');
}
/**
* @return not <code>null</code> value if this is non "trivial" StringDescriptor.
*/
public String getKey() {
return myKey;
}
/**
* @return can be null
*/
public String getResolvedValue() {
return myResolvedValue;
}
/**
* @param resolvedValue can be null
*/
public void setResolvedValue(final String resolvedValue) {
myResolvedValue = resolvedValue;
}
public boolean isNoI18n() {
return myNoI18n;
}
public void setNoI18n(final boolean noI18n) {
myNoI18n = noI18n;
}
public boolean equals(final Object o) {
if (this == o) return true;
if (!(o instanceof StringDescriptor)) return false;
final StringDescriptor descriptor = (StringDescriptor)o;
if (myBundleName != null ? !myBundleName.equals(descriptor.myBundleName) : descriptor.myBundleName != null) return false;
if (myKey != null ? !myKey.equals(descriptor.myKey) : descriptor.myKey != null) return false;
if (myValue != null ? !myValue.equals(descriptor.myValue) : descriptor.myValue != null) return false;
if (myNoI18n != descriptor.myNoI18n) return false;
return true;
}
public int hashCode() {
int result;
result = (myBundleName != null ? myBundleName.hashCode() : 0);
result = 29 * result + (myKey != null ? myKey.hashCode() : 0);
result = 29 * result + (myValue != null ? myValue.hashCode() : 0);
return result;
}
public String toString() {
if (myValue != null) {
return "[StringDescriptor:" + myValue + "]";
}
return "[StringDescriptor" + myBundleName + ":" + myKey + "]";
}
}
@@ -0,0 +1,50 @@
/*
* Copyright 2000-2006 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 org.jdom.Element;
import com.intellij.uiDesigner.shared.XYLayoutManager;
import java.awt.*;
/**
* @author yole
*/
public class XYLayoutSerializer extends LayoutSerializer {
static XYLayoutSerializer INSTANCE = new XYLayoutSerializer();
private XYLayoutSerializer() {
}
void readLayout(Element element, LwContainer container) {
container.setLayout(new XYLayoutManager());
}
void readChildConstraints(final Element constraintsElement, final LwComponent component) {
final Element xyElement = LwXmlReader.getChild(constraintsElement, "xy");
if(xyElement != null){
component.setBounds(
new Rectangle(
LwXmlReader.getRequiredInt(xyElement, "x"),
LwXmlReader.getRequiredInt(xyElement, "y"),
LwXmlReader.getRequiredInt(xyElement, "width"),
LwXmlReader.getRequiredInt(xyElement, "height")
)
);
}
}
}
@@ -0,0 +1,111 @@
/*
* Copyright 2000-2005 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.shared;
import com.intellij.uiDesigner.compiler.UnexpectedFormElementException;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
/**
* @author Vladimir Kondratyev
*/
public final class BorderType {
public static final BorderType NONE = new BorderType("none", "None",null,null);
public static final BorderType BEVEL_LOWERED = new BorderType("bevel-lowered", "Bevel Lowered", BorderFactory.createLoweredBevelBorder(), "createLoweredBevelBorder");
public static final BorderType BEVEL_RAISED = new BorderType("bevel-raised", "Bevel Raised", BorderFactory.createRaisedBevelBorder(), "createRaisedBevelBorder");
public static final BorderType ETCHED = new BorderType("etched", "Etched", BorderFactory.createEtchedBorder(), "createEtchedBorder");
public static final BorderType LINE = new BorderType("line", "Line", BorderFactory.createLineBorder(Color.BLACK), "createLineBorder");
public static final BorderType EMPTY = new BorderType("empty", "Empty", BorderFactory.createEmptyBorder(0, 0, 0, 0), "createEmptyBorder");
private final String myId;
private final String myName;
private final Border myBorder;
private final String myBorderFactoryMethodName;
private BorderType(final String id, final String name, final Border border, final String borderFactoryMethodName) {
myId=id;
myName=name;
myBorder=border;
myBorderFactoryMethodName = borderFactoryMethodName;
}
public String getId(){
return myId;
}
public String getName(){
return myName;
}
public Border createBorder(final String title,
final int titleJustification,
final int titlePosition,
final Font titleFont,
final Color titleColor,
final Insets borderSize,
final Color borderColor) {
Border baseBorder = myBorder;
if (equals(EMPTY) && borderSize != null) {
baseBorder = BorderFactory.createEmptyBorder(borderSize.top, borderSize.left, borderSize.bottom, borderSize.right);
}
else if (equals(LINE) && borderColor != null) {
baseBorder = BorderFactory.createLineBorder(borderColor);
}
if (title != null) {
return BorderFactory.createTitledBorder(baseBorder, title, titleJustification, titlePosition, titleFont, titleColor);
}
else {
return baseBorder;
}
}
public String getBorderFactoryMethodName(){
return myBorderFactoryMethodName;
}
public boolean equals(final Object o){
if (o instanceof BorderType){
return myId.equals(((BorderType)o).myId);
}
return false;
}
public int hashCode(){
return 0;
}
public static BorderType valueOf(final String name){
BorderType[] allTypes = getAllTypes();
for(int i=0; i<allTypes.length; i++) {
if (allTypes [i].getId().equals(name)) return allTypes [i];
}
throw new UnexpectedFormElementException("unknown type: "+name);
}
public static BorderType[] getAllTypes() {
return new BorderType[]{
BorderType.NONE,
BorderType.EMPTY,
BorderType.BEVEL_LOWERED,
BorderType.BEVEL_RAISED,
BorderType.ETCHED,
BorderType.LINE
};
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2000-2005 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.shared;
import com.intellij.uiDesigner.core.AbstractLayout;
import java.awt.*;
public class XYLayoutManager extends AbstractLayout {
public XYLayoutManager(){
}
public Dimension maximumLayoutSize(final Container target){
throw new UnsupportedOperationException();
}
public Dimension preferredLayoutSize(final Container parent){
throw new UnsupportedOperationException();
}
public Dimension minimumLayoutSize(final Container parent){
throw new UnsupportedOperationException();
}
public void layoutContainer(final Container parent){
throw new UnsupportedOperationException();
}
public void setPreferredSize(final Dimension size){
throw new UnsupportedOperationException();
}
public final void invalidateLayout(final Container target){
}
}
@@ -0,0 +1,190 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public final class EliminateTest extends TestCase{
public void test1() {
// 11
// 2
doTest(
new int[][]{
{0, 2},
{1, 1}
},
new int[][]{
{0, 1},
{0, 1}
}
);
}
public void test2(){
// 111
// 2
doTest(
new int[][]{
{0, 3},
{1, 1}
},
new int[][]{
{0, 1},
{0, 1}
}
);
}
public void test3(){
// 11
// 2
doTest(
new int[][]{
{0,2},
{0,1}
},
new int[][]{
{0, 1},
{0, 1}
}
);
}
public void test4(){
// 12
// 33
doTest(
new int[][]{
{0, 1},
{1, 1},
{0, 2}
},
new int[][]{
{0, 1},
{1, 1},
{0, 2}
}
);
}
public void test5(){
// 112
// 333
doTest(
new int[][]{
{0, 2},
{2, 1},
{1, 3}
},
new int[][]{
{0, 1},
{1, 1},
{0, 2}
}
);
}
public void test7(){
// 11 222
// 3333
doTest(
new int[][]{
{0, 2},
{3, 3},
{1, 4}
},
new int[][]{
{0, 1},
{1, 1},
{0, 2}
}
);
}
public void test8(){
// 111
// 222
doTest(
new int[][]{
{2, 3},
{0, 3}
},
new int[][]{
{0, 1},
{0, 1}
}
);
}
public void test9(){
// 1 22
// 333
doTest(
new int[][]{
{0, 1},
{2, 2},
{0, 3}
},
new int[][]{
{0, 1},
{1, 1},
{0, 2}
}
);
}
public void test9a(){
// 122
// 33
doTest(
new int[][]{
{0, 1},
{1, 2},
{0, 2}
},
new int[][]{
{0, 1},
{1, 1},
{0, 2}
}
);
}
public void test10(){
// 1 2
doTest(
new int[][]{
{0, 1},
{2, 1},
},
new int[][]{
{0, 1},
{1, 1},
}
);
}
private static void doTest(final int[][] src, final int[][] expected) {
final int[] cells = new int[src.length];
final int[] spans = new int[src.length];
for (int i = 0; i < cells.length; i++) {
cells[i] = src[i][0];
spans[i] = src[i][1];
}
Util.eliminate(cells, spans, null);
for (int i = 0; i < spans.length; i++) {
if (cells[i] != expected[i][0] ||
spans[i] != expected[i][1]
){
for (int j = 0; j < spans.length; j++) {
System.out.println("i=" + j + " expected ("+expected[j][0] + "," + expected[j][1] +"), result (" + cells[j] + "," + spans[j]+")");
}
assertTrue(false);
}
}
}
}
@@ -0,0 +1,48 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
import java.util.Arrays;
public final class EmptyPanelTest extends TestCase{
public void test1() {
final GridLayoutManager layoutManager = new GridLayoutManager(2,3, new Insets(0,0,0,0), 0, 0);
final JPanel panel = new JPanel(layoutManager);
assertEquals(0, panel.getPreferredSize().width);
assertEquals(0, panel.getPreferredSize().height);
panel.setSize(90, 200);
panel.doLayout(); // should not crash with exception
assertTrue(Arrays.equals(new int[]{0,30,60}, layoutManager.getXs()));
assertTrue(Arrays.equals(new int[]{30,30,30}, layoutManager.getWidths()));
assertTrue(Arrays.equals(new int[]{0,100}, layoutManager.getYs()));
assertTrue(Arrays.equals(new int[]{100,100}, layoutManager.getHeights()));
// add component
final JButton button = new JButton();
button.setPreferredSize(new Dimension(100,20));
panel.add(button, new GridConstraints(0,1,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,GridConstraints.SIZEPOLICY_CAN_GROW,GridConstraints.SIZEPOLICY_FIXED,null,null,null,
0));
// wisdom
layoutManager.invalidateLayout(panel);
assertEquals(new Dimension(100,20), panel.getPreferredSize());
panel.setSize(panel.getPreferredSize());
panel.doLayout();
assertEquals(100, button.getWidth());
assertEquals(20, panel.getHeight());
assertTrue(Arrays.equals(new int[]{0,0,100}, layoutManager.getXs()));
assertTrue(Arrays.equals(new int[]{0,100,0}, layoutManager.getWidths()));
assertTrue(Arrays.equals(new int[]{0,20}, layoutManager.getYs()));
assertTrue(Arrays.equals(new int[]{20,0}, layoutManager.getHeights()));
}
}
@@ -0,0 +1,112 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
public final class EqualSizeCellsTest extends TestCase{
/**
* field1 | field2 | field3
*/
public void test1() {
final GridLayoutManager layout = new GridLayoutManager(1,3, new Insets(0,0,0,0), 7, 0);
layout.setSameSizeHorizontally(true);
final JPanel panel = new JPanel(layout);
final JTextField field1 = new JTextField();
field1.setMinimumSize(new Dimension(5,20));
field1.setPreferredSize(new Dimension(10,20));
final JTextField field2 = new JTextField();
field2.setMinimumSize(new Dimension(25,20));
field2.setPreferredSize(new Dimension(50,20));
final JTextField field3 = new JTextField();
field3.setMinimumSize(new Dimension(70,20));
field3.setPreferredSize(new Dimension(100,20));
panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field3, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension minimumSize = panel.getMinimumSize();
assertEquals(70 + 7 + 70 + 7 + 70, minimumSize.width);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(100 + 7 + 100 + 7 + 100, preferredSize.width);
//
panel.setSize(panel.getPreferredSize());
panel.doLayout();
assertEquals(100, field1.getWidth());
assertEquals(100, field2.getWidth());
assertEquals(100, field3.getWidth());
//
panel.setSize(new Dimension(1000, 1000));
panel.doLayout();
assertEquals(329, field1.getWidth());
assertEquals(329, field2.getWidth());
assertEquals(328, field3.getWidth());
}
/**
* field1
* ------
* field2
* ------
* field3
*/
public void test2() {
final GridLayoutManager layout = new GridLayoutManager(3,1, new Insets(0,0,0,0), 0, 7);
layout.setSameSizeVertically(true);
final JPanel panel = new JPanel(layout);
final JTextField field1 = new JTextField();
field1.setMinimumSize(new Dimension(20, 5));
field1.setPreferredSize(new Dimension(20, 10));
final JTextField field2 = new JTextField();
field2.setMinimumSize(new Dimension(20, 25));
field2.setPreferredSize(new Dimension(20, 50));
final JTextField field3 = new JTextField();
field3.setMinimumSize(new Dimension(20, 70));
field3.setPreferredSize(new Dimension(20, 100));
panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null, 0));
panel.add(field2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null, 0));
panel.add(field3, new GridConstraints(2,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null, 0));
final Dimension minimumSize = panel.getMinimumSize();
assertEquals(70 + 7 + 70 + 7 + 70, minimumSize.height);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(100 + 7 + 100 + 7 + 100, preferredSize.height);
panel.setSize(panel.getPreferredSize());
panel.doLayout();
assertEquals(100, field1.getHeight());
assertEquals(100, field2.getHeight());
assertEquals(100, field3.getHeight());
}
}
@@ -0,0 +1,243 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
public final class GapsTest extends TestCase{
public void test1() {
final JPanel panel = new JPanel(new GridLayoutManager(1,2, new Insets(0,0,0,0), 10, 0));
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(100,20));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(100,20));
panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(210, preferredSize.width);
}
/**
* field (span 2) | field (span 1)
*/
public void test2() {
final JPanel panel = new JPanel(new GridLayoutManager(1,3, new Insets(0,0,0,0), 7, 0));
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(100,20));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(100,20));
panel.add(field1, new GridConstraints(0,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field2, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(207, preferredSize.width);
panel.setSize(panel.getPreferredSize());
panel.doLayout();
assertEquals(new Rectangle(0,0,100,20), field1.getBounds());
assertEquals(new Rectangle(107,0,100,20), field2.getBounds());
}
/**
*
* btn1 | btn2 | btn4
* btn3 (span 2) |
*/
public void test3() {
final JPanel panel = new JPanel(new GridLayoutManager(2,3, new Insets(0,0,0,0), 7, 0));
final JButton btn1 = new JButton();
btn1.setPreferredSize(new Dimension(100,20));
final JButton btn2 = new JButton();
btn2.setPreferredSize(new Dimension(100,20));
final JButton btn3 = new JButton();
btn3.setPreferredSize(new Dimension(100,20));
final JButton btn4 = new JButton();
btn4.setPreferredSize(new Dimension(100,20));
panel.add(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(btn2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(btn3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(btn4, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(314, preferredSize.width);
panel.setSize(panel.getPreferredSize());
panel.doLayout();
}
/**
*
* btn1 | btn2 | btn4
* btn3 (span 2) |
*/
public void test3a() {
final JPanel panel = new JPanel(new GridLayoutManager(2,3, new Insets(0,0,0,0), 1000, 0));
final JButton btn1 = new JButton();
btn1.setPreferredSize(new Dimension(100,20));
final JButton btn2 = new JButton();
btn2.setPreferredSize(new Dimension(100,20));
final JButton btn3 = new JButton();
btn3.setPreferredSize(new Dimension(100,20));
final JButton btn4 = new JButton();
btn4.setPreferredSize(new Dimension(100,20));
panel.add(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(btn2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(btn3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(btn4, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(2300, preferredSize.width);
panel.setSize(panel.getPreferredSize());
panel.doLayout();
}
/**
*
* btn1 | btn2
* btn3 (span 2)
*/
public void test3b() {
final JPanel panel = new JPanel(new GridLayoutManager(2,3, new Insets(0,0,0,0), 1000, 0));
final JButton btn1 = new JButton();
btn1.setPreferredSize(new Dimension(100,20));
final JButton btn2 = new JButton();
btn2.setPreferredSize(new Dimension(100,20));
final JButton btn3 = new JButton();
btn3.setPreferredSize(new Dimension(100,20));
panel.add(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(btn2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(btn3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(1200, preferredSize.width);
panel.setSize(panel.getPreferredSize());
panel.doLayout();
}
/**
* btn1
* -----
* empty
* ----
* btn2
*/
public void test4() {
final JPanel panel = new JPanel(new GridLayoutManager(3,1, new Insets(0,0,0,0), 0, 7));
final JButton btn1 = new JButton();
btn1.setPreferredSize(new Dimension(100,20));
final JButton btn2 = new JButton();
btn2.setPreferredSize(new Dimension(100,20));
panel.add(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(btn2, new GridConstraints(2,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(47, preferredSize.height);
panel.setSize(panel.getPreferredSize());
panel.doLayout();
}
/**
* btn1
* -----
* spacer
* ----
* btn2
*/
public void test5() {
final JPanel panel = new JPanel(new GridLayoutManager(3,1, new Insets(0,0,0,0), 0, 7));
final JButton btn1 = new JButton();
btn1.setPreferredSize(new Dimension(100,20));
final JButton btn2 = new JButton();
btn2.setPreferredSize(new Dimension(100,20));
panel.add(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(new Spacer(), new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0));
panel.add(btn2, new GridConstraints(2,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(47, preferredSize.height);
panel.setSize(panel.getPreferredSize());
panel.doLayout();
}
/**
* btn1
* ----- (very big gap)
* btn2
*/
public void test6() {
final JPanel panel = new JPanel(new GridLayoutManager(2,1, new Insets(0,0,0,0), 0, 500));
final JButton btn1 = new JButton();
btn1.setPreferredSize(new Dimension(100,20));
final JButton btn2 = new JButton();
btn2.setPreferredSize(new Dimension(100,20));
panel.add(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(btn2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(540, preferredSize.height);
panel.setSize(panel.getPreferredSize());
panel.doLayout(); // should not crash
}
}
@@ -0,0 +1,909 @@
/*
* Copyright 2000-2005 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.core;
import com.intellij.uiDesigner.compiler.GridBagConverter;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
/**
* Created by IntelliJ IDEA.
* User: yole
* Date: 23.11.2005
* Time: 13:47:38
* To change this template use File | Settings | File Templates.
*/
public class GridBagConverterTest extends TestCase {
/**
* button 1
* <empty>
* button 2
*/
public void testLayout2() {
final GridBagLayout layoutManager = new GridBagLayout();
final JPanel panel = new JPanel(layoutManager);
final JButton button1 = new JButton();
button1.setMinimumSize(new Dimension(9, 7));
button1.setPreferredSize(new Dimension(50, 10));
final JButton button2 = new JButton();
button2.setMinimumSize(new Dimension(15, 6));
button2.setPreferredSize(new Dimension(50, 10));
GridBagConverter converter = new GridBagConverter();
final GridConstraints button1Constraints = new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK,
null, null, null, 0);
converter.addComponent(button1, button1Constraints);
final GridConstraints button2Constraints = new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK,
GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0);
converter.addComponent(button2, button2Constraints);
applyConversionResults(panel, converter);
assertEquals(20, panel.getPreferredSize().height);
assertEquals(50, panel.getPreferredSize().width);
assertEquals(17, panel.getMinimumSize().height);
assertEquals(50, panel.getMinimumSize().width);
panel.setSize(new Dimension(500, 100));
panel.doLayout();
assertEquals(50, button1.getHeight());
assertEquals(50, button2.getHeight());
}
public void testLayout2ByConstraints() {
final GridBagLayout layoutManager = new GridBagLayout();
final JPanel panel = new JPanel(layoutManager);
final JButton button1 = new JButton();
final JButton button2 = new JButton();
GridBagConverter converter = new GridBagConverter();
final GridConstraints button1Constraints = new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_GROW,
GridConstraints.SIZEPOLICY_CAN_SHRINK,
new Dimension(9, 7), new Dimension(50, 10), null, 0);
converter.addComponent(button1, button1Constraints);
final GridConstraints button2Constraints = new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK,
GridConstraints.SIZEPOLICY_FIXED,
new Dimension(15, 6), new Dimension(50, 10), null, 0);
converter.addComponent(button2, button2Constraints);
applyConversionResults(panel, converter);
assertEquals(20, panel.getPreferredSize().height);
assertEquals(50, panel.getPreferredSize().width);
assertEquals(17, panel.getMinimumSize().height);
assertEquals(50, panel.getMinimumSize().width);
panel.setSize(new Dimension(500, 100));
panel.doLayout();
assertEquals(50, button1.getHeight());
assertEquals(50, button2.getHeight());
}
public void testLayout3() {
final JPanel panel = new JPanel(new GridBagLayout());
final JButton button1 = new JButton();
button1.setPreferredSize(new Dimension(100,20));
final JButton button2 = new JButton();
button2.setPreferredSize(new Dimension(100,100));
GridBagConverter converter = new GridBagConverter();
converter.addComponent(button1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(button2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(120, preferredSize.height);
}
public void testLayout4() {
final JPanel panel = new JPanel(new GridBagLayout());
// button 1 button 3
// button 2 button 3
final JButton button1 = new JButton();
button1.setPreferredSize(new Dimension(100,10));
final JButton button2 = new JButton();
button2.setPreferredSize(new Dimension(100,10));
final JButton button3 = new JButton();
button3.setPreferredSize(new Dimension(100,200));
GridBagConverter converter = new GridBagConverter();
converter.addComponent(button1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW + GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null,
0));
converter.addComponent(button2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW + GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null,
0));
converter.addComponent(button3, new GridConstraints(0,1,2,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW + GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null,
0));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(200, preferredSize.height);
}
/* TODO[yole]: this layout does not work as expected at runtime
public void testLayout5_1() {
final JPanel panel = new JPanel(new GridBagLayout());
// label textfield(span 2)
// textfield(span 2)
final JTextField label = new JTextField();
label.setPreferredSize(new Dimension(10,30));
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(100,30));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(100,30));
GridBagConverter converter = new GridBagConverter();
converter.addComponent(label, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null));
converter.addComponent(field1, new GridConstraints(0,1,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null));
converter.addComponent(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(110, preferredSize.width);
assertEquals(60, preferredSize.height);
}
*/
public void testLayout7() {
final JPanel panel = new JPanel(new GridBagLayout());
final JLabel label = new JLabel();
label.setPreferredSize(new Dimension(50,10));
final JTextField field = new JTextField();
field.setPreferredSize(new Dimension(100,10));
final JTextField scroll = new JTextField();
scroll.setPreferredSize(new Dimension(503, 10));
GridBagConverter converter = new GridBagConverter();
converter.addComponent(label, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
converter.addComponent(field, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
converter.addComponent(scroll, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
applyConversionResults(panel, converter);
assertEquals(503, panel.getMinimumSize().width);
assertEquals(503, panel.getPreferredSize().width);
panel.setSize(503, 100);
panel.doLayout();
assertEquals(50, label.getWidth());
assertEquals(453, field.getWidth());
}
public void testLayout8() {
final JPanel panel = new JPanel(new GridBagLayout());
final JLabel label1 = new JLabel();
label1.setMinimumSize(new Dimension(10,10));
label1.setPreferredSize(new Dimension(100,10));
final JLabel label2 = new JLabel();
label2.setMinimumSize(new Dimension(10,10));
label2.setPreferredSize(new Dimension(100,10));
GridBagConverter converter = new GridBagConverter();
converter.addComponent(label1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK + GridConstraints.SIZEPOLICY_CAN_GROW,
GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(label2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK,
GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(new JLabel(), new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK + GridConstraints.SIZEPOLICY_CAN_GROW + GridConstraints.SIZEPOLICY_WANT_GROW,
GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0));
applyConversionResults(panel, converter);
assertEquals(20, panel.getMinimumSize().width);
assertEquals(200, panel.getPreferredSize().width);
// minimum
panel.setSize(20, 100);
panel.doLayout();
assertEquals(10, label1.getWidth());
assertEquals(10, label2.getWidth());
// between min and pref
/* TODO[yole]: GridBag honors weights in this situation, and GridLayout distributes evenly
panel.setSize(76, 100);
panel.doLayout();
assertEquals(38, label1.getWidth());
assertEquals(38, label2.getWidth());
*/
// pref-1
/* TODO[yole]: investigate
panel.setSize(199, 100);
panel.doLayout();
assertEquals(100, label1.getWidth());
assertEquals(99, label2.getWidth());
*/
// pref
panel.setSize(200, 100);
panel.doLayout();
assertEquals(100, label1.getWidth());
assertEquals(100, label2.getWidth());
// pref+1
panel.setSize(201, 100);
panel.doLayout();
assertEquals(101, label1.getWidth());
assertEquals(100, label2.getWidth());
// pref + few
panel.setSize(205, 100);
panel.doLayout();
assertEquals(105, label1.getWidth());
assertEquals(100, label2.getWidth());
}
public void testPrefSize1() {
final JPanel panel = new JPanel(new GridBagLayout());
final JTextField field1 = new JTextField();
field1.setMinimumSize(new Dimension(110,10));
field1.setPreferredSize(new Dimension(120,10));
final JTextField field2 = new JTextField();
field2.setMinimumSize(new Dimension(215,10));
field2.setPreferredSize(new Dimension(225,10));
GridBagConverter converter = new GridBagConverter();
converter.addComponent(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(345, preferredSize.width);
final Dimension minSize = panel.getMinimumSize();
assertEquals(325, minSize.width);
panel.setSize(preferredSize.width, preferredSize.height);
panel.doLayout();
assertEquals(120, field1.getWidth());
assertEquals(225, field2.getWidth());
panel.setSize(400, panel.getWidth());
panel.invalidate(); // to invalidate layout
panel.doLayout();
}
/* TODO[yole]: this relies on strange myMinCellSize logic
public void testPrefSize2() {
final JPanel panel = new JPanel(new GridBagLayout());
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(100,10));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(200,10));
GridBagConverter converter = new GridBagConverter();
converter.addComponent(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null));
converter.addComponent(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(300 + 20, preferredSize.width);
panel.setSize(preferredSize.width, preferredSize.height);
panel.doLayout();
assertEquals(100, field1.getWidth());
assertEquals(200, field2.getWidth());
panel.setSize(270, preferredSize.height);
panel.doLayout(); // should not fail
}
*/
/**
* button(can grow) | text field (want grow)
* text field (want grow, span 2)
*/
public void testSpans1() {
final JPanel panel = new JPanel(new GridBagLayout());
final JButton button = new JButton();
button.setPreferredSize(new Dimension(50, 10));
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(50, 10));
final JTextField field2 = new JTextField();
GridBagConverter converter = new GridBagConverter();
converter.addComponent(button, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(field1, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(100, preferredSize.width);
panel.setSize(new Dimension(500, 100));
panel.doLayout();
assertEquals(500, field2.getWidth());
assertEquals(50, button.getWidth());
assertEquals(450, field1.getWidth());
}
/**
* button(can grow) | text field (can grow)
* text field (want grow, span 2)
*/
public void testSpans2() {
final JPanel panel = new JPanel(new GridBagLayout());
final JButton button = new JButton();
button.setPreferredSize(new Dimension(50, 10));
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(50, 10));
final JTextField field2 = new JTextField();
GridBagConverter converter = new GridBagConverter();
converter.addComponent(button, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(field1, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(100, preferredSize.width);
panel.setSize(new Dimension(500, 100));
panel.doLayout();
assertEquals(500, field2.getWidth());
assertEquals(250, button.getWidth());
assertEquals(250, field1.getWidth());
}
/**
* button(can grow) | text field (want grow, span 2)
*/
public void testSpans3() {
final JPanel panel = new JPanel(new GridBagLayout());
final JButton button = new JButton();
button.setPreferredSize(new Dimension(50, 10));
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(110, 10));
GridBagConverter converter = new GridBagConverter();
converter.addComponent(button, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(field1, new GridConstraints(0,1,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(160, preferredSize.width);
panel.setSize(new Dimension(500, 100));
panel.doLayout();
assertEquals(50, button.getWidth());
assertEquals(450, field1.getWidth());
}
/**
* button (can grow, span 2 ) | text field 1 (span 1)
* text field 2 (want grow, span 2) | empty
*/
public void testSpans4() {
final JPanel panel = new JPanel(new GridBagLayout());
final JButton button = new JButton();
button.setPreferredSize(new Dimension(50, 10));
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(110, 10));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(110, 10));
GridBagConverter converter = new GridBagConverter();
converter.addComponent(button, new GridConstraints(0,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(field1, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(220, preferredSize.width);
panel.setSize(new Dimension(500, 100));
panel.doLayout();
assertEquals(250, button.getWidth());
assertEquals(250, field1.getWidth());
assertEquals(250, field2.getWidth());
}
/**
* label | label
* text area (span 2)
*/
public void testTextAreas1() {
final JPanel panel = new JPanel(new GridBagLayout());
final JLabel label1 = new JLabel();
label1.setPreferredSize(new Dimension(15,20));
final JLabel label2 = new JLabel();
label2.setPreferredSize(new Dimension(15,20));
final JTextArea textArea = new JTextArea();
textArea.setLineWrap(true);
GridBagConverter converter = new GridBagConverter();
converter.addComponent(label1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(label2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(textArea, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0));
applyConversionResults(panel, converter);
assertEquals(100, textArea.getPreferredSize().width);
final Dimension initialPreferredSize = panel.getPreferredSize();
assertEquals(new Dimension(100,20 + textArea.getPreferredSize().height), initialPreferredSize);
panel.setSize(initialPreferredSize);
panel.invalidate();
panel.doLayout();
assertEquals(initialPreferredSize, panel.getPreferredSize());
}
/**
* textfield1 | textfield2
* textfield3 (span 2)
*
* important: hspan should be greater than 0
*/
public void testTextAreas2() {
final JPanel panel = new JPanel(/*new GridLayoutManager(2,2, new Insets(0,0,0,0), 11, 0)*/ new GridBagLayout());
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(15,20));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(15,20));
final JTextField field3 = new JTextField();
field3.setPreferredSize(new Dimension(100,20));
GridBagConverter converter = new GridBagConverter();
converter.addComponent(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(field3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
assertEquals(100, panel.getPreferredSize().width);
}
public void testGaps1() {
final JPanel panel = new JPanel(new GridBagLayout());
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(100,20));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(100,20));
GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 10, 0, false, false);
converter.addComponent(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(210, preferredSize.width);
}
/**
* field (span 2) | field (span 1)
*/
public void testGaps2() {
final JPanel panel = new JPanel(new GridBagLayout());
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(100,20));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(100,20));
GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 7, 0, false, false);
converter.addComponent(field1, new GridConstraints(0,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(field2, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(207, preferredSize.width);
panel.setSize(panel.getPreferredSize());
panel.doLayout();
assertEquals(new Rectangle(0,0,100,20), field1.getBounds());
assertEquals(new Rectangle(107,0,100,20), field2.getBounds());
}
/**
*
* btn1 | btn2 | btn4
* btn3 (span 2) |
*/
public void testGaps3() {
final JPanel panel = new JPanel(new GridBagLayout());
final JButton btn1 = new JButton();
btn1.setPreferredSize(new Dimension(100,20));
final JButton btn2 = new JButton();
btn2.setPreferredSize(new Dimension(100,20));
final JButton btn3 = new JButton();
btn3.setPreferredSize(new Dimension(100,20));
final JButton btn4 = new JButton();
btn4.setPreferredSize(new Dimension(100,20));
GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 7, 0, false, false);
converter.addComponent(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(btn2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(btn3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(btn4, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(314, preferredSize.width);
panel.setSize(panel.getPreferredSize());
panel.doLayout();
}
/**
*
* btn1 | btn2 | btn4
* btn3 (span 2) |
*/
public void testGaps3a() {
final JPanel panel = new JPanel(new GridBagLayout());
final JButton btn1 = new JButton();
btn1.setPreferredSize(new Dimension(100,20));
final JButton btn2 = new JButton();
btn2.setPreferredSize(new Dimension(100,20));
final JButton btn3 = new JButton();
btn3.setPreferredSize(new Dimension(100,20));
final JButton btn4 = new JButton();
btn4.setPreferredSize(new Dimension(100,20));
GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 1000, 0, false, false);
converter.addComponent(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(btn2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(btn3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(btn4, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(2300, preferredSize.width);
panel.setSize(panel.getPreferredSize());
panel.doLayout();
}
/**
*
* btn1 | btn2
* btn3 (span 2)
*/
public void testGaps3b() {
final JPanel panel = new JPanel(new GridBagLayout());
final JButton btn1 = new JButton();
btn1.setPreferredSize(new Dimension(100,20));
final JButton btn2 = new JButton();
btn2.setPreferredSize(new Dimension(100,20));
final JButton btn3 = new JButton();
btn3.setPreferredSize(new Dimension(100,20));
GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 1000, 0, false, false);
converter.addComponent(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(btn2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(btn3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(1200, preferredSize.width);
panel.setSize(panel.getPreferredSize());
panel.doLayout();
}
/**
* btn1
* -----
* empty
* ----
* btn2
*/
public void testGaps4() {
final JPanel panel = new JPanel(new GridBagLayout());
final JButton btn1 = new JButton();
btn1.setPreferredSize(new Dimension(100,20));
final JButton btn2 = new JButton();
btn2.setPreferredSize(new Dimension(100,20));
GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 0, 7, false, false);
converter.addComponent(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(btn2, new GridConstraints(2,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(47, preferredSize.height);
panel.setSize(panel.getPreferredSize());
panel.doLayout();
}
// skipped GapsTest.test5 because its only difference from test4 is spacer usage
public void testGaps6() {
final JPanel panel = new JPanel(new GridBagLayout());
final JButton btn1 = new JButton();
btn1.setPreferredSize(new Dimension(100,20));
final JButton btn2 = new JButton();
btn2.setPreferredSize(new Dimension(100,20));
GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 0, 500, false, false);
converter.addComponent(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(btn2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(540, preferredSize.height);
panel.setSize(panel.getPreferredSize());
panel.doLayout(); // should not crash
}
public void testEqualSizeCells1() {
final JPanel panel = new JPanel(new GridBagLayout());
final JTextField field1 = new JTextField();
field1.setMinimumSize(new Dimension(5,20));
field1.setPreferredSize(new Dimension(10,20));
final JTextField field2 = new JTextField();
field2.setMinimumSize(new Dimension(25,20));
field2.setPreferredSize(new Dimension(50,20));
final JTextField field3 = new JTextField();
field3.setMinimumSize(new Dimension(70,20));
field3.setPreferredSize(new Dimension(100,20));
GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 7, 0, true, false);
converter.addComponent(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
converter.addComponent(field3, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension minimumSize = panel.getMinimumSize();
assertEquals(70 + 7 + 70 + 7 + 70, minimumSize.width);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(100 + 7 + 100 + 7 + 100, preferredSize.width);
//
panel.setSize(panel.getPreferredSize());
panel.doLayout();
assertEquals(100, field1.getWidth());
assertEquals(100, field2.getWidth());
assertEquals(100, field3.getWidth());
//
panel.setSize(new Dimension(1000, 1000));
panel.doLayout();
assertEquals(329, field1.getWidth(), 1.0);
assertEquals(329, field2.getWidth(), 1.0);
assertEquals(328, field3.getWidth(), 1.0);
}
public void testEqualSizeCells2() {
final JPanel panel = new JPanel(new GridBagLayout());
final JTextField field1 = new JTextField();
field1.setMinimumSize(new Dimension(20, 5));
field1.setPreferredSize(new Dimension(20, 10));
final JTextField field2 = new JTextField();
field2.setMinimumSize(new Dimension(20, 25));
field2.setPreferredSize(new Dimension(20, 50));
final JTextField field3 = new JTextField();
field3.setMinimumSize(new Dimension(20, 70));
field3.setPreferredSize(new Dimension(20, 100));
GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 0, 7, false, true);
converter.addComponent(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null, 0));
converter.addComponent(field2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null, 0));
converter.addComponent(field3, new GridConstraints(2,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null, 0));
applyConversionResults(panel, converter);
final Dimension minimumSize = panel.getMinimumSize();
assertEquals(70 + 7 + 70 + 7 + 70, minimumSize.height);
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(100 + 7 + 100 + 7 + 100, preferredSize.height);
panel.setSize(panel.getPreferredSize());
panel.doLayout();
assertEquals(100, field1.getHeight());
assertEquals(100, field2.getHeight());
assertEquals(100, field3.getHeight());
}
private void applyConversionResults(final JPanel panel, final GridBagConverter converter) {
GridBagConverter.Result[] results = converter.convert();
for(int i=0; i<results.length; i++) {
GridBagConverter.Result result = results [i];
JComponent component = result.isFillerPanel ? new JPanel() : result.component;
if (result.minimumSize != null) {
component.setMinimumSize(result.minimumSize);
}
if (result.preferredSize != null) {
component.setPreferredSize(result.preferredSize);
}
panel.add(component, result.constraints);
}
}
}
@@ -0,0 +1,31 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
/**
* @author yole
*/
public class IndentTest extends TestCase {
public void testSimple() {
final GridLayoutManager layout = new GridLayoutManager(1,1, new Insets(0,0,0,0), 0, 0);
final JPanel panel = new JPanel(layout);
final JTextField field1 = new JTextField();
field1.setMinimumSize(new Dimension(5,20));
field1.setPreferredSize(new Dimension(10,20));
panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 1));
assertEquals(15, panel.getMinimumSize().width);
assertEquals(20, panel.getPreferredSize().width);
panel.setSize(new Dimension(100, 100));
panel.doLayout();
assertEquals(10, field1.getBounds().x);
assertEquals(90, field1.getBounds().width);
}
}
@@ -0,0 +1,45 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
public final class Layout2Test extends TestCase{
/**
* button 1
* <empty>
* button 2
*/
public void test1() {
final GridLayoutManager layoutManager = new GridLayoutManager(3,1, new Insets(0,0,0,0), 0, 0);
final JPanel panel = new JPanel(layoutManager);
final JButton button1 = new JButton();
button1.setMinimumSize(new Dimension(9, 7));
button1.setPreferredSize(new Dimension(50, 10));
final JButton button2 = new JButton();
button2.setMinimumSize(new Dimension(15, 6));
button2.setPreferredSize(new Dimension(50, 10));
panel.add(button1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null, 0));
panel.add(button2, new GridConstraints(2,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
assertEquals(20, panel.getPreferredSize().height);
assertEquals(50, panel.getPreferredSize().width);
assertEquals(17, panel.getMinimumSize().height);
assertEquals(50, panel.getMinimumSize().width);
panel.setSize(new Dimension(500, 100));
panel.doLayout();
assertEquals(50, button1.getHeight());
assertEquals(50, button2.getHeight());
}
}
@@ -0,0 +1,26 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
public final class Layout3Test extends TestCase{
public void test1() {
final JPanel panel = new JPanel(new GridLayoutManager(2,1, new Insets(0,0,0,0), 0, 0));
final JButton button1 = new JButton();
button1.setPreferredSize(new Dimension(100,20));
final JButton button2 = new JButton();
button2.setPreferredSize(new Dimension(100,100));
panel.add(button1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(button2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(120, preferredSize.height);
}
}
@@ -0,0 +1,39 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
public final class Layout4Test extends TestCase{
public void test1() {
final JPanel panel = new JPanel(new GridLayoutManager(2,2, new Insets(0,0,0,0), 0, 0));
// button 1 button 3
// button 2 button 3
final JButton button1 = new JButton();
button1.setPreferredSize(new Dimension(100,10));
final JButton button2 = new JButton();
button2.setPreferredSize(new Dimension(100,10));
final JButton button3 = new JButton();
button3.setPreferredSize(new Dimension(100,200));
panel.add(button1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW + GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null,
0));
panel.add(button2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW + GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null,
0));
panel.add(button3, new GridConstraints(0,1,2,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW + GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null,
0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(200, preferredSize.height);
}
}
@@ -0,0 +1,127 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
public final class Layout5Test extends TestCase{
public void test1() {
final JPanel panel = new JPanel(new GridLayoutManager(2,3, new Insets(0,0,0,0), 0, 0));
// label textfield(span 2)
// textfield(span 2)
final JTextField label = new JTextField();
label.setPreferredSize(new Dimension(10,30));
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(100,30));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(100,30));
panel.add(label, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
panel.add(field1, new GridConstraints(0,1,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
panel.add(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(110, preferredSize.width);
assertEquals(60, preferredSize.height);
}
public void test2() {
final GridLayoutManager layoutManager = new GridLayoutManager(2,3, new Insets(0,0,0,0), 0, 0);
final JPanel panel = new JPanel(layoutManager);
// empty textfield(span 2)
// textfield(span 2) empty
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(100,30));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(100,30));
panel.add(field1, new GridConstraints(0,1,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
panel.add(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
// after getPreferredSize() invocation, the field should be not null
final DimensionInfo horizontalInfo = layoutManager.myHorizontalInfo;
assertEquals(3, horizontalInfo.getCellCount());
assertEquals(GridConstraints.SIZEPOLICY_CAN_SHRINK, horizontalInfo.getCellSizePolicy(0));
assertEquals(GridConstraints.SIZEPOLICY_WANT_GROW, horizontalInfo.getCellSizePolicy(1));
assertEquals(GridConstraints.SIZEPOLICY_CAN_SHRINK, horizontalInfo.getCellSizePolicy(2));
assertEquals(100, preferredSize.width);
assertEquals(60, preferredSize.height);
panel.setSize(400, 100);
panel.doLayout();
assertEquals(400, field1.getWidth());
assertEquals(400, field2.getWidth());
}
public void test3() {
final GridLayoutManager layoutManager = new GridLayoutManager(2,3, new Insets(0,0,0,0), 0, 0);
final JPanel panel = new JPanel(layoutManager);
// label textfield(span 2)
// textfield(span 2) label
final JTextField label1 = new JTextField();
label1.setPreferredSize(new Dimension(10,30));
final JTextField label2 = new JTextField();
label2.setPreferredSize(new Dimension(10,30));
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(100,30));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(100,30));
panel.add(field1, new GridConstraints(0,1,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
panel.add(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
panel.add(label1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
panel.add(label2, new GridConstraints(1,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
// after getPreferredSize() invocation, the field should be not null
final DimensionInfo horizontalInfo = layoutManager.myHorizontalInfo;
assertEquals(GridConstraints.SIZEPOLICY_FIXED, horizontalInfo.getCellSizePolicy(0));
assertEquals(GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, horizontalInfo.getCellSizePolicy(1));
assertEquals(GridConstraints.SIZEPOLICY_FIXED, horizontalInfo.getCellSizePolicy(2));
assertEquals(110, preferredSize.width);
assertEquals(60, preferredSize.height);
panel.setSize(400, 100);
panel.doLayout();
assertEquals(390, field1.getWidth());
assertEquals(390, field2.getWidth());
assertEquals(10, label1.getWidth());
assertEquals(10, label2.getWidth());
}
}
@@ -0,0 +1,46 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
public final class Layout6Test extends TestCase{
/**
* control(min size 10) control(same) control(same)
*/
public void test1() {
final GridLayoutManager layoutManager = new GridLayoutManager(2,3, new Insets(0,0,0,0), 0, 0);
final JPanel panel = new JPanel(layoutManager);
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(10,30));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(10,30));
final JTextField field3 = new JTextField();
field3.setPreferredSize(new Dimension(10,30));
panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
panel.add(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
panel.add(field3, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(30, preferredSize.width);
for (int size = 31; size < 100; size++) {
panel.setSize(size, 30);
layoutManager.invalidateLayout(panel); // wisdom
panel.doLayout();
}
}
}
@@ -0,0 +1,45 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
public final class Layout7Test extends TestCase{
/**
* label | text field
* scroll pane
*/
public void test1() {
final GridLayoutManager layoutManager = new GridLayoutManager(2,2, new Insets(0,0,0,0), 0, 0);
final JPanel panel = new JPanel(layoutManager);
final JLabel label = new JLabel();
label.setPreferredSize(new Dimension(50,10));
final JTextField field = new JTextField();
field.setPreferredSize(new Dimension(100,10));
final JTextField scroll = new JTextField();
scroll.setPreferredSize(new Dimension(503, 10));
panel.add(label, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
panel.add(field, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
panel.add(scroll, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
assertEquals(503, panel.getMinimumSize().width);
assertEquals(503, panel.getPreferredSize().width);
panel.setSize(503, 100);
panel.doLayout();
assertEquals(50, label.getWidth());
assertEquals(453, field.getWidth());
}
}
@@ -0,0 +1,77 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
public final class Layout8Test extends TestCase{
/**
* label 1 (pref=100, min=10, can shrink, can grow) | label 2 (pref=100, min=10, can shrink)
* (can grow, want grow)
*/
public void test1() {
final GridLayoutManager layoutManager = new GridLayoutManager(2,2, new Insets(0,0,0,0), 0, 0);
final JPanel panel = new JPanel(layoutManager);
final JLabel label1 = new JLabel();
label1.setMinimumSize(new Dimension(10,10));
label1.setPreferredSize(new Dimension(100,10));
final JLabel label2 = new JLabel();
label2.setMinimumSize(new Dimension(10,10));
label2.setPreferredSize(new Dimension(100,10));
panel.add(label1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK + GridConstraints.SIZEPOLICY_CAN_GROW,
GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(label2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK,
GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(new JLabel(), new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK + GridConstraints.SIZEPOLICY_CAN_GROW + GridConstraints.SIZEPOLICY_WANT_GROW,
GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0));
assertEquals(20, panel.getMinimumSize().width);
assertEquals(200, panel.getPreferredSize().width);
// minimum
panel.setSize(20, 100);
panel.doLayout();
assertEquals(10, label1.getWidth());
assertEquals(10, label2.getWidth());
// between min and pref
panel.setSize(76, 100);
panel.doLayout();
assertEquals(38, label1.getWidth());
assertEquals(38, label2.getWidth());
// pref-1
panel.setSize(199, 100);
panel.doLayout();
assertEquals(100, label1.getWidth());
assertEquals(99, label2.getWidth());
// pref
panel.setSize(200, 100);
panel.doLayout();
assertEquals(100, label1.getWidth());
assertEquals(100, label2.getWidth());
// pref+1
panel.setSize(201, 100);
panel.doLayout();
assertEquals(101, label1.getWidth());
assertEquals(100, label2.getWidth());
// pref + few
panel.setSize(205, 100);
panel.doLayout();
assertEquals(105, label1.getWidth());
assertEquals(100, label2.getWidth());
}
}
@@ -0,0 +1,79 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
public final class PrefSizeTest extends TestCase{
/**
* control(min size 110, pref size 120) control(min size 215, pref size 225)
*/
public void test1() {
final GridLayoutManager layoutManager = new GridLayoutManager(1,2, new Insets(0,0,0,0), 0, 0);
final JPanel panel = new JPanel(layoutManager);
final JTextField field1 = new JTextField();
field1.setMinimumSize(new Dimension(110,10));
field1.setPreferredSize(new Dimension(120,10));
final JTextField field2 = new JTextField();
field2.setMinimumSize(new Dimension(215,10));
field2.setPreferredSize(new Dimension(225,10));
panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(345, preferredSize.width);
final Dimension minSize = panel.getMinimumSize();
assertEquals(325, minSize.width);
panel.setSize(preferredSize.width, preferredSize.height);
panel.doLayout();
assertEquals(120, field1.getWidth());
assertEquals(225, field2.getWidth());
panel.setSize(400, panel.getWidth());
panel.invalidate(); // to invalidate layout
panel.doLayout();
}
public void test2() {
final GridLayoutManager layoutManager = new GridLayoutManager(1,3); // min cell size should
layoutManager.setHGap(0);
layoutManager.setVGap(0);
final JPanel panel = new JPanel(layoutManager);
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(100,10));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(200,10));
panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(300 + 20, preferredSize.width);
panel.setSize(preferredSize.width, preferredSize.height);
panel.doLayout();
assertEquals(100, field1.getWidth());
assertEquals(200, field2.getWidth());
panel.setSize(270, preferredSize.height);
panel.doLayout(); // should not fail
}
}
@@ -0,0 +1,154 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
public final class SpansTest extends TestCase{
/**
* button(can grow) | text field (want grow)
* text field (want grow, span 2)
*/
public void test1() {
final GridLayoutManager layout = new GridLayoutManager(2,2, new Insets(0,0,0,0), 0, 0);
final JPanel panel = new JPanel(layout);
final JButton button = new JButton();
button.setPreferredSize(new Dimension(50, 10));
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(50, 10));
final JTextField field2 = new JTextField();
panel.add(button, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field1, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(100, preferredSize.width);
panel.setSize(new Dimension(500, panel.getHeight()));
panel.doLayout();
assertEquals(500, field2.getWidth());
assertEquals(50, button.getWidth());
assertEquals(450, field1.getWidth());
}
/**
* button(can grow) | text field (can grow)
* text field (want grow, span 2)
*/
public void test2() {
final JPanel panel = new JPanel(new GridLayoutManager(2,2, new Insets(0,0,0,0), 0, 0));
final JButton button = new JButton();
button.setPreferredSize(new Dimension(50, 10));
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(50, 10));
final JTextField field2 = new JTextField();
panel.add(button, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field1, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(100, preferredSize.width);
panel.setSize(new Dimension(500, panel.getHeight()));
panel.doLayout();
assertEquals(500, field2.getWidth());
assertEquals(250, button.getWidth());
assertEquals(250, field1.getWidth());
}
/**
* button(can grow) | text field (want grow, span 2)
*/
public void test3() {
final JPanel panel = new JPanel(new GridLayoutManager(1,3, new Insets(0,0,0,0), 0, 0));
final JButton button = new JButton();
button.setPreferredSize(new Dimension(50, 10));
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(110, 10));
panel.add(button, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field1, new GridConstraints(0,1,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
assertEquals(160, preferredSize.width);
panel.setSize(new Dimension(500, panel.getHeight()));
panel.doLayout();
assertEquals(50, button.getWidth());
assertEquals(450, field1.getWidth());
}
/**
* button (can grow, span 2 ) | text field 1 (span 1)
* text field 2 (want grow, span 2) | empty
*/
public void test4() {
final GridLayoutManager layoutManager = new GridLayoutManager(2,3, new Insets(0,0,0,0), 0, 0);
final JPanel panel = new JPanel(layoutManager);
final JButton button = new JButton();
button.setPreferredSize(new Dimension(50, 10));
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(110, 10));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(110, 10));
panel.add(button, new GridConstraints(0,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field1, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
final Dimension preferredSize = panel.getPreferredSize();
// field will be not null after getPreferredSize()
final DimensionInfo horizontalInfo = layoutManager.myHorizontalInfo;
assertEquals(GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_GROW, horizontalInfo.getCellSizePolicy(0));
assertEquals(GridConstraints.SIZEPOLICY_CAN_SHRINK, horizontalInfo.getCellSizePolicy(1));
assertEquals(GridConstraints.SIZEPOLICY_WANT_GROW, horizontalInfo.getCellSizePolicy(2));
assertEquals(220, preferredSize.width);
panel.setSize(new Dimension(500, panel.getHeight()));
panel.doLayout();
assertEquals(250, button.getWidth());
assertEquals(250, field1.getWidth());
assertEquals(250, field2.getWidth());
}
}
@@ -0,0 +1,74 @@
package com.intellij.uiDesigner.core;
import junit.framework.TestCase;
import javax.swing.*;
import java.awt.*;
public final class TextAreasTest extends TestCase{
/**
* label | label
* text area (span 2)
*/
public void test1() {
final JPanel panel = new JPanel(new GridLayoutManager(2,2, new Insets(0,0,0,0), 0, 0));
final JLabel label1 = new JLabel();
label1.setPreferredSize(new Dimension(15,20));
final JLabel label2 = new JLabel();
label2.setPreferredSize(new Dimension(15,20));
final JTextArea textArea = new JTextArea();
textArea.setLineWrap(true);
panel.add(label1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(label2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(textArea, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0));
assertEquals(100, textArea.getPreferredSize().width);
final Dimension initialPreferredSize = panel.getPreferredSize();
assertEquals(new Dimension(100,20 + textArea.getPreferredSize().height), initialPreferredSize);
panel.setSize(initialPreferredSize);
panel.invalidate();
panel.doLayout();
assertEquals(initialPreferredSize, panel.getPreferredSize());
}
/**
* textfield1 | textfield2
* textfield3 (span 2)
*
* important: hspan should be greater than 0
*/
public void test2() {
final JPanel panel = new JPanel(new GridLayoutManager(2,2, new Insets(0,0,0,0), 11, 0));
final JTextField field1 = new JTextField();
field1.setPreferredSize(new Dimension(15,20));
final JTextField field2 = new JTextField();
field2.setPreferredSize(new Dimension(15,20));
final JTextField field3 = new JTextField();
field3.setPreferredSize(new Dimension(100,20));
panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
panel.add(field3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
assertEquals(100, panel.getPreferredSize().width);
}
}