jdk/src/share/classes/java/awt/ScrollPaneAdjustable.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/awt/ScrollPaneAdjustable.java	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,445 @@
+/*
+ * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package java.awt;
+
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import java.awt.peer.ScrollPanePeer;
+import java.io.Serializable;
+
+
+/**
+ * This class represents the state of a horizontal or vertical
+ * scrollbar of a <code>ScrollPane</code>.  Objects of this class are
+ * returned by <code>ScrollPane</code> methods.
+ *
+ * @since       1.4
+ */
+public class ScrollPaneAdjustable implements Adjustable, Serializable {
+
+    /**
+     * The <code>ScrollPane</code> this object is a scrollbar of.
+     * @serial
+     */
+    private ScrollPane sp;
+
+    /**
+     * Orientation of this scrollbar.
+     *
+     * @serial
+     * @see #getOrientation
+     * @see java.awt.Adjustable#HORIZONTAL
+     * @see java.awt.Adjustable#VERTICAL
+     */
+    private int orientation;
+
+    /**
+     * The value of this scrollbar.
+     * <code>value</code> should be greater than <code>minimum</code>
+     * and less than <code>maximum</code>
+     *
+     * @serial
+     * @see #getValue
+     * @see #setValue
+     */
+    private int value;
+
+    /**
+     * The minimum value of this scrollbar.
+     * This value can only be set by the <code>ScrollPane</code>.
+     * <p>
+     * <strong>ATTN:</strong> In current implementation
+     * <code>minimum</code> is always <code>0</code>.  This field can
+     * only be altered via <code>setSpan</code> method and
+     * <code>ScrollPane</code> always calls that method with
+     * <code>0</code> for the minimum.  <code>getMinimum</code> method
+     * always returns <code>0</code> without checking this field.
+     *
+     * @serial
+     * @see #getMinimum
+     * @see #setSpan(int, int, int)
+     */
+    private int minimum;
+
+    /**
+     * The maximum value of this scrollbar.
+     * This value can only be set by the <code>ScrollPane</code>.
+     *
+     * @serial
+     * @see #getMaximum
+     * @see #setSpan(int, int, int)
+     */
+    private int maximum;
+
+    /**
+     * The size of the visible portion of this scrollbar.
+     * This value can only be set by the <code>ScrollPane</code>.
+     *
+     * @serial
+     * @see #getVisibleAmount
+     * @see #setSpan(int, int, int)
+     */
+    private int visibleAmount;
+
+    /**
+     * The adjusting status of the <code>Scrollbar</code>.
+     * True if the value is in the process of changing as a result of
+     * actions being taken by the user.
+     *
+     * @see #getValueIsAdjusting
+     * @see #setValueIsAdjusting
+     * @since 1.4
+     */
+    private transient boolean isAdjusting;
+
+    /**
+     * The amount by which the scrollbar value will change when going
+     * up or down by a line.
+     * This value should be a non negative integer.
+     *
+     * @serial
+     * @see #getUnitIncrement
+     * @see #setUnitIncrement
+     */
+    private int unitIncrement  = 1;
+
+    /**
+     * The amount by which the scrollbar value will change when going
+     * up or down by a page.
+     * This value should be a non negative integer.
+     *
+     * @serial
+     * @see #getBlockIncrement
+     * @see #setBlockIncrement
+     */
+    private int blockIncrement = 1;
+
+    private AdjustmentListener adjustmentListener;
+
+    /**
+     * Error message for <code>AWTError</code> reported when one of
+     * the public but unsupported methods is called.
+     */
+    private static final String SCROLLPANE_ONLY =
+        "Can be set by scrollpane only";
+
+
+    /**
+     * Initialize JNI field and method ids.
+     */
+    private static native void initIDs();
+
+    static {
+        Toolkit.loadLibraries();
+        if (!GraphicsEnvironment.isHeadless()) {
+            initIDs();
+        }
+    }
+
+    /**
+     * JDK 1.1 serialVersionUID.
+     */
+    private static final long serialVersionUID = -3359745691033257079L;
+
+
+    /**
+     * Constructs a new object to represent specified scrollabar
+     * of the specified <code>ScrollPane</code>.
+     * Only ScrollPane creates instances of this class.
+     * @param sp           <code>ScrollPane</code>
+     * @param l            <code>AdjustmentListener</code> to add upon creation.
+     * @param orientation  specifies which scrollbar this object represents,
+     *                     can be either  <code>Adjustable.HORIZONTAL</code>
+     *                     or <code>Adjustable.VERTICAL</code>.
+     */
+    ScrollPaneAdjustable(ScrollPane sp, AdjustmentListener l, int orientation) {
+        this.sp = sp;
+        this.orientation = orientation;
+        addAdjustmentListener(l);
+    }
+
+    /**
+     * This is called by the scrollpane itself to update the
+     * <code>minimum</code>, <code>maximum</code> and
+     * <code>visible</code> values.  The scrollpane is the only one
+     * that should be changing these since it is the source of these
+     * values.
+     */
+    void setSpan(int min, int max, int visible) {
+        // adjust the values to be reasonable
+        minimum = min;
+        maximum = Math.max(max, minimum + 1);
+        visibleAmount = Math.min(visible, maximum - minimum);
+        visibleAmount = Math.max(visibleAmount, 1);
+        blockIncrement = Math.max((int)(visible * .90), 1);
+        setValue(value);
+    }
+
+    /**
+     * Returns the orientation of this scrollbar.
+     * @return    the orientation of this scrollbar, either
+     *            <code>Adjustable.HORIZONTAL</code> or
+     *            <code>Adjustable.VERTICAL</code>
+     */
+    public int getOrientation() {
+        return orientation;
+    }
+
+    /**
+     * This method should <strong>NOT</strong> be called by user code.
+     * This method is public for this class to properly implement
+     * <code>Adjustable</code> interface.
+     *
+     * @throws <code>AWTError</code>  Always throws an error when called.
+     */
+    public void setMinimum(int min) {
+        throw new AWTError(SCROLLPANE_ONLY);
+    }
+
+    public int getMinimum() {
+        // XXX: This relies on setSpan always being called with 0 for
+        // the minimum (which is currently true).
+        return 0;
+    }
+
+    /**
+     * This method should <strong>NOT</strong> be called by user code.
+     * This method is public for this class to properly implement
+     * <code>Adjustable</code> interface.
+     *
+     * @throws <code>AWTError</code>  Always throws an error when called.
+     */
+    public void setMaximum(int max) {
+        throw new AWTError(SCROLLPANE_ONLY);
+    }
+
+    public int getMaximum() {
+        return maximum;
+    }
+
+    public synchronized void setUnitIncrement(int u) {
+        if (u != unitIncrement) {
+            unitIncrement = u;
+            if (sp.peer != null) {
+                ScrollPanePeer peer = (ScrollPanePeer) sp.peer;
+                peer.setUnitIncrement(this, u);
+            }
+        }
+    }
+
+    public int getUnitIncrement() {
+        return unitIncrement;
+    }
+
+    public synchronized void setBlockIncrement(int b) {
+        blockIncrement = b;
+    }
+
+    public int getBlockIncrement() {
+        return blockIncrement;
+    }
+
+    /**
+     * This method should <strong>NOT</strong> be called by user code.
+     * This method is public for this class to properly implement
+     * <code>Adjustable</code> interface.
+     *
+     * @throws <code>AWTError</code>  Always throws an error when called.
+     */
+    public void setVisibleAmount(int v) {
+        throw new AWTError(SCROLLPANE_ONLY);
+    }
+
+    public int getVisibleAmount() {
+        return visibleAmount;
+    }
+
+
+    /**
+     * Sets the <code>valueIsAdjusting</code> property.
+     *
+     * @param b new adjustment-in-progress status
+     * @see #getValueIsAdjusting
+     * @since 1.4
+     */
+    public void setValueIsAdjusting(boolean b) {
+        if (isAdjusting != b) {
+            isAdjusting = b;
+            AdjustmentEvent e =
+                new AdjustmentEvent(this,
+                        AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+                        AdjustmentEvent.TRACK, value, b);
+            adjustmentListener.adjustmentValueChanged(e);
+        }
+    }
+
+    /**
+     * Returns true if the value is in the process of changing as a
+     * result of actions being taken by the user.
+     *
+     * @return the value of the <code>valueIsAdjusting</code> property
+     * @see #setValueIsAdjusting
+     */
+    public boolean getValueIsAdjusting() {
+        return isAdjusting;
+    }
+
+    /**
+     * Sets the value of this scrollbar to the specified value.
+     * <p>
+     * If the value supplied is less than the current minimum or
+     * greater than the current maximum, then one of those values is
+     * substituted, as appropriate.
+     *
+     * @param v the new value of the scrollbar
+     */
+    public void setValue(int v) {
+        setTypedValue(v, AdjustmentEvent.TRACK);
+    }
+
+    /**
+     * Sets the value of this scrollbar to the specified value.
+     * <p>
+     * If the value supplied is less than the current minimum or
+     * greater than the current maximum, then one of those values is
+     * substituted, as appropriate. Also, creates and dispatches
+     * the AdjustementEvent with specified type and value.
+     *
+     * @param v the new value of the scrollbar
+     * @param type the type of the scrolling operation occured
+     */
+    private void setTypedValue(int v, int type) {
+        v = Math.max(v, minimum);
+        v = Math.min(v, maximum - visibleAmount);
+
+        if (v != value) {
+            value = v;
+            // Synchronously notify the listeners so that they are
+            // guaranteed to be up-to-date with the Adjustable before
+            // it is mutated again.
+            AdjustmentEvent e =
+                new AdjustmentEvent(this,
+                        AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+                        type, value, isAdjusting);
+            adjustmentListener.adjustmentValueChanged(e);
+        }
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    /**
+     * Adds the specified adjustment listener to receive adjustment
+     * events from this <code>ScrollPaneAdjustable</code>.
+     * If <code>l</code> is <code>null</code>, no exception is thrown
+     * and no action is performed.
+     * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
+     * >AWT Threading Issues</a> for details on AWT's threading model.
+     *
+     * @param    l   the adjustment listener.
+     * @see      #removeAdjustmentListener
+     * @see      #getAdjustmentListeners
+     * @see      java.awt.event.AdjustmentListener
+     * @see      java.awt.event.AdjustmentEvent
+     */
+    public synchronized void addAdjustmentListener(AdjustmentListener l) {
+        if (l == null) {
+            return;
+        }
+        adjustmentListener = AWTEventMulticaster.add(adjustmentListener, l);
+    }
+
+    /**
+     * Removes the specified adjustment listener so that it no longer
+     * receives adjustment events from this <code>ScrollPaneAdjustable</code>.
+     * If <code>l</code> is <code>null</code>, no exception is thrown
+     * and no action is performed.
+     * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
+     * >AWT Threading Issues</a> for details on AWT's threading model.
+     *
+     * @param         l     the adjustment listener.
+     * @see           #addAdjustmentListener
+     * @see           #getAdjustmentListeners
+     * @see           java.awt.event.AdjustmentListener
+     * @see           java.awt.event.AdjustmentEvent
+     * @since         JDK1.1
+     */
+    public synchronized void removeAdjustmentListener(AdjustmentListener l){
+        if (l == null) {
+            return;
+        }
+        adjustmentListener = AWTEventMulticaster.remove(adjustmentListener, l);
+    }
+
+    /**
+     * Returns an array of all the adjustment listeners
+     * registered on this <code>ScrollPaneAdjustable</code>.
+     *
+     * @return all of this <code>ScrollPaneAdjustable</code>'s
+     *         <code>AdjustmentListener</code>s
+     *         or an empty array if no adjustment
+     *         listeners are currently registered
+     *
+     * @see           #addAdjustmentListener
+     * @see           #removeAdjustmentListener
+     * @see           java.awt.event.AdjustmentListener
+     * @see           java.awt.event.AdjustmentEvent
+     * @since 1.4
+     */
+    public synchronized AdjustmentListener[] getAdjustmentListeners() {
+        return (AdjustmentListener[])(AWTEventMulticaster.getListeners(
+                                      adjustmentListener,
+                                      AdjustmentListener.class));
+    }
+
+    /**
+     * Returns a string representation of this scrollbar and its values.
+     * @return    a string representation of this scrollbar.
+     */
+    public String toString() {
+        return getClass().getName() + "[" + paramString() + "]";
+    }
+
+    /**
+     * Returns a string representing the state of this scrollbar.
+     * This method is intended to be used only for debugging purposes,
+     * and the content and format of the returned string may vary
+     * between implementations.  The returned string may be empty but
+     * may not be <code>null</code>.
+     *
+     * @return      the parameter string of this scrollbar.
+     */
+    public String paramString() {
+        return ((orientation == Adjustable.VERTICAL ? "vertical,"
+                                                    :"horizontal,")
+                + "[0.."+maximum+"]"
+                + ",val=" + value
+                + ",vis=" + visibleAmount
+                + ",unit=" + unitIncrement
+                + ",block=" + blockIncrement
+                + ",isAdjusting=" + isAdjusting);
+    }
+}