com.google.gwt.user.client.ui.AbstractNativeScrollbar.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.user.client.ui.AbstractNativeScrollbar.java

Source

/*
 * Copyright 2011 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.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.event.dom.client.HasScrollHandlers;
import com.google.gwt.event.dom.client.ScrollEvent;
import com.google.gwt.event.dom.client.ScrollHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Event;

/**
 * Abstract parent class for scrollbars implemented using the native browser
 * scrollbars.
 */
public abstract class AbstractNativeScrollbar extends Widget implements HasScrollHandlers {

    private static int nativeHeight = -1;
    private static int nativeWidth = -1;
    private static boolean nativeRtl = false;

    /**
     * Get the height of a native horizontal scrollbar.
     * 
     * <p>
     * This method assumes that all native scrollbars on the page have the same
     * height.
     * 
     * @return the height in pixels
     */
    public static int getNativeScrollbarHeight() {
        maybeRecalculateNativeScrollbarSize();
        return nativeHeight;
    }

    /**
     * Get the width of a native vertical scrollbar.
     * 
     * <p>
     * This method assumes that all native vertical scrollbars on the page have
     * the same width.
     * 
     * @return the height in pixels
     */
    public static int getNativeScrollbarWidth() {
        maybeRecalculateNativeScrollbarSize();
        return nativeWidth;
    }

    /**
     * Check whether or not the native vertical scrollbar is aligned on the left
     * side of the scrollable element in RTL mode.
     * 
     * @return true if left aligned, false if not
     */
    public static boolean isScrollbarLeftAlignedInRtl() {
        maybeRecalculateNativeScrollbarSize();
        return nativeRtl;
    }

    /**
     * Recalculate the height and width of a native scrollbar.
     */
    private static void maybeRecalculateNativeScrollbarSize() {
        // Check if the size has already been calculated.
        if (nativeHeight > -1) {
            return;
        }

        // Create a scrollable element and attach it to the body.
        Element scrollable = Document.get().createDivElement();
        scrollable.getStyle().setPosition(Position.ABSOLUTE);
        scrollable.getStyle().setTop(0.0, Unit.PX);
        scrollable.getStyle().setLeft(0.0, Unit.PX);
        scrollable.getStyle().setHeight(100.0, Unit.PX);
        scrollable.getStyle().setWidth(100.0, Unit.PX);
        scrollable.getStyle().setOverflow(Overflow.SCROLL);
        scrollable.getStyle().setVisibility(Visibility.HIDDEN);
        scrollable.getStyle().setProperty("direction", "rtl");
        Document.get().getBody().appendChild(scrollable);

        // Add some content.
        Element content = Document.get().createDivElement();
        content.setInnerText("content");
        scrollable.appendChild(content);

        // Measure the height and width.
        nativeHeight = scrollable.getOffsetHeight() - scrollable.getClientHeight();
        nativeWidth = scrollable.getOffsetWidth() - scrollable.getClientWidth();
        nativeRtl = (content.getAbsoluteLeft() > scrollable.getAbsoluteLeft());

        // Detach the scrollable element.
        scrollable.removeFromParent();
    }

    public HandlerRegistration addScrollHandler(ScrollHandler handler) {
        // Sink the event on the scrollable element, not the root element.
        Event.sinkEvents(getScrollableElement(), Event.ONSCROLL);
        return addHandler(handler, ScrollEvent.getType());
    }

    /**
     * Get the scrollable element.
     * 
     * @return the scrollable element
     */
    protected abstract Element getScrollableElement();

    @Override
    protected void onAttach() {
        super.onAttach();

        /*
         * Attach the event listener in onAttach instead of onLoad so users cannot
         * accidentally override it.
         */
        Event.setEventListener(getScrollableElement(), this);
    }

    @Override
    protected void onDetach() {
        /*
         * Detach the event listener in onDetach instead of onUnload so users cannot
         * accidentally override it.
         */
        Event.setEventListener(getScrollableElement(), null);

        super.onDetach();
    }
}