co.fxl.gui.gwt.GWTElement.java Source code

Java tutorial

Introduction

Here is the source code for co.fxl.gui.gwt.GWTElement.java

Source

/**
 * Copyright (c) 2010-2015 Dangelmayr IT GmbH. All rights reserved.
 *  
 * This file is part of FXL GUI API.
 *  
 * FXL GUI API is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *  
 * FXL GUI API is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *  
 * You should have received a copy of the GNU General Public License
 * along with FXL GUI API.  If not, see <http://www.gnu.org/licenses/>.
 */
package co.fxl.gui.gwt;

import java.util.LinkedList;
import java.util.List;

import co.fxl.gui.api.IBordered.IBorder;
import co.fxl.gui.api.IClickable.IClickListener;
import co.fxl.gui.api.IClickable.IKey;
import co.fxl.gui.api.IColored.IColor;
import co.fxl.gui.api.ICursor;
import co.fxl.gui.api.IDisplay;
import co.fxl.gui.api.IDraggable;
import co.fxl.gui.api.IDraggable.IDragStartListener.IDragStartEvent;
import co.fxl.gui.api.IDropTarget.IDragEvent;
import co.fxl.gui.api.IDropTarget.IDragMoveListener;
import co.fxl.gui.api.IDropTarget.IDropListener;
import co.fxl.gui.api.IElement;
import co.fxl.gui.api.IFontElement.IFont;
import co.fxl.gui.api.IKeyRecipient;
import co.fxl.gui.api.IKeyRecipient.ControlKey;
import co.fxl.gui.api.IKeyRecipient.IKeyListener;
import co.fxl.gui.api.IMargin;
import co.fxl.gui.api.IMouseOverElement.IMouseOverListener;
import co.fxl.gui.api.IPadding;
import co.fxl.gui.api.IShell;
import co.fxl.gui.api.IUpdateable.IUpdateListener;
import co.fxl.gui.gwt.GWTClickHandler.ClickEventAdp;
import co.fxl.gui.gwt.GWTClickHandler.DoubleClickEventAdp;
import co.fxl.gui.gwt.GWTClickHandler.KeyPressAdp;
import co.fxl.gui.impl.RuntimeConstants;
import co.fxl.gui.impl.StatusDisplay;
import co.fxl.gui.log.impl.Log;

import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DoubleClickEvent;
import com.google.gwt.event.dom.client.DoubleClickHandler;
import com.google.gwt.event.dom.client.DragDropEventBase;
import com.google.gwt.event.dom.client.DragEndEvent;
import com.google.gwt.event.dom.client.DragEndHandler;
import com.google.gwt.event.dom.client.DragLeaveEvent;
import com.google.gwt.event.dom.client.DragLeaveHandler;
import com.google.gwt.event.dom.client.DragOverEvent;
import com.google.gwt.event.dom.client.DragOverHandler;
import com.google.gwt.event.dom.client.DragStartEvent;
import com.google.gwt.event.dom.client.DragStartHandler;
import com.google.gwt.event.dom.client.DropEvent;
import com.google.gwt.event.dom.client.DropHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.dom.client.HasDoubleClickHandlers;
import com.google.gwt.event.dom.client.HasKeyPressHandlers;
import com.google.gwt.event.dom.client.HasKeyUpHandlers;
import com.google.gwt.event.dom.client.HasMouseOutHandlers;
import com.google.gwt.event.dom.client.HasMouseOverHandlers;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.FocusListener;
import com.google.gwt.user.client.ui.Focusable;
import com.google.gwt.user.client.ui.HasFocus;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

public class GWTElement<T extends Widget, R> implements IElement<R>, RuntimeConstants {

    public interface Injector {

        void inject(Widget nativeElement);

    }

    private final class GWTPoint implements IDragEvent {

        private final DragDropEventBase<?> event;

        private GWTPoint(DragDropEventBase<?> event) {
            this.event = event;
        }

        @Override
        public int offsetX() {
            return event.getNativeEvent().getClientX() - container.widget.getAbsoluteLeft();
        }

        @Override
        public int offsetY() {
            return event.getNativeEvent().getClientY() - container.widget.getAbsoluteTop();
        }

        @Override
        public String iD() {
            return event.getData("text");
        }

        @Override
        public boolean shift() {
            return event.getNativeEvent().getShiftKey();
        }

        @Override
        public boolean ctrl() {
            return event.getNativeEvent().getCtrlKey();
        }
    }

    private final class KeyPressHandlerAdapter implements KeyPressHandler, KeyUpHandler, IKeyRecipient.IKey<R> {

        private IClickListener listener;
        private char targetCode = '\r';
        private int nativeKeyCode = -1;
        private IKeyListener keyListener = null;

        private KeyPressHandlerAdapter(IClickListener listener) {
            this.listener = listener;
        }

        private KeyPressHandlerAdapter(IKeyListener listener) {
            this.keyListener = listener;
            listenOnKeyup();
        }

        @SuppressWarnings("unchecked")
        public R listenOnKeyPress(char c) {
            // DOM.sinkEvents(container.widget.getElement(),
            // com.google.gwt.user.client.Event.ONKEYPRESS);
            targetCode = c;
            return (R) GWTElement.this;
        }

        @SuppressWarnings("unchecked")
        public R listenOnKeyUp(int keyRight) {
            listenOnKeyup();
            nativeKeyCode = keyRight;
            return (R) GWTElement.this;
        }

        protected void listenOnKeyup() {
            DOM.sinkEvents(container.widget.getElement(), com.google.gwt.user.client.Event.ONKEYUP);
        }

        @Override
        public void onKeyPress(KeyPressEvent event) {
            if (nativeKeyCode != -1)
                return;
            char charCode = event.getCharCode();
            if (keyListener != null) {
                keyListener.onCharacterKey(charCode);
            } else if (charCode == targetCode) {
                listener.onClick();
            }
        }

        @Override
        public void onKeyUp(KeyUpEvent event) {
            int charCode = event.getNativeKeyCode();
            if (keyListener != null) {
                keyListener.onControlKey(key(charCode));
                return;
            }
            if (nativeKeyCode == -1)
                return;
            if (charCode == nativeKeyCode) {
                listener.onClick();
            }
        }

        private ControlKey key(int charCode) {
            switch (charCode) {
            case KeyCodes.KEY_UP:
                return ControlKey.UP;
            case KeyCodes.KEY_DOWN:
                return ControlKey.DOWN;
            default:
                return ControlKey.OTHER;
            }
        }

        @Override
        public R enter() {
            return listenOnKeyPress('\r');
        }

        @Override
        public R tab() {
            return listenOnKeyPress('\t');
        }

        @Override
        public R up() {
            return listenOnKeyUp(KeyCodes.KEY_UP);
        }

        @Override
        public R down() {
            return listenOnKeyUp(KeyCodes.KEY_DOWN);
        }

        @Override
        public R backspace() {
            return listenOnKeyUp(KeyCodes.KEY_BACKSPACE);
        }

        @Override
        public R left() {
            return listenOnKeyUp(KeyCodes.KEY_LEFT);
        }

        @Override
        public R right() {
            return listenOnKeyUp(KeyCodes.KEY_RIGHT);
        }

        @Override
        public co.fxl.gui.api.IKeyRecipient.IKey<R> ctrl() {
            throw new UnsupportedOperationException();
        }

        @Override
        public R character(char c) {
            throw new UnsupportedOperationException();
        }
    }

    static final int IEDECREMENTW = IE_STANDARD ? 8 : 0;
    static final int IEDECREMENTH = IE_STANDARD ? 8 : 0;
    private static final boolean LOG_ILLEGAL_SIZES = true;
    public GWTContainer<T> container;
    protected HandlerRegistration registration;
    protected HandlerRegistration registration2;
    protected HandlerRegistration registration3;
    protected List<GWTClickHandler<R>> handlers = new LinkedList<GWTClickHandler<R>>();
    private String visibleStyle = null;
    private boolean hasDragListener;
    private HandlerRegistration dummyDragListener;
    public Injector injector;
    private Style style;
    private boolean focusListenerSet;
    private List<IUpdateListener<Boolean>> focusListeners = new LinkedList<IUpdateListener<Boolean>>();
    private IShell shell;
    private IBorder border;

    public GWTElement() {
    }

    public GWTElement(GWTContainer<T> container) {
        assert container != null : "GWTElement.new";
        this.container = container;
    }

    protected T widget() {
        return container.widget;
    }

    protected void addStyleName(String string) {
        container.widget.addStyleName(string);
    }

    protected Style style() {
        if (style == null) {
            style = container.widget.getElement().getStyle();
        }
        return style;
    }

    // IFont defaultFont() {
    // return ((IFontElement) this).font().pixel(12).family().arial();
    // }

    public IBorder border() {
        if (border != null)
            return border;
        return border = new GWTWidgetBorder(container.widget);
    }

    @SuppressWarnings("unchecked")
    @Override
    public R visible(boolean visible) {
        boolean visible2 = container.widget.isVisible();
        if (visible2 == visible)
            return (R) this;
        if (!visible) {
            if (visible())
                visibleStyle = style().getProperty("display");
            container.widget.setVisible(false);
        } else {
            if (visibleStyle != null)
                style().setProperty("display", visibleStyle);
            else
                container.widget.setVisible(visible);
        }
        return (R) this;
    }

    @Override
    public R width(int width) {
        if (LOG_ILLEGAL_SIZES && width == 0)
            Log.instance().warn("Illegal width 0 set on " + getClass().getName());
        return width(width < 0, width + "px");
    }

    @SuppressWarnings("unchecked")
    @Override
    public R minWidth(int minWidth) {
        if (isUndefined())
            return (R) this;
        if (minWidth < 0)
            style().clearProperty("minWidth");
        else {
            style().setProperty("minWidth", minWidth + "px");
        }
        return (R) this;
    }

    @Override
    public R width(double width) {
        return width(width < 0, percent(width) + "%");
    }

    private String percent(double width) {
        return String.valueOf(width * 100);
    }

    @SuppressWarnings("unchecked")
    R width(boolean isNegative, String widthString) {
        if (isUndefined())
            return (R) this;
        if (isNegative)
            style().clearWidth();
        else {
            container.widget.setWidth(widthString);
        }
        return (R) this;
    }

    protected boolean isUndefined() {
        return container == null || container.widget == null;
    }

    @Override
    public R height(int height) {
        if (LOG_ILLEGAL_SIZES && height == 0)
            Log.instance().warn("Illegal height 0 set on " + getClass().getName());
        return height(height < 0, height + "px");
    }

    @Override
    public R height(double height) {
        return height(height < 0, percent(height) + "%");
    }

    @SuppressWarnings("unchecked")
    private R height(boolean isNegative, String heightString) {
        if (isUndefined())
            return (R) this;
        if (isNegative)
            style().clearHeight();
        else {
            container.widget.setHeight(heightString);
        }
        return (R) this;
    }

    @Override
    public R size(int width, int height) {
        width(width);
        return height(height);
    }

    @Override
    public int height() {
        return container.widget.getOffsetHeight();
    }

    @Override
    public int width() {
        int width = container.widget.getOffsetWidth();
        // if (LOG_ILLEGAL_SIZES && width == 0)
        // Log.instance().warn(
        // "Illegal width 0 encountered on " + getClass().getName());
        return width;
    }

    @Override
    public int offsetX() {
        return container.widget.getAbsoluteLeft();
    }

    @Override
    public int offsetY() {
        int absoluteTop = container.widget.getAbsoluteTop();
        // if (LOG_ILLEGAL_SIZES && absoluteTop == 0)
        // Log.instance().warn(
        // "Potentially illegal offsetY 0 on " + getClass().getName());
        return absoluteTop;
    }

    @Override
    public void remove() {
        container.parent.remove(container.widget);
    }

    @SuppressWarnings({ "unchecked" })
    @Override
    public <N> N nativeElement() {
        return (N) container.widget;
    }

    @SuppressWarnings("unchecked")
    @Override
    public R tooltip(String tooltip) {
        container.widget.setTitle(tooltip);
        return (R) this;
    }

    @Override
    public boolean visible() {
        return container.widget.isAttached() && container.widget.isVisible();
    }

    public IKey<R> addClickListener(IClickListener clickListener) {
        // assert handlers.isEmpty() :
        // "Multiple click listeners are not yet supported";
        GWTClickHandler<R> handler = newGWTClickHandler(clickListener);
        handlers.add(handler);
        toggleClickHandler(true);
        return handler;
    }

    GWTClickHandler<R> newGWTClickHandler(IClickListener clickListener) {
        throw new UnsupportedOperationException();
    }

    private void toggleClickHandler(boolean toggle) {
        style().setCursor(toggle ? com.google.gwt.dom.client.Style.Cursor.POINTER
                : com.google.gwt.dom.client.Style.Cursor.DEFAULT);
        if (registration != null) {
            registration.removeHandler();
            registration = null;
        }
        if (registration2 != null) {
            registration2.removeHandler();
            registration2 = null;
        }
        if (registration3 != null) {
            registration3.removeHandler();
            registration3 = null;
        }
        if (toggle) {
            registerClickHandler();
        }
    }

    void registerClickHandler() {
        registration = ((HasClickHandlers) container.widget).addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                fireClickListenersSingleClick(event);
            }
        });
        if (container.widget instanceof HasDoubleClickHandlers)
            registration2 = ((HasDoubleClickHandlers) container.widget)
                    .addDoubleClickHandler(new DoubleClickHandler() {
                        @Override
                        public void onDoubleClick(DoubleClickEvent event) {
                            fireClickListenersDoubleClick(event);
                        }
                    });
        if (container.widget instanceof HasKeyPressHandlers)
            registration3 = ((HasKeyPressHandlers) container.widget).addKeyPressHandler(new KeyPressHandler() {

                @Override
                public void onKeyPress(KeyPressEvent event) {
                    fireClickListenersKeyPress(event);
                }
            });
    }

    @SuppressWarnings("unchecked")
    public R clickable(boolean enable) {
        toggleClickHandler(enable);
        return (R) this;
    }

    public boolean clickable() {
        return registration != null;
    }

    @Override
    public IDisplay display() {
        return container.display();
    }

    protected IColor newBackgroundColor() {
        GWTWidgetStyle style = new GWTWidgetStyle("background-color-", container.widget);
        return new GWTStyleColor(style) {
            @Override
            void setColor(String color, com.google.gwt.dom.client.Style stylable) {
                stylable.setBackgroundColor(color);
            }
        };
    }

    public R focus(final boolean focus) {
        T widget = container.widget;
        return focus(focus, widget);
    }

    private void notifyFocusListeners(boolean b) {
        for (IUpdateListener<Boolean> l : focusListeners)
            l.onUpdate(b);
    }

    public R addFocusListener(final IUpdateListener<Boolean> l) {
        T widget = container.widget;
        return addFocusListener(l, widget);
    }

    @SuppressWarnings("unchecked")
    protected R focus(final boolean focus, Widget widget) {
        if (widget.isVisible() && widget.isAttached()) {
            Focusable focusable = (Focusable) widget;
            focusable.setFocus(focus);
            notifyFocusListeners(focus);
        }
        return (R) this;
    }

    @SuppressWarnings({ "unchecked", "deprecation" })
    protected R addFocusListener(final IUpdateListener<Boolean> l, Widget widget) {
        if (!focusListenerSet) {
            ((HasFocus) widget).addFocusListener(new FocusListener() {
                @Override
                public void onFocus(Widget sender) {
                    notifyFocusListeners(true);
                }

                @Override
                public void onLostFocus(Widget sender) {
                    notifyFocusListeners(false);
                }
            });
        }
        focusListeners.add(l);
        return (R) this;
    }

    public IKeyRecipient.IKey<R> addKeyListener(IClickListener listener) {
        KeyPressHandlerAdapter adp = new KeyPressHandlerAdapter(listener);
        addKeyPressHandler(adp);
        return adp;
    }

    @SuppressWarnings("unchecked")
    public R addKeyListener(IKeyListener listener) {
        KeyPressHandlerAdapter adp = new KeyPressHandlerAdapter(listener);
        addKeyPressHandler(adp);
        return (R) this;
    }

    protected void addKeyPressHandler(KeyPressHandlerAdapter adp) {
        ((HasKeyPressHandlers) container.widget).addKeyPressHandler(adp);
        ((HasKeyUpHandlers) container.widget).addKeyUpHandler(adp);
    }

    @Override
    public R offset(int x, int y) {
        throw new UnsupportedOperationException();
    }

    public IColor color() {
        return newBackgroundColor();
    }

    public IFont font() {
        return new GWTFont(container.widget);
    }

    @SuppressWarnings("unchecked")
    public R addMouseOverListener(final IMouseOverListener l) {
        ((HasMouseOverHandlers) container.widget).addMouseOverHandler(new MouseOverHandler() {
            @Override
            public void onMouseOver(MouseOverEvent event) {
                l.onMouseOver();
            }
        });
        ((HasMouseOutHandlers) container.widget).addMouseOutHandler(new MouseOutHandler() {
            @Override
            public void onMouseOut(MouseOutEvent event) {
                l.onMouseOut();
            }
        });
        return (R) this;
    }

    // @SuppressWarnings("unchecked")
    // @Override
    // public R attach(boolean attach) {
    // if (attach)
    // container.parent.add(container.widget);
    // else
    // container.parent.remove(container.widget);
    // return (R) this;
    // }

    @SuppressWarnings("unchecked")
    public R draggable(boolean draggable) {
        container.widget.getElement().setDraggable(draggable ? Element.DRAGGABLE_TRUE : Element.DRAGGABLE_FALSE);
        return (R) this;
    }

    @SuppressWarnings("unchecked")
    public R addDragStartListener(final IDraggable.IDragStartListener l) {
        draggable(true);
        container.widget.addDomHandler(new DragStartHandler() {
            @Override
            public void onDragStart(final DragStartEvent event) {
                event.setData("text", "dragging");
                l.onDragStart(new IDragStartEvent() {

                    @Override
                    public int offsetX() {
                        return event.getNativeEvent().getClientX()
                                - container.widget.getElement().getAbsoluteLeft();
                    }

                    @Override
                    public int offsetY() {
                        return event.getNativeEvent().getClientY() - container.widget.getElement().getAbsoluteTop();
                    }

                    @Override
                    public IDragStartEvent dragImage(IElement<?> element) {
                        GWTElement<?, ?> gwtElement = (GWTElement<?, ?>) element;
                        Element domElement = gwtElement.getDOMElement();
                        if (domElement == null)
                            throw new RuntimeException("drag image element is null");
                        event.getDataTransfer().setDragImage(domElement, 0, 0);
                        return this;
                    }

                    @Override
                    public IDragStartEvent iD(String iD) {
                        event.setData("text", iD);
                        return this;
                    }
                });
            }
        }, DragStartEvent.getType());
        container.widget.addDomHandler(new DragEndHandler() {

            @Override
            public void onDragEnd(DragEndEvent event) {
                GWTDisplay.instance.resetScrollPanelTop();
                l.onDragEnd();
            }

        }, DragEndEvent.getType());
        return (R) this;
    }

    @SuppressWarnings("unchecked")
    public R addDragOverListener(final IDragMoveListener l) {
        hasDragListener = true;
        if (dummyDragListener != null) {
            dummyDragListener.removeHandler();
        }
        container.widget.addDomHandler(new DragOverHandler() {

            @Override
            public void onDragOver(DragOverEvent event) {
                event.preventDefault();
                l.onDragOver(new GWTPoint(event));
            }
        }, DragOverEvent.getType());
        container.widget.addDomHandler(new DragLeaveHandler() {

            @Override
            public void onDragLeave(final DragLeaveEvent event) {
                event.preventDefault();
                l.onDragOut(new GWTPoint(event));
            }
        }, DragLeaveEvent.getType());
        return (R) this;
    }

    @SuppressWarnings("unchecked")
    public R addDropListener(final IDropListener l) {
        if (!hasDragListener) {
            dummyDragListener = container.widget.addDomHandler(new DragOverHandler() {

                @Override
                public void onDragOver(DragOverEvent event) {
                    event.preventDefault();
                }
            }, DragOverEvent.getType());
        }
        container.widget.addDomHandler(new DropHandler() {

            @Override
            public void onDrop(DropEvent event) {
                event.preventDefault();
                // GWTDisplay.waiting-delta if (GWTDisplay.waiting)
                // return;
                l.onDropOn(new GWTPoint(event));
            }
        }, DropEvent.getType());
        return (R) this;
    }

    public Element getDOMElement() {
        return container.widget.getElement();
    }

    @SuppressWarnings("unchecked")
    @Override
    public R padding(int padding) {
        style().setPadding(padding, Unit.PX);
        return (R) this;
    }

    @SuppressWarnings("unchecked")
    @Override
    public R margin(int margin) {
        style().setMargin(margin, Unit.PX);
        return (R) this;
    }

    @Override
    public IPadding padding() {
        return new IPadding() {

            @Override
            public IPadding left(int pixel) {
                style().setPaddingLeft(pixel, Unit.PX);
                return this;
            }

            @Override
            public IPadding right(int pixel) {
                style().setPaddingRight(pixel, Unit.PX);
                return this;
            }

            @Override
            public IPadding top(int pixel) {
                style().setPaddingTop(pixel, Unit.PX);
                return this;
            }

            @Override
            public IPadding bottom(int pixel) {
                style().setPaddingBottom(pixel, Unit.PX);
                return this;
            }

        };
    }

    @Override
    public IMargin margin() {
        return new IMargin() {

            @Override
            public IMargin left(int pixel) {
                style().setMarginLeft(pixel, Unit.PX);
                return this;
            }

            @Override
            public IMargin right(int pixel) {
                style().setMarginRight(pixel, Unit.PX);
                return this;
            }

            @Override
            public IMargin top(int pixel) {
                style().setMarginTop(pixel, Unit.PX);
                return this;
            }

            @Override
            public IMargin bottom(int pixel) {
                style().setMarginBottom(pixel, Unit.PX);
                return this;
            }

        };
    }

    @SuppressWarnings("unchecked")
    @Override
    public R opacity(double opacity) {
        if (!GWTDisplay.isInternetExplorer8OrBelow)
            container.widget.getElement().getStyle().setOpacity(opacity);
        return (R) this;
    }

    @SuppressWarnings("unchecked")
    @Override
    public <N> R nativeElement(N nativeElement) {
        injector.inject((Widget) nativeElement);
        return (R) this;
    }

    @SuppressWarnings("unchecked")
    @Override
    public R iD(String iD) {
        container.widget.getElement().setId(iD);
        GWTDisplay.instance.notifyElement(this);
        return (R) this;
    }

    void fireClickListenersDoubleClick(DoubleClickEvent event) {
        DoubleClickEventAdp adp = new DoubleClickEventAdp(event);
        fireClickListenersDoubleClick(adp);
    }

    void fireClickListenersDoubleClick(DoubleClickEventAdp adp) {
        for (GWTClickHandler<R> handler : handlers) {
            handler.onDoubleClick(adp);
        }
    }

    void fireClickListenersKeyPress(KeyPressEvent event) {
        KeyPressAdp adp = new KeyPressAdp(event);
        fireClickListenersKeyPress(adp);
    }

    void fireClickListenersKeyPress(KeyPressAdp adp) {
        for (GWTClickHandler<R> handler : handlers) {
            handler.onClick(adp);
        }
    }

    void fireClickListenersSingleClick(ClickEvent event) {
        ClickEventAdp adp = new ClickEventAdp(event);
        fireClickListenersSingleClick(adp);
    }

    void fireClickListenersSingleClick(ClickEventAdp adp) {
        for (GWTClickHandler<R> handler : handlers) {
            handler.onClick(adp);
        }
    }

    @Override
    public String iD() {
        return container.widget.getElement().getId();
    }

    // void log(DragDropEventBase<?> event) {
    // Log.instance().debug(
    // "event " + event.getClass().getName() + ": "
    // + event.getNativeEvent().getClientX() + " | "
    // + event.getNativeEvent().getClientY());
    // }

    // @Override
    // public <N> R nativeElement(N nativeElement) {
    // throw new UnsupportedOperationException();
    // }

    @Override
    public IShell shell() {
        if (shell == null) {
            shell = find(container.widget);
        }
        return shell;
    }

    private IShell find(Widget widget) {
        if (widget instanceof PopupPanel)
            return new GWTPopUp((PopupPanel) widget);
        else if (widget instanceof RootPanel)
            return StatusDisplay.instance();
        else {
            Widget parent = widget.getParent();
            if (parent == null)
                return StatusDisplay.instance();
            return find(parent);
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public R addStyle(String style) {
        container.widget.addStyleName(style);
        return (R) this;
    }

    @SuppressWarnings("unchecked")
    @Override
    public R removeStyle(String style) {
        container.widget.removeStyleName(style);
        return (R) this;
    }

    @SuppressWarnings("unchecked")
    @Override
    public ICursor<R> cursor() {
        return new GWTCursor<R>((R) this, container.widget);
    }

}