Search code examples
gwtgxt

GWT/GXT containers render position issues


While trying to insert absolute positioned HorizontalContainer into other container, I came upon weird issue. This absolute container pushes his next sibling by its width, if siblings are still being rendered (has a mask set).

Example:.

//parent container, holding all the widgets
HorizontalLayoutContainer hlc;

//widgets that are inserted into hlc container from the start
HBoxLayoutContainer hbox1;
HBoxLayoutContainer hbox2;
HBoxLayoutContainer hbox3;

//container that's inserted into hlc onMouseOver event. It can be inserted while hlc hboxes are still being rendered
HorizontalLayoutContainer panelContainer = new HorizontalLayoutContainer(); 
panelContainer.getElement().getStyle().setZIndex(13);
panelContainer.getElement().getStyle().setPosition(Position.ABSOLUTE);
panelContainer.getElement().getStyle().setWidth(55, Unit.PX);
panelContainer.getElement().getStyle().setHeight(18, Unit.PX);
panelContainer.getElement().getStyle().setFloat(Float.LEFT);

Now let's say a user hovers mouse over hlc container, which has hboxes1-3, however some of them has a mask set (data is still loading), like hbox1.mask(). onMouseOver event panelContainer is inserted into hlc:

hlc.insert(panelContainer, 0, new HorizontalLayoutData(55, 18));

However, since hboxes are still being rendered, panelContainer pushes hbox1 by 55px (its length) to the right. Even if it has position:absolute;.

                left:55px; should be left: 0px;
                -->
|panleContainer|hbox1|hbox2|hbox3| 

Any suggestions how should I properly insert panelContainer? Why is absolute positioning being ignored?

Note:

If I wait for hboxes to be rendered, panelContainer is inserted properly, hbox1 is not pushed.

Clarification to avoid xy problem:

Short summary: add an absolutely positioned box (for clarity, let's call it DragBox) which has a predefined width to an existing container (WidgetBox). WidgetBox is a HorizontalLayoutContainer which has 2 or 3 HBoxLayoutContainers. WidgetBox children (HBoxLayoutContainers) have widths of percentages. Example: if WidgetBox has 2 children, their widths are 0.3 and 0.7, if 3 children, then widths are 0.3, 0.4, 0.3;

WidgetBox is sized by its parent (SimpleContainer->VerticalLayoutContainer->WidgetBox).

Expecting: When a mouse is hovered over any WidgetBox container, a new item (DragBox) is added as a first element of the WidgetBox. It should not affect WidgetBox children in anyway. It should act as an absolute (within WidgetBox bounds) box.

Result: If WidgetBox or its parent's layout is forced (through forceLayout()), then DragBox affects first WidgetBox child. If forceLayout() is not used, DragBox does not affect WidgetBox children.


Solution

  • Since forceLayout() in my case is used only to ensure proper WidgetBox children (see my edit) content formatting, I don't want to force children to be laid out for widgetBox.

    To avoid this, I forced layout on each child of widgetBox instead of a parent.

    Example:.

    HorizontalLayoutContainer (parent) 
      -> HorizontalLayoutContainer (child 1, removed/added on mouseOver/Out)
      -> HBoxLayoutContainer (child 2)
      -> ...
    

    I used to force layout on parent, like parent.forceLayout() which would force children to be laid out and parent container would be resized.

    To avoid, as mentioned, I force layout on each child separately:

    for(int i = 0; i < parent.getWidgetCount(); i++) {
        if (parent.getWidget(i) instanceof ResizeContainer) {
            ResizeContainer widget = (ResizeContainer) parent.getWidget(i);
            widget.forceLayout();
        }
    }