From 69c24adddec9f6b0c73558304e24ba628ee85e1a Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Thu, 2 Feb 2012 22:16:28 +0400 Subject: [PATCH] IDEA-37522 --- .../uiDesigner/compiler/AsmCodeGenerator.java | 2 +- .../compiler/CardLayoutCodeGenerator.java | 53 ++++++++++++ .../compiler/SimpleLayoutCodeGenerator.java | 2 +- .../uiDesigner/lw/CardLayoutSerializer.java | 3 + .../uiDesigner/UIFormXmlConstants.java | 1 + .../com/intellij/uiDesigner/XmlReader.java | 6 +- .../editors/ComponentEditor.java | 2 +- .../radComponents/RadCardLayoutManager.java | 83 ++++++++++++++++++- .../radComponents/RadLayoutManager.java | 4 + plugins/ui-designer/testData/BindingTest.java | 2 + .../ui-designer/testData/TestCardLayout.form | 20 +++++ .../testData/TestCardLayoutShow.form | 26 ++++++ .../uiDesigner/core/AsmCodeGeneratorTest.java | 16 ++++ 13 files changed, 213 insertions(+), 7 deletions(-) create mode 100644 java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CardLayoutCodeGenerator.java create mode 100644 plugins/ui-designer/testData/TestCardLayout.form create mode 100644 plugins/ui-designer/testData/TestCardLayoutShow.form diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java index 5ba3fd521c01..b7a344dcf74e 100644 --- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java +++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java @@ -75,7 +75,7 @@ public class AsmCodeGenerator { 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_CARD, new CardLayoutCodeGenerator()); myContainerLayoutCodeGenerators.put(UIFormXmlConstants.LAYOUT_FLOW, new FlowLayoutCodeGenerator()); myComponentLayoutCodeGenerators.put(LwSplitPane.class, new SplitPaneLayoutCodeGenerator()); diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CardLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CardLayoutCodeGenerator.java new file mode 100644 index 000000000000..8db3a8b89eca --- /dev/null +++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CardLayoutCodeGenerator.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2012 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.LwComponent; +import org.objectweb.asm.Type; +import org.objectweb.asm.commons.GeneratorAdapter; +import org.objectweb.asm.commons.Method; + +import java.awt.*; + +/** + * @author Alexander Lobas + */ +public class CardLayoutCodeGenerator extends SimpleLayoutCodeGenerator { + private static final Method ourGetLayoutMethod = Method.getMethod("java.awt.LayoutManager getLayout()"); + private static final Method ourShowMethod = Method.getMethod("void show(java.awt.Container,java.lang.String)"); + + public CardLayoutCodeGenerator() { + super(Type.getType(CardLayout.class)); + } + + public void generateComponentLayout(LwComponent lwComponent, + GeneratorAdapter generator, + int componentLocal, + int parentLocal) { + super.generateComponentLayout(lwComponent, generator, componentLocal, parentLocal); + + String defaultCard = (String)lwComponent.getParent().getClientProperty(UIFormXmlConstants.LAYOUT_CARD); + if (lwComponent.getId().equals(defaultCard)) { + generator.loadLocal(parentLocal); + generator.invokeVirtual(ourContainerType, ourGetLayoutMethod); + generator.checkCast(myLayoutType); + generator.loadLocal(parentLocal); + generator.push((String) lwComponent.getCustomLayoutConstraints()); + generator.invokeVirtual(myLayoutType, ourShowMethod); + } + } +} \ No newline at end of file diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SimpleLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SimpleLayoutCodeGenerator.java index 30c70f7dc7bc..c1456e668b91 100644 --- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SimpleLayoutCodeGenerator.java +++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SimpleLayoutCodeGenerator.java @@ -28,7 +28,7 @@ import org.objectweb.asm.commons.Method; * @author yole */ public class SimpleLayoutCodeGenerator extends LayoutCodeGenerator { - private final Type myLayoutType; + protected final Type myLayoutType; private static final Method ourConstructor = Method.getMethod("void (int,int)"); public SimpleLayoutCodeGenerator(final Type layoutType) { diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/CardLayoutSerializer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/CardLayoutSerializer.java index bd38f2fc1823..9371b5c9906d 100644 --- a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/CardLayoutSerializer.java +++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/CardLayoutSerializer.java @@ -34,6 +34,9 @@ public class CardLayoutSerializer extends LayoutSerializer { 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)); + + String defaultCard = LwXmlReader.getOptionalString(element, UIFormXmlConstants.ATTRIBUTE_SHOW, null); + container.putClientProperty(UIFormXmlConstants.LAYOUT_CARD, defaultCard); } void readChildConstraints(final Element constraintsElement, final LwComponent component) { diff --git a/platform/forms_rt/src/com/intellij/uiDesigner/UIFormXmlConstants.java b/platform/forms_rt/src/com/intellij/uiDesigner/UIFormXmlConstants.java index f5ee1cd6afed..c5f6c0309e87 100644 --- a/platform/forms_rt/src/com/intellij/uiDesigner/UIFormXmlConstants.java +++ b/platform/forms_rt/src/com/intellij/uiDesigner/UIFormXmlConstants.java @@ -45,6 +45,7 @@ public class UIFormXmlConstants { public static final String ATTRIBUTE_SAME_SIZE_HORIZONTALLY = "same-size-horizontally"; public static final String ATTRIBUTE_SAME_SIZE_VERTICALLY = "same-size-vertically"; public static final String ATTRIBUTE_USE_PARENT_LAYOUT = "use-parent-layout"; + public static final String ATTRIBUTE_SHOW = "show"; public static final String ATTRIBUTE_HGAP = "hgap"; public static final String ATTRIBUTE_VGAP = "vgap"; public static final String ATTRIBUTE_BORDER_CONSTRAINT = "border-constraint"; diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/XmlReader.java b/plugins/ui-designer/src/com/intellij/uiDesigner/XmlReader.java index e30542fd3c9f..9170490fa324 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/XmlReader.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/XmlReader.java @@ -165,7 +165,11 @@ public final class XmlReader { layoutManagerName = UIFormXmlConstants.LAYOUT_INTELLIJ; } } - ((RadContainer) component).setLayoutManager(LayoutManagerRegistry.createLayoutManager(layoutManagerName)); + + RadLayoutManager layoutManager = LayoutManagerRegistry.createLayoutManager(layoutManagerName); + RadContainer container = (RadContainer)component; + layoutManager.readLayout(lwContainer, container); + container.setLayoutManager(layoutManager); } ((RadContainer)component).setLayout(layout); } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/editors/ComponentEditor.java b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/editors/ComponentEditor.java index 41cb6b8e2cbd..9f3040bec705 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/editors/ComponentEditor.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/propertyInspector/editors/ComponentEditor.java @@ -59,7 +59,7 @@ public class ComponentEditor extends ComboBoxPropertyEditor { return myCbx; } - private RadComponent[] collectFilteredComponents(final RadComponent component) { + protected RadComponent[] collectFilteredComponents(final RadComponent component) { final ArrayList result = new ArrayList(); result.add(null); diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/radComponents/RadCardLayoutManager.java b/plugins/ui-designer/src/com/intellij/uiDesigner/radComponents/RadCardLayoutManager.java index 6569d04da758..02a18b4208f4 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/radComponents/RadCardLayoutManager.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/radComponents/RadCardLayoutManager.java @@ -17,6 +17,7 @@ package com.intellij.uiDesigner.radComponents; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.uiDesigner.UIDesignerBundle; import com.intellij.uiDesigner.UIFormXmlConstants; import com.intellij.uiDesigner.XmlWriter; @@ -25,12 +26,15 @@ import com.intellij.uiDesigner.designSurface.ComponentDragObject; import com.intellij.uiDesigner.designSurface.ComponentDropLocation; import com.intellij.uiDesigner.designSurface.FeedbackLayer; import com.intellij.uiDesigner.designSurface.GuiEditor; +import com.intellij.uiDesigner.lw.LwContainer; import com.intellij.uiDesigner.propertyInspector.Property; import com.intellij.uiDesigner.propertyInspector.PropertyEditor; import com.intellij.uiDesigner.propertyInspector.PropertyRenderer; import com.intellij.uiDesigner.propertyInspector.editors.AbstractTextFieldEditor; +import com.intellij.uiDesigner.propertyInspector.editors.ComponentEditor; import com.intellij.uiDesigner.propertyInspector.properties.HGapProperty; import com.intellij.uiDesigner.propertyInspector.properties.VGapProperty; +import com.intellij.uiDesigner.propertyInspector.renderers.ComponentRenderer; import com.intellij.uiDesigner.propertyInspector.renderers.LabelPropertyRenderer; import com.intellij.uiDesigner.snapShooter.SnapshotContext; import com.intellij.util.IncorrectOperationException; @@ -61,6 +65,12 @@ public class RadCardLayoutManager extends RadLayoutManager { return new CardLayout(); } + @Override + public void readLayout(LwContainer lwContainer, RadContainer radContainer) throws Exception { + String defaultCard = (String)lwContainer.getClientProperty(UIFormXmlConstants.LAYOUT_CARD); + DefaultCardProperty.INSTANCE.setValue(radContainer, defaultCard); + } + public void writeChildConstraints(final XmlWriter writer, final RadComponent child) { writer.startElement(UIFormXmlConstants.ELEMENT_CARD); try { @@ -74,14 +84,28 @@ public class RadCardLayoutManager extends RadLayoutManager { @Override public void writeLayout(final XmlWriter writer, final RadContainer radContainer) { CardLayout layout = (CardLayout) radContainer.getLayout(); + writer.addAttribute(UIFormXmlConstants.ATTRIBUTE_HGAP, layout.getHgap()); writer.addAttribute(UIFormXmlConstants.ATTRIBUTE_VGAP, layout.getVgap()); + + String defaultCard = DefaultCardProperty.INSTANCE.getValue(radContainer); + if (!StringUtil.isEmpty(defaultCard)) { + writer.addAttribute(UIFormXmlConstants.ATTRIBUTE_SHOW, defaultCard); + } } public void addComponentToContainer(final RadContainer container, final RadComponent component, final int index) { container.getDelegee().add(component.getDelegee(), component.getCustomLayoutConstraints()); } + @Override + public void removeComponentFromContainer(RadContainer container, RadComponent component) { + if (component.getId().equals(DefaultCardProperty.INSTANCE.getValue(container))) { + DefaultCardProperty.INSTANCE.setValueEx(container, null); + } + super.removeComponentFromContainer(container, component); + } + @Override public void changeContainerLayout(RadContainer container) throws IncorrectOperationException { if (container.getComponentCount() != 0) { throw new IncorrectOperationException("Only empty containers can be changed to CardLayout"); @@ -96,9 +120,10 @@ public class RadCardLayoutManager extends RadLayoutManager { @Override public Property[] getContainerProperties(final Project project) { - return new Property[] { + return new Property[]{ HGapProperty.getInstance(project), - VGapProperty.getInstance(project) }; + VGapProperty.getInstance(project), + DefaultCardProperty.INSTANCE }; } @Override @@ -255,4 +280,56 @@ public class RadCardLayoutManager extends RadLayoutManager { return selection.size() == 1; } } -} + + private static class DefaultCardProperty extends Property { + @NonNls private static final String NAME = "Default Card"; + + private final ComponentRenderer myRenderer = new ComponentRenderer(); + private ComponentEditor myEditor; + + static DefaultCardProperty INSTANCE = new DefaultCardProperty(); + + public DefaultCardProperty() { + super(null, NAME); + } + + @NotNull + @Override + public PropertyRenderer getRenderer() { + return myRenderer; + } + + @Override + public PropertyEditor getEditor() { + if (myEditor == null) { + myEditor = new ComponentEditor(null, null) { + @Override + protected RadComponent[] collectFilteredComponents(RadComponent component) { + RadContainer container = (RadContainer)component; + RadComponent[] result = new RadComponent[container.getComponentCount() + 1]; + for (int i = 1; i < result.length; i++) { + result[i] = container.getComponent(i - 1); + } + return result; + } + }; + } + return myEditor; + } + + @Override + public String getValue(RadContainer component) { + return (String)component.getDelegee().getClientProperty(NAME); + } + + @Override + protected void setValueImpl(RadContainer component, String value) throws Exception { + component.getDelegee().putClientProperty(NAME, StringUtil.isEmpty(value) ? null : value); + } + + @Override + public boolean appliesToSelection(List selection) { + return selection.size() == 1; + } + } +} \ No newline at end of file diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/radComponents/RadLayoutManager.java b/plugins/ui-designer/src/com/intellij/uiDesigner/radComponents/RadLayoutManager.java index c89a2bd9e7e6..a1f185cfa69c 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/radComponents/RadLayoutManager.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/radComponents/RadLayoutManager.java @@ -23,6 +23,7 @@ import com.intellij.uiDesigner.inspections.FormInspectionUtil; import com.intellij.uiDesigner.lw.IProperty; import com.intellij.uiDesigner.designSurface.ComponentDropLocation; import com.intellij.uiDesigner.designSurface.NoDropLocation; +import com.intellij.uiDesigner.lw.LwContainer; import com.intellij.uiDesigner.propertyInspector.Property; import com.intellij.uiDesigner.snapShooter.SnapshotContext; import com.intellij.util.IncorrectOperationException; @@ -52,6 +53,9 @@ public abstract class RadLayoutManager { return null; } + public void readLayout(LwContainer lwContainer, RadContainer radContainer) throws Exception { + } + public void changeContainerLayout(RadContainer container) throws IncorrectOperationException { ensureChildrenVisible(container); container.setLayoutManager(this); diff --git a/plugins/ui-designer/testData/BindingTest.java b/plugins/ui-designer/testData/BindingTest.java index 181687d6ad16..e1fcbfeb0694 100644 --- a/plugins/ui-designer/testData/BindingTest.java +++ b/plugins/ui-designer/testData/BindingTest.java @@ -21,6 +21,8 @@ public class BindingTest { public final JComponent myFinalField = null; public int myIntField; public String myStringField; + public JButton button; + public JTextField textField; public BindingTest() { } diff --git a/plugins/ui-designer/testData/TestCardLayout.form b/plugins/ui-designer/testData/TestCardLayout.form new file mode 100644 index 000000000000..b80bc66e4c66 --- /dev/null +++ b/plugins/ui-designer/testData/TestCardLayout.form @@ -0,0 +1,20 @@ + +
+ + + + + + + + + + + + + + + + + +
diff --git a/plugins/ui-designer/testData/TestCardLayoutShow.form b/plugins/ui-designer/testData/TestCardLayoutShow.form new file mode 100644 index 000000000000..0e4b0b75aeab --- /dev/null +++ b/plugins/ui-designer/testData/TestCardLayoutShow.form @@ -0,0 +1,26 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/plugins/ui-designer/testSrc/com/intellij/uiDesigner/core/AsmCodeGeneratorTest.java b/plugins/ui-designer/testSrc/com/intellij/uiDesigner/core/AsmCodeGeneratorTest.java index a99f7dac1175..3bc39bccc584 100644 --- a/plugins/ui-designer/testSrc/com/intellij/uiDesigner/core/AsmCodeGeneratorTest.java +++ b/plugins/ui-designer/testSrc/com/intellij/uiDesigner/core/AsmCodeGeneratorTest.java @@ -174,6 +174,22 @@ public class AsmCodeGeneratorTest extends TestCase { assertEquals(1, gridLayout.getColumnCount()); } + public void testCardLayout() throws Exception { + JComponent rootComponent = getInstrumentedRootComponent("TestCardLayout.form", "BindingTest"); + assertTrue(rootComponent.getLayout() instanceof CardLayout); + CardLayout cardLayout = (CardLayout) rootComponent.getLayout(); + assertEquals(10, cardLayout.getHgap()); + assertEquals(20, cardLayout.getVgap()); + } + + public void testCardLayoutShow() throws Exception { + JComponent rootComponent = getInstrumentedRootComponent("TestCardLayoutShow.form", "BindingTest"); + assertTrue(rootComponent.getLayout() instanceof CardLayout); + assertEquals(rootComponent.getComponentCount(), 2); + assertFalse(rootComponent.getComponent(0).isVisible()); + assertTrue(rootComponent.getComponent(1).isVisible()); + } + public void testGridConstraints() throws Exception { JComponent rootComponent = getInstrumentedRootComponent("TestGridConstraints.form", "BindingTest"); assertEquals(1, rootComponent.getComponentCount());