IDEA-37522

This commit is contained in:
Alexander Lobas
2012-02-02 22:16:28 +04:00
parent 52efa194da
commit 69c24addde
13 changed files with 213 additions and 7 deletions

View File

@@ -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());

View File

@@ -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);
}
}
}

View File

@@ -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 <init>(int,int)");
public SimpleLayoutCodeGenerator(final Type layoutType) {

View File

@@ -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) {

View File

@@ -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";

View File

@@ -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);
}

View File

@@ -59,7 +59,7 @@ public class ComponentEditor extends ComboBoxPropertyEditor<String> {
return myCbx;
}
private RadComponent[] collectFilteredComponents(final RadComponent component) {
protected RadComponent[] collectFilteredComponents(final RadComponent component) {
final ArrayList<RadComponent> result = new ArrayList<RadComponent>();
result.add(null);

View File

@@ -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<RadContainer, String> {
@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<String> getRenderer() {
return myRenderer;
}
@Override
public PropertyEditor<String> 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<RadComponent> selection) {
return selection.size() == 1;
}
}
}

View File

@@ -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);

View File

@@ -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() {
}

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="BindingTest">
<grid id="27dc6" binding="myRootComponent" layout-manager="CardLayout" hgap="10" vgap="20">
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="d8b1" class="javax.swing.JButton" binding="button" default-binding="true">
<constraints>
<card name="Card1"/>
</constraints>
<properties>
<text value="Button"/>
</properties>
</component>
</children>
</grid>
</form>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="BindingTest">
<grid id="27dc6" binding="myRootComponent" layout-manager="CardLayout" hgap="0" vgap="0" show="77d5d">
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="d8b1" class="javax.swing.JButton" binding="button" default-binding="true">
<constraints>
<card name="Card1"/>
</constraints>
<properties>
<text value="Button"/>
</properties>
</component>
<component id="77d5d" class="javax.swing.JTextField" binding="textField" default-binding="true">
<constraints>
<card name="Card2"/>
</constraints>
<properties/>
</component>
</children>
</grid>
</form>

View File

@@ -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());