Java tutorial
/** * Copyright 2010 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.livingstories.client.ui; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style; import com.google.gwt.event.logical.shared.ResizeEvent; import com.google.gwt.event.logical.shared.ResizeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.Window.ScrollEvent; import com.google.gwt.user.client.Window.ScrollHandler; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; /** * Panel that makes its contents scroll with the page. * However, the scrollable area is bounded by the box defined by this panel. * When the content hits a boundary, it will stop scrolling. */ public class AnchoredPanel extends SimplePanel { private boolean scrolling; private HandlerRegistration scrollHandler; private HandlerRegistration resizeHandler; @Override public void setWidget(Widget widget) { super.setWidget(widget); Style style = widget.getElement().getStyle(); style.setProperty("position", "relative"); style.setPropertyPx("left", 0); style.setPropertyPx("top", 0); removeHandlers(); scrollHandler = Window.addWindowScrollHandler(new ScrollHandler() { @Override public void onWindowScroll(ScrollEvent event) { reposition(); } }); resizeHandler = Window.addResizeHandler(new ResizeHandler() { @Override public void onResize(ResizeEvent event) { reposition(); } }); } public void remove() { super.clear(); removeHandlers(); } private void removeHandlers() { if (scrollHandler != null) { scrollHandler.removeHandler(); scrollHandler = null; } if (resizeHandler != null) { resizeHandler.removeHandler(); resizeHandler = null; } } public void reposition() { Widget content = getWidget(); Element boundingBox = getElement().getParentElement(); int windowTop = Window.getScrollTop(); int windowLeft = Window.getScrollLeft(); int topBound = boundingBox.getAbsoluteTop(); int bottomBound = topBound + boundingBox.getOffsetHeight() - content.getOffsetHeight(); if (!scrolling) { if (windowTop > topBound && windowTop < bottomBound) { scrolling = true; Style style = content.getElement().getStyle(); style.setProperty("position", "fixed"); style.setPropertyPx("top", 0); style.setPropertyPx("left", boundingBox.getAbsoluteLeft() - windowLeft); } } else { if (windowTop < topBound) { scrolling = false; Style style = content.getElement().getStyle(); style.setProperty("position", "relative"); style.setPropertyPx("top", 0); style.setPropertyPx("left", 0); } else if (windowTop > bottomBound) { scrolling = false; Style style = content.getElement().getStyle(); style.setProperty("position", "relative"); // Can't use bottom:0px here because the spacer has no height. // Even if we set the spacer's height to be 100%, it won't necessarily // work if this panel is in a table cell. style.setPropertyPx("top", bottomBound - topBound); style.setPropertyPx("left", 0); } else { content.getElement().getStyle().setPropertyPx("left", boundingBox.getAbsoluteLeft() - windowLeft); } } } }