Remove a generated panel in GWT after a button is clicked

Miquella picture Miquella · Jun 8, 2009 · Viewed 9.1k times · Source

I am attempting to create a Google Web Toolkit (GWT) application that also uses Google Gears, but every time I try to remove the panel, I get an exception and the panel stays there.

Here is an excerpt from the exception I get (I've only included the relevant bits of the call stack, the rest just descends into the included function below):

java.lang.AssertionError: A widget that has an existing parent widget may not be added to the detach list
    at com.google.gwt.user.client.ui.RootPanel.detachOnWindowClose(RootPanel.java:122)
    at com.google.gwt.user.client.ui.RootPanel.get(RootPanel.java:197) 

I'm not sure what the problem is, but I really don't like leaving the button there after they approve the use of Gears.

What am I doing wrong? Or any suggestions on a different way I could do this to make it work?

if(!gearsFactory.hasPermission()) {
    HorizontalPanel rightPanel = new HorizontalPanel();
    rightPanel.getElement().setId("gearsPrompt");
    rightPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE);
    rightPanel.setSpacing(0);
    rightPanel.setHeight("28px");

    InlineLabel enableGearsText = new InlineLabel("Enable Gears for off-line access");
    enableGearsText.getElement().setId("gearsText");
    enableGearsText.addStyleName("titleElement");
    rightPanel.add(enableGearsText);

    final Button gearsButton = new Button("Use Gears");
    gearsButton.getElement().setId("gearsButton");
    gearsButton.addStyleName("titleElement");
    gearsButton.setHeight("24px");

    gearsButton.addClickHandler( new ClickHandler() {
        public void onClick(ClickEvent event) {
            Factory gearsFactory = Factory.getInstance();
            if(gearsFactory != null) {
                if(gearsFactory.getPermission()) {
                    RootPanel gearsPrompt = RootPanel.get("gearsPrompt");
                    gearsPrompt.removeFromParent();
                }
            }
        }
    });

    rightPanel.add(gearsButton);

    RootPanel titleBarRight = RootPanel.get("titleBarRight");
    titleBarRight.add(rightPanel);
}

Answer

Miquella picture Miquella · Jun 8, 2009

One solution I've found is to loop through all of the widgets under the "titleBarRight" panel and remove all widgets it contains:

if(gearsFactory.getPermission()) {
    RootPanel titleBarRight = RootPanel.get("titleBarRight");
    java.util.Iterator<Widget> itr = titleBarRight.iterator();
    while(itr.hasNext()) {
        itr.next();
        itr.remove();
    }
}

But somehow this still seems hacky and not quite the "right way to do it."