gwtmvpgwt-tablayoutpanel

TabLayoutPanel on GWT and MVP


I start developping an interface with GWT using MVP architecture according to this model:

On the second view I recieve the appropriate TabLayoutPanel but when I retrieve the second Tab, make changes and insert it in the old panel I got the message "This widget's parent does not implement HasWidgets" and the second Tab disappears.

Thanks for helpping me to see what is the true problem here or how to do it otherwise.

I added the second view code with comments.

public class MDP2View extends Composite implements MDP2Presenter.Display {

    private final TabLayoutPanel tabPanel;
    private final VerticalPanel MDP2;
    private final Label label;

    public MDP2View(HasSelectionHandlers<Integer> tabPanel) {
            // Getting the TabLayoutPanel created on the first View  
        this.tabPanel = (TabLayoutPanel) tabPanel;
            // Getting the second Tab (this will remove the Tab from the TabLayoutPanel)
        MDP2 = (VerticalPanel) this.tabPanel.getWidget(1); 
        initWidget(MDP2);
            // Adding a label to the Tab
        label = new Label();
        label.setText("onSelectionHandler Works!!!");
        MDP2.add(label);
            // Inserting the Tab in the tabPanel
        this.tabPanel.insert(MDP2, "MDP2", 1);
}

Solution

  • The problem started when you added a widget in it's constructor to a parent. Which resulted in this bug in your code. First you attach the MDP2 widget to a new parent the MDP2View by calling initWidget. MDP2View is the new parent of MDP2 (as it now has been removed from the tabPanel). Then in the insert you probably intend to insert your view, but instead insert it's only child the widget MDP2. The error is thrown because insert will implicitly try to remove MDP2 from it's parent MDP2View via the method removeParent and that is not allowed a child widget of MDP2View. If I'm correct this should make it work this.tabPanel.insert(this, "MDP2", 1);.

    But it's much better to remove the interaction with the tabPanel from this constructor and move that to the implementation of for example the selectionHandler. That will make your view much cleaner. This code is just waiting for future bugs: casts to TabLayoutPanel, cast to VerticalPanel; what if you change that widget, that will lead to runtime errors. Getting and inserting in a hardcoded position 1; what if you add a tab before 1; you code will behave incorrect.