gt:             if (nval != hbar.getValue()) {
context: /*
   * Copyright 2000,2005 wingS development team.
   *
   * This file is part of wingS (http://wingsframework.org).
   *
   * wingS is free software; you can redistribute it and/or modify
   * it under the terms of the GNU Lesser General Public License
   * as published by the Free Software Foundation; either version 2.1
   * of the License, or (at your option) any later version.
   *
   * Please see COPYING for the complete licence.
   */
  package org.wings;
  
  import java.awt.Adjustable;
  import java.awt.LayoutManager;
  import java.awt.Rectangle;
  
  import javax.swing.BoundedRangeModel;
  import javax.swing.event.ChangeEvent;
  import javax.swing.event.ChangeListener;
  import javax.swing.event.EventListenerList;
  
  import org.wings.event.SViewportChangeEvent;
  import org.wings.event.SViewportChangeListener;
  import org.wings.plaf.ScrollPaneCG;
  
  /**
   * A pane which allows to add {@link Scrollable} components on this pane
   * and display only a viewport of it. Can be used to scroll graphically
   * (default) or pages (using {@link SPageScroller} components.).
   *
   * @author <a href="mailto:haaf@mercatis.de">Armin Haaf</a>
   */
  public class SScrollPane
          extends SContainer
          implements javax.swing.ScrollPaneConstants {
  
      public static final int MODE_SCROLLING = 0;
      public static final int MODE_COMPLETE = 1;
      public static final int MODE_PAGING = 2;
  
      /**
       * The element which should be scrolled.
       */
      protected Scrollable scrollable;
  
      protected Adjustable verticalScrollBar = null;
  
      protected Adjustable horizontalScrollBar = null;
  
      protected int horizontalScrollBarPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED;
  
      protected int verticalScrollBarPolicy = VERTICAL_SCROLLBAR_AS_NEEDED;
  
      protected int horizontalExtent = 10;
  
      protected int verticalExtent = 10;
  
      protected int mode = MODE_SCROLLING;
  
      /**
       * While the (horizontal) maximum of columns displayed by this scrollpane
       * will never be greater than the number of available columns in the model
       * of the contained scrollable, the (vertical) maximum of rows displayed by
       * this scrollpane CAN be greater than the number of available rows in the
       * model of the contained scrollable. For example this might be true if ...
       *   - MODE == SCROLLING and this scrollpane's vertical extent was set to
       *     something greater than the number of available rows in the model, or
       *   - MODE == PAGING and there are not enough rows in the model in order
       *     to fill up the last page so that the full vertical extent is reached.
       * In such cases the scrollable's CG fills the difference with empty lines.
       * The "virtualViewportHeight" equals der number of available rows in the
       * scrollable's model (typically "scrollable.getScrollableViewport()") PLUS
       * the number of empty lines needed to fill the viewport until the vertical
       * extent of this scrollpane is reached.
       * If MODE == COMPLETE this variable equals the number of available rows.
       */
      protected int virtualViewportHeight;
  
      /**
       * Holds the viewport that the scrollable had before adding it to this
       * scrollpane. The scrollable's viewport is reset to this value, if it
       * is removed from the this scrollpane.
       */
      protected Rectangle backupViewport;
  
      protected SViewportSynchronizationModel horizontalModel = new SViewportSynchronizationModel(true);
  
      protected SViewportSynchronizationModel verticalModel = new SViewportSynchronizationModel(false);
  
  
      public SScrollPane() {
          super(new SScrollPaneLayout());
          setHorizontalScrollBar(new SScrollBar(SConstants.HORIZONTAL));
          setVerticalScrollBar(new SScrollBar(SConstants.VERTICAL));
      }
  
      public SScrollPane(SComponent c) {
          this();
          setViewportView(c);
      }
  
      /**
       * Sets the element which should be scrolled.
       *
       * @param c the element which should be scrolled.
       */
      protected void setScrollable(SComponent c) {
          Scrollable oldVal = this.scrollable;
          if (scrollable != null) {
              // reset the scrollable's viewport to the one
              // it had before adding it to this scrollpane
              scrollable.setViewportSize(backupViewport);
          }
  
          if (c instanceof Scrollable) {
              scrollable = (Scrollable) c;
              horizontalModel.setScrollable(scrollable);
              verticalModel.setScrollable(scrollable);
  
              // keep the scrollable's original viewport - the
              // one it had before adding it to this scrollpane
              backupViewport = scrollable.getViewportSize();
  
              // apply new viewport to scrollable
              setInitialViewportSize();
          } else {
              scrollable = null;
          }
  
          reload();
          propertyChangeSupport.firePropertyChange("scrollable", oldVal, this.scrollable);
      }
  
      /**
       * Returns the element which should be scrolled.
       *
       * @return the element which should be scrolled.
       */
      public final Scrollable getScrollable() {
          return scrollable;
      }
  
      /**
       * Sets the scrollable.
       * If there is already one, it will be removed first.
       *
       * @param view the component to add to the viewport
       */
      public void setViewportView(SComponent view) {
          //SComponent oldVal = t.b.d.;
          String oldVal = "oldValue";
          add(view, SScrollPaneLayout.VIEWPORT);
          propertyChangeSupport.firePropertyChange("viewportView", oldVal , view);
      }
        
      /**
       * Only {@link Scrollable scrollables} are allowed here!
       */
      public SComponent addComponent(SComponent c, Object constraint, int index) {
          if (c instanceof Scrollable || constraint == SScrollPaneLayout.VIEWPORT) {
              super.addComponent(c, SScrollPaneLayout.VIEWPORT, index);
              setScrollable(c);
          } else {
              super.addComponent(c, constraint, index);
          }
          return c;
      }
  
      protected SComponent addMe(SComponent c, Object constraint, int index) {
          return super.addComponent(c, constraint, index);
      }
  
      public int getMode() {
          return mode;
      }
  
      public void setMode(int mode) {
          int oldVal = this.mode;
          reloadIfChange(this.mode, mode);
          this.mode = mode;
          setInitialViewportSize();
          propertyChangeSupport.firePropertyChange("mode", oldVal, this.mode);
      }
  
      public void setCG(ScrollPaneCG cg) {
          super.setCG(cg);
      }
  
      /**
       * Returns the horizontal scroll bar.
       *
       * @return the scrollbar that controls the viewports horizontal view position
       */
      public Adjustable getHorizontalScrollBar() {
          return horizontalScrollBar;
      }
  
      /**
       * Sets the horizontal scroll bar.
       *
       * @param sb the scrollbar that controls the viewports horizontal view position
       */
      public void setHorizontalScrollBar(Adjustable sb) {
          setHorizontalScrollBar(sb, SScrollPaneLayout.SOUTH);
      }
  
      /**
       * Sets the horizontal scrollbar.
       *
       * @param sb         the scrollbar that controls the viewports horizontal view position
       * @param constraint the constraint for the {@link LayoutManager} of this {@link SContainer}.
       *                   The {@link LayoutManager} is per default {@link SScrollPaneLayout}.
       */
      public void setHorizontalScrollBar(Adjustable sb, String constraint) {
          Adjustable oldVal = this.horizontalScrollBar;
          if (horizontalScrollBar != null) {
              if (horizontalScrollBar instanceof SAbstractAdjustable)
                  ((SAbstractAdjustable) horizontalScrollBar).setModel(new SDefaultBoundedRangeModel());
  
              if (horizontalScrollBar instanceof SComponent)
                  super.remove((SComponent) horizontalScrollBar);
          }
  
          horizontalScrollBar = sb;
  
          if (horizontalScrollBar != null) {
              if (horizontalScrollBar instanceof SComponent)
                  super.addComponent((SComponent) horizontalScrollBar, constraint, getComponentCount());
  
              if (horizontalScrollBar instanceof SAbstractAdjustable) {
                  SAbstractAdjustable scrollbar = (SAbstractAdjustable) horizontalScrollBar;
                  if (scrollbar.getOrientation() == SConstants.HORIZONTAL)
                      scrollbar.setModel(horizontalModel);
                  else
                      scrollbar.setModel(verticalModel);
              }
  
              adoptScrollBarVisibility(horizontalScrollBar, horizontalScrollBarPolicy);
          }
  
          reload();
          propertyChangeSupport.firePropertyChange("horizontalScrollBar", oldVal, this.horizontalScrollBar);
      }
  
      /**
       * Returns the horizontal scroll bar policy value.
       *
       * @return the horizontal scrollbar policy.
       * @see #setHorizontalScrollBarPolicy(int)
       */
      public final int getHorizontalScrollBarPolicy() {
          return horizontalScrollBarPolicy;
      }
  
      /**
       * Returns the vertical scrollbar.
       *
       * @return the scrollbar that controls the viewports vertical view position
       */
      public final Adjustable getVerticalScrollBar() {
          return verticalScrollBar;
      }
  
      /**
       * Sets the vertical scroll bar.
       *
       * @param sb the scrollbar that controls the viewports vertical view position
       */
      public void setVerticalScrollBar(Adjustable sb) {
          setVerticalScrollBar(sb, SScrollPaneLayout.EAST);
      }
  
      /**
       * Sets the vertical scroll bar.
       *
       * @param sb         the scrollbar that controls the viewports vertical view position
       * @param constraint the constraint for the {@link LayoutManager} of this {@link SContainer}.
       *                   The {@link LayoutManager} is per default {@link SScrollPaneLayout}.
       */
      public void setVerticalScrollBar(Adjustable sb, String constraint) {
          Adjustable oldVal = this.verticalScrollBar;
          if (verticalScrollBar != null) {
              if (verticalScrollBar instanceof SAbstractAdjustable)
                  ((SAbstractAdjustable) verticalScrollBar).setModel(new SDefaultBoundedRangeModel());
  
              if (verticalScrollBar instanceof SComponent)
                  super.remove((SComponent) verticalScrollBar);
          }
  
          verticalScrollBar = sb;
  
          if (verticalScrollBar != null) {
              if (verticalScrollBar instanceof SComponent)
                  super.addComponent((SComponent) verticalScrollBar, constraint, getComponentCount());
  
              if (verticalScrollBar instanceof SAbstractAdjustable) {
                  SAbstractAdjustable scrollbar = (SAbstractAdjustable) verticalScrollBar;
                  if (scrollbar.getOrientation() == SConstants.HORIZONTAL)
                      scrollbar.setModel(horizontalModel);
                  else
                      scrollbar.setModel(verticalModel);
              }
  
              adoptScrollBarVisibility(verticalScrollBar, verticalScrollBarPolicy);
          }
  
          reload();
          propertyChangeSupport.firePropertyChange("verticalScrollBar", oldVal, this.verticalScrollBar);
      }
  
      /**
       * Returns the vertical scroll bar policy value.
       *
       * @return the vertical scrollbar policy.
       * @see #setVerticalScrollBarPolicy(int)
       */
      public final int getVerticalScrollBarPolicy() {
          return verticalScrollBarPolicy;
      }
  
      /**
       * Determines when the horizontal scrollbar appears in the scrollpane.
       * The options are:
       * <li><code>SScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED</code></li>
       * <li><code>SScrollPane.HORIZONTAL_SCROLLBAR_NEVER</code></li>
       * <li><code>SScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS</code></li>
       */
      public void setHorizontalScrollBarPolicy(int policy) {
          if (policy != horizontalScrollBarPolicy) {
              int oldVal = this.horizontalScrollBarPolicy;
              horizontalScrollBarPolicy = policy;
              adoptScrollBarVisibility(horizontalScrollBar, policy);
              reload();
              propertyChangeSupport.firePropertyChange("horizontalScrollBar", oldVal, this.horizontalScrollBarPolicy);
          }
      }
  
      /**
       * Determines when the vertical scrollbar appears in the scrollpane.
       * The options are:
       * <li><code>SScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED</code></li>
       * <li><code>SScrollPane.VERTICAL_SCROLLBAR_NEVER</code></li>
       * <li><code>SScrollPane.VERTICAL_SCROLLBAR_ALWAYS</code></li>
       */
      public void setVerticalScrollBarPolicy(int policy) {
          if (policy != verticalScrollBarPolicy) {
              int oldVal = this.verticalScrollBarPolicy;
              verticalScrollBarPolicy = policy;
              adoptScrollBarVisibility(verticalScrollBar, policy);
              reload();
              propertyChangeSupport.firePropertyChange("verticalScrollBarPolicy", oldVal, this.verticalScrollBarPolicy);
          }
      }
  
      public void setHorizontalExtent(int horizontalExtent) {
          int oldVal = this.horizontalExtent;
          reloadIfChange(this.horizontalExtent, horizontalExtent);
          this.horizontalExtent = horizontalExtent;
          propertyChangeSupport.firePropertyChange("horizontalExtent", oldVal, this.horizontalExtent);
          horizontalModel.setExtent(horizontalExtent);
      }
  
      public final int getHorizontalExtent() {
          return horizontalExtent;
      }
  
      public void setVerticalExtent(int verticalExtent) {
          int oldVal = this.verticalExtent;
          reloadIfChange(this.verticalExtent, verticalExtent);
          this.verticalExtent = verticalExtent;
          verticalModel.setExtent(verticalExtent);
          propertyChangeSupport.firePropertyChange("verticalExtent", oldVal, this.verticalExtent);
      }
  
      public final int getVerticalExtent() {
          return verticalExtent;
      }
  
      public void scrollRectToVisible(Rectangle aRect) {
          Rectangle viewport = scrollable.getScrollableViewportSize();
  
          // This should never happen. If it happen we got a serious
          // problem, because we cannot determine what to scroll...
          if (viewport == null) {
              return;
          }
  
          Adjustable hbar = getHorizontalScrollBar();
          if (hbar != null &&
                  getHorizontalScrollBarPolicy() != HORIZONTAL_SCROLLBAR_NEVER) {
              int nval = scrollValue(hbar.getValue(), getHorizontalExtent(),
                      aRect.x, aRect.width,
                      hbar.getUnitIncrement());
  