PDA

View Full Version : strange behaviors of the method WidgetContainer.removeAll () from a ContentPanel



dbettoni
6 May 2008, 3:09 AM
For now I am using still MyGWT 0.5.2.

See at http://dbj.it/it.dbj.mygwt.RemoveAllAndLayoutProblem/Main.html
it is a running version of the attached code at the end of this page.

Operation explain:

1) when you push "set content" button the method MyContentPanel.setContent() is called


private static class MyContentPanel extends ContentPanel {
.....
private boolean forceLayout=true;
private int n;
.....
void setContent(){
removeAll();

VerticalPanel vp = new VerticalPanel();
vp.add(new Label("content "+ (n++) ));
add(vp);

if(forceLayout) layout(true);
setText("Collapsible (getWidgetCount()="+getWidgetCount()+")");
}
.....
.....
2) when you push "toggle layout" button the field MyContentPanel.forceLayout
is toggled and if it was false the method layout(true) is called.


private static class MyContentPanel extends ContentPanel {
.....
void toggleLayout(){

if( !forceLayout ){
layout(true);
}

forceLayout = !forceLayout;
}

....

3) when you push "clean container" button the method removeAll() is called on the external container.

Correct run: :)
to the beginning MyContentPanel.forceLayout is true.
If you push "set content" button, the content of panel changes correctly.
If you push "clean container" button the external container is cleaned correctly.

Abnormal run: :-/

1) try to set the "toggle layout" button to off, and click "set content" button more than once.
result: the panel is partially closed and the removeAll() has failed.

2) now try to open the panel (twice click on button in the header of panel)
result: look at the panel, the content is displayed more that one.

3) now you close the panel (one click on button in the header of panel),
you do one or more click "set content" button,
now you click "clean container".
result: the "java.lang.IllegalStateException: Should only call onDetach when the widget is attached to the browser's document exception" has been throws.



java.lang.IllegalStateException: Should only call onDetach when the widget is attached to the browser's document
at com.google.gwt.user.client.ui.Widget.onDetach(Widget.java:138)
at com.google.gwt.user.client.ui.WidgetHelper.doDetach(WidgetHelper.java:20)
at net.mygwt.ui.client.widget.Container.doDetachChildren(Container.java:175)
at net.mygwt.ui.client.widget.ContentPanel.doDetachChildren(ContentPanel.java:423)
at com.google.gwt.user.client.ui.Widget.onDetach(Widget.java:148)
at net.mygwt.ui.client.widget.Component.onDetach(Component.java:1014)
at com.google.gwt.user.client.ui.Panel.doDetachChildren(Panel.java:170)
at com.google.gwt.user.client.ui.Widget.onDetach(Widget.java:148)
at com.google.gwt.user.client.ui.Widget.setParent(Widget.java:229)
at com.google.gwt.user.client.ui.WidgetHelper.setParent(WidgetHelper.java:24)
at net.mygwt.ui.client.widget.Container.orphan(Container.java:182)
at net.mygwt.ui.client.widget.Container.remove(Container.java:125)
at net.mygwt.ui.client.widget.WidgetContainer.remove(WidgetContainer.java:256)
at net.mygwt.ui.client.widget.WidgetContainer.removeAll(WidgetContainer.java:274)
at it.dbj.mygwt.client.RemoveAllAndLayoutProblem$4.widgetSelected(RemoveAllAndLayoutProblem.java:99)
at net.mygwt.ui.client.event.TypedListener.handleEvent(TypedListener.java:74)
at net.mygwt.ui.client.util.EventTable.sendEvent(EventTable.java:84)
at net.mygwt.ui.client.util.Observable.fireEvent(Observable.java:78)
at net.mygwt.ui.client.widget.Component.fireEvent(Component.java:329)
at net.mygwt.ui.client.widget.Component.fireEvent(Component.java:318)
at net.mygwt.ui.client.widget.Button.onClick(Button.java:159)
at net.mygwt.ui.client.widget.Item.onBaseEvent(Item.java:189)
at net.mygwt.ui.client.widget.Component.onBrowserEvent(Component.java:595)
at com.google.gwt.user.client.DOM.dispatchEventImpl(DOM.java:1265)
at com.google.gwt.user.client.DOM.dispatchEventAndCatch(DOM.java:1244)
at com.google.gwt.user.client.DOM.dispatchEvent(DOM.java:1211)
at sun.reflect.GeneratedMethodAccessor28.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.google.gwt.dev.shell.ie.IDispatchImpl.callMethod(IDispatchImpl.java:126)
at com.google.gwt.dev.shell.ie.IDispatchProxy.invoke(IDispatchProxy.java:150)
at com.google.gwt.dev.shell.ie.IDispatchImpl.Invoke(IDispatchImpl.java:293)
at com.google.gwt.dev.shell.ie.IDispatchImpl.method6(IDispatchImpl.java:196)
at org.eclipse.swt.internal.ole.win32.COMObject.callback6(COMObject.java:117)
at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method)
at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:1925)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2966)
at com.google.gwt.dev.GWTShell.pumpEventLoop(GWTShell.java:689)
at com.google.gwt.dev.GWTShell.run(GWTShell.java:550)
at com.google.gwt.dev.GWTShell.main(GWTShell.java:321)


Question: :-?

thing thought of it you?
is it a misuse of the library or a bug on method WidgetContainer.removeAll() ?



Complete test code:



package it.dbj.mygwt.client;


import net.mygwt.ui.client.Style;
import net.mygwt.ui.client.event.BaseEvent;
import net.mygwt.ui.client.event.SelectionListener;
import net.mygwt.ui.client.widget.Button;
import net.mygwt.ui.client.widget.ContentPanel;
import net.mygwt.ui.client.widget.LoadingPanel;
import net.mygwt.ui.client.widget.Shell;
import net.mygwt.ui.client.widget.ToolItem;
import net.mygwt.ui.client.widget.WidgetContainer;
import net.mygwt.ui.client.widget.layout.FlowLayout;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;


public class RemoveAllAndLayoutProblem implements EntryPoint {

public void onModuleLoad() {
LoadingPanel.get().show("Loading RemoveAllAndLayoutProblem test ...");
RootPanel.get().add( createWidget() );
LoadingPanel.get().hide();

GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler(){

public void onUncaughtException(Throwable e) {
e.printStackTrace(System.out);
Shell sh = new Shell(Style.CLOSE);
sh.setText("onUncaughtException");
WidgetContainer content = sh.getContent();
content.setLayout(new FlowLayout());
content.setScrollEnabled(true);
content.addText(e.getMessage());
sh.open();

throw new RuntimeException(e);
}

});
}

private Widget createWidget() {

final WidgetContainer container = new WidgetContainer();
container.setScrollEnabled(true);
container.setSize(700, 300);
container.setLayout(new FlowLayout());
container.setScrollEnabled(true);

final MyContentPanel cp = new MyContentPanel();
final HorizontalPanel hp = new HorizontalPanel();
hp.setSpacing(10);

cp.setWidth(400);
cp.setText("Collapsible");
hp.add(cp);


final VerticalPanel vp = new VerticalPanel();

ToolItem item = new ToolItem(Style.TOGGLE);
item.setText("toggle layout");
item.setSelected(true);
item.addSelectionListener(new SelectionListener(){
public void widgetSelected(BaseEvent be) {
cp.toggleLayout();
}
});
vp.add(item);


Button bt = new Button(
"set content",
new SelectionListener(){
public void widgetSelected(BaseEvent be) {
cp.setContent();
}
}
);
vp.add(bt);


bt = new Button(
"clean container",
new SelectionListener(){
public void widgetSelected(BaseEvent be) {
container.removeAll();
}
}
);
vp.add(bt);




hp.add(vp);
cp.setContent();
container.add(hp);
return container;
}


private static class MyContentPanel extends ContentPanel {

private boolean forceLayout=true;
private int n;

public MyContentPanel() {
super(Style.HEADER | Style.COLLAPSE, "my-cpanel-small");
}

void setContent(){

removeAll();


VerticalPanel vp = new VerticalPanel();
vp.add(new Label("content "+ (n++) ));
add(vp);
if(forceLayout) layout(true);

setText("Collapsible (getWidgetCount()="+getWidgetCount()+")");

}

void toggleLayout(){

if( !forceLayout ){
layout(true);
}

forceLayout = !forceLayout;
}
}


}

gslender
6 May 2008, 3:52 AM
This forum is for Ext GWT - myGWT is no longer supported.

dbettoni
6 May 2008, 4:41 AM
The answer is not very kind since Ext GWT is the son only a few days MyGWT.
If I can bring the testing ExtGWT I hope to have a better answer.

gslender
6 May 2008, 5:08 AM
since Ext GWT is the son only a few days MyGWT

even so, this forum and site is for ExtGWT, not myGWT - most of the users (if not all) here are using ExtGWT and no longer focus on myGWT bugs and/or issues.

dbettoni
6 May 2008, 5:19 AM
pity that the mygwt forum has become read-only

dbettoni
15 May 2008, 1:52 AM
ok I completed the code porting (see code after) from the previous mygwt to gxt.
I'm happy :) because the failures encountered on mygwt in gxt have disappeared.

I've only a question.
After a removeAll() and repopulating contaniner, must always call a layout(true) to redraw everything?



package it.dbj.gxt.client;


import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.Button;
import com.extjs.gxt.ui.client.widget.Container;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.ToggleButton;
import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
* see at
* http://extjs.com/forum/showthread.php?t=34726
*/
public class RemoveAllAndLayoutProblem implements EntryPoint {


public void onModuleLoad() {

MessageBox loading = MessageBox.wait("", "Loading RemoveAllAndLayoutProblem test ...", "");
RootPanel.get().add( createWidget() );
loading.hide();

GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler(){

public void onUncaughtException(Throwable e) {
e.printStackTrace(System.out);
Dialog d = new Dialog();
d.setHeading("onUncaughtException");
d.setLayout(new FlowLayout());
d.addText(e.getMessage());
d.show();

throw new RuntimeException(e);
}

});
}

private Widget createWidget() {

final Container container = new Container();
//container.setScrollEnabled(true);
container.setSize(700, 300);
container.setLayout(new FlowLayout());
//container.setScrollEnabled(true);

final MyContentPanel cp = new MyContentPanel();
final HorizontalPanel hp = new HorizontalPanel();
hp.setSpacing(10);

cp.setWidth(400);
cp.setHeading("Collapsible");
hp.add(cp);


final VerticalPanel vp = new VerticalPanel();

ToggleButton tb = new ToggleButton("toggle layout");
tb.toggle(true);
tb.addSelectionListener(new SelectionListener(){
public void componentSelected(ComponentEvent ce) {
cp.toggleLayout();
}
});
vp.add(tb);


Button bt = new Button(
"set content",
new SelectionListener(){
public void componentSelected(ComponentEvent ce) {
cp.setContent();

}
}
);
vp.add(bt);


bt = new Button(
"clean container",
new SelectionListener(){
public void componentSelected(ComponentEvent ce) {
container.removeAll();
}
}
);
vp.add(bt);




hp.add(vp);
cp.setContent();
container.add(hp);
return container;
}


private static class MyContentPanel extends ContentPanel {

private boolean forceLayout=true;
private int n;

public MyContentPanel() {
setCollapsible(true);
}

void setContent(){

removeAll();


VerticalPanel vp = new VerticalPanel();
vp.add(new Label("content "+ (n++) ));
add(vp);
if(forceLayout) layout(true);

setHeading("Collapsible (getWidgetCount()="+ getItemCount()+")");


}

void toggleLayout(){

if( !forceLayout ){
layout(true);
}

forceLayout = !forceLayout;
}
}
}

gslender
15 May 2008, 3:26 AM
After a removeAll() and repopulating contaniner, must always call a layout(true) to redraw everything?

Yes and No /:)

setLayoutOnChange(true) would possibly allow you to add/remove widgets and it will auto-layout to ensure all is good.

But if you bulk add/remove widgets, you be best not to do this - performance would be slow so turn off and call layout(true) yourself.

dbettoni
19 May 2008, 12:14 AM
Ok,
thanks for your explain

pavan.pappu
21 Jul 2008, 9:31 AM
Hi Guys,

I am trying to remove widgets from a Contentpanel using removeAll() method and adding a new widget into it.But the problem is the new widget which has been added second is not displayed in the Contentpanel.When I collapse the ContentPanel and again expand it using the minimise/maximise button the widget is displayed properly.how do I get it correct the first time itself without collapsing/expanding.

Thanks,
Pavan Pappu.

gslender
21 Jul 2008, 12:31 PM
without code its hard to say - but ensure you call layout