0

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

  • A first view that instantiates a TabLayoutPanel, defines the first Tab's widgets and an empty second Tab.
  • onSelection of the second Tab I fire an event that sends the whole TabLayoutPanel to a second view that will define the second Tab's widgets.

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);
}
user1331120
  • 247
  • 2
  • 3
  • 8

2 Answers2

0

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.

Hilbrand Bouwkamp
  • 13,509
  • 1
  • 45
  • 52
  • In my code I manage the selection in the presenter of the `view1` so I fire an event that will call the `MDP2Presenter` wich call the `MDP2View`, so I don't see how to make the changes (add labels and textBoxes) in the presenter 1 – user1331120 May 16 '12 at 08:38
  • thanks for your help! I tried this.tabPanel.insert(this, "MDP2", 1); and I don't catch any error but the MDP2 tab still not displayed – user1331120 May 16 '12 at 08:57
0

I think you must create your MDP2 object without getting a reference on an existing widget (here this.tabPanel.getWidget(1)). Then, insert brand new MDP2 into tabpanel#1.

Something like:

MDP2 = initWidget(new VerticalPanel()); 
// 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);

I think calling a method "init" on something which already exists may be dangerous :)

Josh Darnell
  • 11,304
  • 9
  • 38
  • 66
Arcadien
  • 2,258
  • 16
  • 26