-
28 Jan 2013 8:03 AM #1
Answered: Broken tab layout when hiding and then revealing
Answered: Broken tab layout when hiding and then revealing
Hi everyone. I'm not really sure how to describe my problem concisely without leaving out important stuff, but I'll try.
We're using GWT 2.4, GXT 3.0.3 and UIBinder.
We have a PlainTabPanel with two very similar tabs. At the bottom of those tabs (in some containers) is the following:
<gxt:button>
<button:TextButton ui:field="submitButton" addStyleNames="defaultButton"
text="irrelevant" icon="{resources.someicon}" />
</gxt:button>
Now, when I display the page, the default tab shows properly. But when I switch to the second tab, which has the same layout, configured the same way, in the same containers and so on, the button doesn't show properly.
That's the default tab:
ok.png
That's the other tab:
notok.png
If I inspect the generated markup in firefox, they are extremely similar except for one thing:
These two style attributes are the only relevant changes, and if I correct them manually (to 34 and 463px respectively), I get the intended layout.Code:<div class="GB35TKPICB-com-sencha-gxt-theme-base-client-container-BoxLayoutDefaultAppearance-BoxLayoutStyle-inner" style="width: 588px; height: 10px;"> <div class="GB35TKPB3-com-sencha-gxt-core-client-resources-CommonStyles-CommonStylesDefaultAppearance-CommonDefaultStyles-inlineBlock defaultButton GB35TKPL2-com-sencha-gxt-core-client-resources-CommonStyles-CommonStylesDefaultAppearance-CommonDefaultStyles-floatLeft GB35TKPI3-com-sencha-gxt-core-client-resources-CommonStyles-CommonStylesDefaultAppearance-CommonDefaultStyles-unselectable GB35TKPF3-com-sencha-gxt-core-client-resources-CommonStyles-CommonStylesDefaultAppearance-CommonDefaultStyles-positionable" __gwtcellbasedwidgetimpldispatchingfocus="true" __gwtcellbasedwidgetimpldispatchingblur="true" style="margin: 0px; left: 583px; top: 5px;">
Now at first I thought there was some mystical difference between the two tab layouts. But if I change the configuration of the tabpanel so that it displays the second tab by default, it displays fine, and the first tab is broken when I reveal it. So it doesn't seem to be a problem in the tabs themselves, but in how they are handled by the tab panel ?
It seems that the layout gets broken when a tab is hidden and then revealed, but I cannot find any way to fix the problem. I hope someone will know what to do.
Thanks in advance !
Thomas.Last edited by tgi; 28 Jan 2013 at 8:03 AM. Reason: made code block clearer
-
Best Answer Posted by Colin Alworth
I'm unable to reproduce this in a simple example - maybe you can provide some code, either by modifying this example to make it more complex, or by breaking down your own code with the bug:
Test.ui.xml:
Test.java:Code:<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:gxt="urn:import:com.sencha.gxt.widget.core.client" xmlns:button="urn:import:com.sencha.gxt.widget.core.client.button" xmlns:container="urn:import:com.sencha.gxt.widget.core.client.container"> <ui:with type="com.sencha.gxt.widget.core.client.TabItemConfig" field="shortTextTabConfig"> <ui:attributes text="Short Text" /> </ui:with> <gxt:PlainTabPanel> <gxt:child config="{shortTextTabConfig}"> <gxt:ContentPanel headingText="A content panel"> <gxt:button> <button:TextButton>A button</button:TextButton> </gxt:button> </gxt:ContentPanel> </gxt:child> <gxt:child config="{shortTextTabConfig}"> <gxt:ContentPanel headingText="B content panel"> <gxt:button> <button:TextButton>B button</button:TextButton> </gxt:button> </gxt:ContentPanel> </gxt:child> </gxt:PlainTabPanel> </ui:UiBinder>
The most likely culprit I can come up with here is that you are invoking forceLayout() on something which is currently invisible - this makes it try to re-render, but since it isn't visible, measured sizes are incorrect. One fix is to not call forceLayout() until it is visible - another would be to tell the contents of the tab to hide itself using offsets so that it is still rendered and sizes will be correct - but the page will be more expensive to render. This can be configured by invoking setHideMode(HideMode.OFFSETS) on the item being hidden (in this case, probably a ContentPanel).Code:package com.sencha.gxt.examples.test.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; import com.sencha.gxt.widget.core.client.container.Viewport; public class Test implements EntryPoint { interface Binder extends UiBinder<Widget, Test> {} private static final Binder binder = GWT.create(Binder.class); public void onModuleLoad() { Widget panel = binder.createAndBindUi(this); Viewport vp = new Viewport(); vp.setWidget(panel); RootPanel.get().add(vp); } }
-
28 Jan 2013 4:50 PM #2
I'm unable to reproduce this in a simple example - maybe you can provide some code, either by modifying this example to make it more complex, or by breaking down your own code with the bug:
Test.ui.xml:
Test.java:Code:<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:gxt="urn:import:com.sencha.gxt.widget.core.client" xmlns:button="urn:import:com.sencha.gxt.widget.core.client.button" xmlns:container="urn:import:com.sencha.gxt.widget.core.client.container"> <ui:with type="com.sencha.gxt.widget.core.client.TabItemConfig" field="shortTextTabConfig"> <ui:attributes text="Short Text" /> </ui:with> <gxt:PlainTabPanel> <gxt:child config="{shortTextTabConfig}"> <gxt:ContentPanel headingText="A content panel"> <gxt:button> <button:TextButton>A button</button:TextButton> </gxt:button> </gxt:ContentPanel> </gxt:child> <gxt:child config="{shortTextTabConfig}"> <gxt:ContentPanel headingText="B content panel"> <gxt:button> <button:TextButton>B button</button:TextButton> </gxt:button> </gxt:ContentPanel> </gxt:child> </gxt:PlainTabPanel> </ui:UiBinder>
The most likely culprit I can come up with here is that you are invoking forceLayout() on something which is currently invisible - this makes it try to re-render, but since it isn't visible, measured sizes are incorrect. One fix is to not call forceLayout() until it is visible - another would be to tell the contents of the tab to hide itself using offsets so that it is still rendered and sizes will be correct - but the page will be more expensive to render. This can be configured by invoking setHideMode(HideMode.OFFSETS) on the item being hidden (in this case, probably a ContentPanel).Code:package com.sencha.gxt.examples.test.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; import com.sencha.gxt.widget.core.client.container.Viewport; public class Test implements EntryPoint { interface Binder extends UiBinder<Widget, Test> {} private static final Binder binder = GWT.create(Binder.class); public void onModuleLoad() { Widget panel = binder.createAndBindUi(this); Viewport vp = new Viewport(); vp.setWidget(panel); RootPanel.get().add(vp); } }
-
29 Jan 2013 12:51 AM #3


Reply With Quote