All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.user.client.ui.Composite Maven / Gradle / Ivy

/*
 * Copyright 2008 Google Inc.
 * 
 * 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.google.gwt.user.client.ui;

import com.google.gwt.dom.builder.shared.HtmlBuilderFactory;
import com.google.gwt.dom.builder.shared.HtmlSpanBuilder;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.logical.shared.AttachEvent;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;

/**
 * A type of widget that can wrap another widget, hiding the wrapped widget's
 * methods. When added to a panel, a composite behaves exactly as if the widget
 * it wraps had been added.
 *
 * 

* The composite is useful for creating a single widget out of an aggregate of * multiple other widgets contained in a single panel. *

* *

*

Example

* {@example com.google.gwt.examples.CompositeExample} *

*/ public abstract class Composite extends Widget implements IsRenderable { private Widget widget; private IsRenderable renderable; private Element elementToWrap; @Override public void claimElement(Element element) { if (renderable != null) { renderable.claimElement(element); setElement(widget.getElement()); } else { this.elementToWrap = element; } } @Override public void initializeClaimedElement() { if (renderable != null) { renderable.initializeClaimedElement(); } else { elementToWrap.getParentNode().replaceChild(widget.getElement(), elementToWrap); } } @Override public boolean isAttached() { if (widget != null) { return widget.isAttached(); } return false; } @Override public void onBrowserEvent(Event event) { // Fire any handler added to the composite itself. super.onBrowserEvent(event); // Delegate events to the widget. widget.onBrowserEvent(event); } @Override public SafeHtml render(RenderableStamper stamper) { if (renderable != null) { return renderable.render(stamper); } else { checkInit(); HtmlSpanBuilder spanBuilder = HtmlBuilderFactory.get() .createSpanBuilder(); stamper.stamp(spanBuilder).end(); return spanBuilder.asSafeHtml(); } } @Override public void render(RenderableStamper stamper, SafeHtmlBuilder builder) { if (renderable != null) { renderable.render(stamper, builder); } else { builder.append(render(stamper)); } } /** * Provides subclasses access to the topmost widget that defines this * composite. * * @return the widget */ protected Widget getWidget() { return widget; } /** * Check if the composite is initialized. */ private void checkInit() { if (widget == null) { throw new IllegalStateException("initWidget() is not called yet"); } } /** * Sets the widget to be wrapped by the composite. The wrapped widget must be * set before calling any {@link Widget} methods on this object, or adding it * to a panel. This method may only be called once for a given composite. * * @param widget the widget to be wrapped */ protected void initWidget(Widget widget) { // Validate. Make sure the widget is not being set twice. if (this.widget != null) { throw new IllegalStateException("Composite.initWidget() may only be " + "called once."); } if (widget == null) { throw new NullPointerException("widget cannot be null"); } if (widget instanceof IsRenderable) { // In case the Widget being wrapped is an IsRenderable, we save that fact. this.renderable = (IsRenderable) widget; } // Detach the new child. widget.removeFromParent(); // Use the contained widget's element as the composite's element, // effectively merging them within the DOM. Element elem = widget.getElement(); setElement(elem); if (PotentialElement.isPotential(elem)) { PotentialElement.as(elem).setResolver(this); } // Logical attach. this.widget = widget; // Adopt. widget.setParent(this); } @Override protected void onAttach() { checkInit(); if (!isOrWasAttached()) { widget.sinkEvents(eventsToSink); eventsToSink = -1; } widget.onAttach(); // Clobber the widget's call to setEventListener(), causing all events to // be routed to this composite, which will delegate back to the widget by // default (note: it's not necessary to clear this in onDetach(), because // the widget's onDetach will do so). DOM.setEventListener(getElement(), this); // Call doAttachChildren() and then onLoad() directly, because we're not // calling super.onAttach(). doAttachChildren(); onLoad(); AttachEvent.fire(this, true); } @Override protected void onDetach() { try { onUnload(); doDetachChildren(); AttachEvent.fire(this, false); } finally { // We don't want an exception in user code to keep us from calling the // super implementation (or event listeners won't get cleaned up and // the attached flag will be wrong). widget.onDetach(); } } @Override protected Element resolvePotentialElement() { setElement(widget.resolvePotentialElement()); return getElement(); } /** * This method was for initializing the Widget to be wrapped by this * Composite, but has been deprecated in favor of {@link #initWidget(Widget)}. * * @deprecated Use {@link #initWidget(Widget)} instead */ @Deprecated protected void setWidget(Widget widget) { initWidget(widget); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy