moh
moh

Reputation: 1526

Adding same widget to two panel causing issue

I have created two VerticalPanel(mainVP,subVP) and one TextBox(box).TextBox(box) is added to mainVP as well as subVP but i am adding mainVP only to RootPanel here If i lauch my application nothing is visible even though i have added TextBox(box) to VerticalPanel(mainVP) which is added to main Rootpanel.

 VerticalPanel mainVP=new VerticalPanel();
 VerticalPanel subVP=new VerticalPanel();
 TextBox box=new TextBox();

 mainVP.add(box); //Textbox added to VerticalPanel
 subVP.add(box);

 RootPanel.get().add(mainVP);//mainVP contains TextBox

Can anybody explain me how the above code is working internally?

Upvotes: 0

Views: 826

Answers (1)

Colin Alworth
Colin Alworth

Reputation: 18331

Your panel subVP isn't added to anything, and when the box is added to subVP, it is removed from mainVP. Widgets can only be one place at a time.

--

(adding more detail for the comment posted)

This is part of the basic assumption of how a widget works - it isn't a "stamp" that can be put on the page in several places, it instead represents one or more DOM elements, and wraps them up for easier use and reuse. Each widget exposes some event handlers that you can listen to, and ways to change what the widget looks like.

Imagine if you had two buttons on the page, and you need them to do the same thing. When looking at the page, clearly there are two buttons, and while they look the same and cause the same action, they aren't the same thing.

Consider how the button might work internally - lets say it has a check to see if the mouse is hovered, and if so display a tooltip, or change the color. If the same widget is rendered in two places, both now would get this change.

From the API side: Widget has a method getParent(), which returns the parent widget. If you could add a widget to more than one place at a time, either getParent() wouldn't be possible, or it would need to return a list.

Panel likewise has indexOf, but if you could add a widget to more than one parent, it would also follow that you could add the same widget to the same parent multiple times - what would indexOf return?

Finally, implementation to achieve this. From the Javadoc for Panel.add:

/**
 * Adds a child widget.
 * 
 * <p>
 * <b>How to Override this Method</b>
 * </p>
 * <p>
 * There are several important things that must take place in the correct
 * order to properly add or insert a Widget to a Panel. Not all of these steps
 * will be relevant to every Panel, but all of the steps must be considered.
 * <ol>
 * <li><b>Validate:</b> Perform any sanity checks to ensure the Panel can
 * accept a new Widget. Examples: checking for a valid index on insertion;
 * checking that the Panel is not full if there is a max capacity.</li>
 * <li><b>Adjust for Reinsertion:</b> Some Panels need to handle the case
 * where the Widget is already a child of this Panel. Example: when performing
 * a reinsert, the index might need to be adjusted to account for the Widget's
 * removal. See {@link ComplexPanel#adjustIndex(Widget, int)}.</li>
 * <li><b>Detach Child:</b> Remove the Widget from its existing parent, if
 * any. Most Panels will simply call {@link Widget#removeFromParent()} on the
 * Widget.</li>
 * <li><b>Logical Attach:</b> Any state variables of the Panel should be
 * updated to reflect the addition of the new Widget. Example: the Widget is
 * added to the Panel's {@link WidgetCollection} at the appropriate index.</li>
 * <li><b>Physical Attach:</b> The Widget's Element must be physically
 * attached to the Panel's Element, either directly or indirectly.</li>
 * <li><b>Adopt:</b> Call {@link #adopt(Widget)} to finalize the add as the
 * very last step.</li>
 * </ol>
 * </p>
 * 
 * @param child the widget to be added
 * @throws UnsupportedOperationException if this method is not supported (most
 *           often this means that a specific overload must be called)
 * @see HasWidgets#add(Widget)
 */
public void add(Widget child)

Finally, the default implementation used by most panels in GWT is basically this at its heart (ComplexPanel.add):

// Detach new child.
child.removeFromParent();

// Logical attach.
getChildren().add(child);

// Physical attach.
DOM.appendChild(container, child.getElement());

// Adopt.
adopt(child);

There are other implementations as well, but they mostly boil down to this, in keeping with the guidelines outlined in Panel.

Upvotes: 3

Related Questions