com.cgxlib.xq.client.plugins.widgets.WidgetsHtmlPanel.java Source code

Java tutorial

Introduction

Here is the source code for com.cgxlib.xq.client.plugins.widgets.WidgetsHtmlPanel.java

Source

/*
 * Copyright 2011, The gwtquery team.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.cgxlib.xq.client.plugins.widgets;

/*
 * #%L
 * CGXlib
 * %%
 * Copyright (C) 2016 CGXlib (http://www.cgxlib.com)
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
  Code is originally from gwtquery, and modified by CGXlib team.
 */

import com.cgxlib.xq.client.XQ;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

import static com.cgxlib.xq.client.XQ.$;

/**
 * This {@link HTMLPanel} takes as content an element already
 * attached to the DOM. If {@link Widget widgets} are present in the children of
 * the element to attach, they will be automatically adopted by the panel in
 * order to keep a consistent widgets hierarchy.
 */
public class WidgetsHtmlPanel extends HTMLPanel {

    public WidgetsHtmlPanel(Element e) {
        super("");
        if (e != null) {
            Widget w = $(e).widget();
            if (w == null) {
                // We convert the element to a gwt htmlPanel
                setElementImpl(e);
                WidgetsUtils.attachWidget(this, null);
            } else {
                Widget p = w.getParent();
                if (p instanceof Panel) {
                    // Replace the widget by this panel
                    this.add(w);
                    ((Panel) p).add(this);
                } else {
                    // Replace the element by this element
                    Element n = e.getParentElement();
                    n.appendChild(getElement());
                    getElement().appendChild(e);
                    WidgetsUtils.attachWidget(this, null);
                }
            }
        }
        adoptSubWidgets();
    }

    /**
     * use jsni to access private attribute.
     */
    private native void setElementImpl(Element e) /*-{
                                                  this.@com.google.gwt.user.client.ui.UIObject::element = e;
                                                  }-*/;

    /**
     * Iterate over the children of this widget's element to find widget. If
     * widgets are find adopt it automatically
     */
    protected void adoptSubWidgets() {
        adoptSubWidgets(getElement());
    }

    /**
     * Check if the {@link Element Element} <code>root</code> is attached to the
     * widget. If it is the case, adopt the widget. If not, check if the chidren
     * are linked to a widget to adopt them.
     */
    protected void adoptSubWidgets(Element root) {

        XQ children = $(root).children();

        for (Element child : children.elements()) {
            Widget w = $(child).widget();
            if (w != null) {
                doAdopt(w);
            } else {
                adoptSubWidgets(child);
            }
        }
    }

    /**
     * Adopt the {@link Widget widet} <code>w</code>. if the current parent of the
     * widget is an {@link HTMLPanel} or is null, the widget will not detach
     * physically in order to maintain the html structure. If the parent is an
     * other widget, it will be physically detach and reattach to this panel.
     *
     * @param w
     */
    protected void doAdopt(Widget w) {
        Widget parent = w.getParent();
        boolean mustBePhysicallyReattach = false;

        if (parent == null) {
            if (RootPanel.isInDetachList(w)) {
                RootPanel.detachNow(w);
            }
        } else if (parent instanceof HTMLPanel) {
            WidgetsUtils.doLogicalDetachFromHtmlPanel(w);
        } else {
            // the widget will be physically detach
            w.removeFromParent();
            mustBePhysicallyReattach = true;
        }

        getChildren().add(w);

        if (mustBePhysicallyReattach) {
            DOM.appendChild(getElement(), w.getElement());
        }

        adopt(w);
    }
}