PDA

View Full Version : [FNR] Problem adding components with margin data to CardLayout



pgleb
28 Dec 2010, 8:18 AM
[GXT 2.2.1, FF3.6, Windows, DevMode]

Hi,

the problem can be easily reproduced using CardLayoutExample from GXT Showcase if the components are added to CardLayout with some margin data (instead of simply panel.add(c) ).

public class CardLayoutExample extends LayoutContainer {

@Override
protected void onRender(Element parent, int index) {
super.onRender(parent, index);
setStyleAttribute("margin", "10px");

ContentPanel panel = new ContentPanel();
panel.setSize(400, 100);
panel.setFrame(true);
panel.setHeading("CardLayout Example");
panel.setButtonAlign(HorizontalAlignment.CENTER);

final CardLayout layout = new CardLayout();
panel.setLayout(layout);

for (int i = 0; i < 4; i++) {
final LayoutContainer c = new LayoutContainer();
c.addText("This is the contents for card: " + (i + 1));
panel.add(c, new MarginData());
panel.addButton(new Button("Card " + (i + 1), new SelectionListener<ButtonEvent>() {
@Override
public void componentSelected(ButtonEvent ce) {
layout.setActiveItem(c);
}
}));
}

layout.setActiveItem(panel.getItem(0));

add(panel);
}

}

In this case the following exception happens
java.lang.AssertionError: Method must be called after the component is rendered
at com.extjs.gxt.ui.client.widget.Component.assertAfterRender(Component.java:1483)
at com.extjs.gxt.ui.client.widget.Component.el(Component.java:403)
at com.extjs.gxt.ui.client.widget.Layout.onLayout(Layout.java:323)
at com.extjs.gxt.ui.client.widget.layout.FitLayout.onLayout(FitLayout.java:58)
at com.extjs.gxt.ui.client.widget.Layout.layout(Layout.java:114)
at com.extjs.gxt.ui.client.widget.Layout$3.handleEvent(Layout.java:170)
at com.extjs.gxt.ui.client.util.DelayedTask$1.run(DelayedTask.java:30)
at com.extjs.gxt.ui.client.util.DelayedTask.delay(DelayedTask.java:52)
at com.extjs.gxt.ui.client.widget.Layout.onResize(Layout.java:344)
at com.extjs.gxt.ui.client.widget.Layout$2.handleEvent(Layout.java:135)
at com.extjs.gxt.ui.client.widget.Layout$2.handleEvent(Layout.java:1)
at com.extjs.gxt.ui.client.event.BaseObservable.callListener(BaseObservable.java:178)
at com.extjs.gxt.ui.client.event.BaseObservable.fireEvent(BaseObservable.java:86)
at com.extjs.gxt.ui.client.widget.Component.fireEvent(Component.java:454)
at com.extjs.gxt.ui.client.widget.BoxComponent.setSize(BoxComponent.java:522)
at com.extjs.gxt.ui.client.widget.BoxComponent.setSize(BoxComponent.java:559)
at com.extjs.gxt.ui.client.widget.BoxComponent.afterRender(BoxComponent.java:685)
at com.extjs.gxt.ui.client.widget.ScrollContainer.afterRender(ScrollContainer.java:199)
at com.extjs.gxt.ui.client.widget.Component.render(Component.java:1091)
at com.extjs.gxt.ui.client.widget.Layout.renderComponent(Layout.java:361)
at com.extjs.gxt.ui.client.widget.layout.FlowLayout.renderComponent(FlowLayout.java:110)
at com.extjs.gxt.ui.client.widget.Layout.renderAll(Layout.java:352)
at com.extjs.gxt.ui.client.widget.Layout.onLayout(Layout.java:318)
at com.extjs.gxt.ui.client.widget.layout.FlowLayout.onLayout(FlowLayout.java:102)
at com.extjs.gxt.ui.client.widget.Layout.layout(Layout.java:114)
at com.extjs.gxt.ui.client.widget.Container.doLayout(Container.java:351)
at com.extjs.gxt.ui.client.widget.Container.layout(Container.java:443)
at com.extjs.gxt.ui.client.widget.LayoutContainer.layout(LayoutContainer.java:246)
at com.extjs.gxt.ui.client.widget.Container.layout(Container.java:426)
at com.extjs.gxt.ui.client.widget.LayoutContainer.layout(LayoutContainer.java:241)
at com.extjs.gxt.ui.client.widget.Container.onAttach(Container.java:476)
...

After debugging it seems that the problem is caused by the onLayout method (in Layout.java).

protected void onLayout(Container<?> container, El target) {
renderAll(container, target);
for (Component component : container.getItems()) {
LayoutData data = getLayoutData(component);
if (data != null && data instanceof MarginData) {
MarginData ld = (MarginData) data;
applyMargins(component.el(), ld.getMargins());
}
}
}

If there is some margin data, applyMargins is called even for non-active non-rendered components in CardLaoyut. Clearly, all this happens only with a default setting of deferredRender to "true".

sven
28 Dec 2010, 8:24 AM
Fixed in SVN as of revision 2351