| 1 | /* Copyright (C) 2000 Free Software Foundation
|
|---|
| 2 |
|
|---|
| 3 | This file is part of libgcj.
|
|---|
| 4 |
|
|---|
| 5 | This software is copyrighted work licensed under the terms of the
|
|---|
| 6 | Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
|---|
| 7 | details. */
|
|---|
| 8 |
|
|---|
| 9 | package java.awt;
|
|---|
| 10 |
|
|---|
| 11 | import java.awt.event.AdjustmentListener;
|
|---|
| 12 | import java.awt.peer.ScrollPanePeer;
|
|---|
| 13 |
|
|---|
| 14 | /** A ScrollPane is a component that has vertical and horizontal
|
|---|
| 15 | * scrollbars as well as a single child which is scrolled by them.
|
|---|
| 16 | * @author Tom Tromey <[email protected]>
|
|---|
| 17 | * @date December 31, 2000
|
|---|
| 18 | */
|
|---|
| 19 | public class ScrollPane extends Container
|
|---|
| 20 | {
|
|---|
| 21 | /** This indicates that scrollbars should only be displayed when
|
|---|
| 22 | * needed. */
|
|---|
| 23 | public static final int SCROLLBARS_AS_NEEDED = 0;
|
|---|
| 24 | /** This indicates that scrollbars should always be displayed. */
|
|---|
| 25 | public static final int SCROLLBARS_ALWAYS = 1;
|
|---|
| 26 | /** This indicates that scrollbars should never be displayed. */
|
|---|
| 27 | public static final int SCROLLBARS_NEVER = 2;
|
|---|
| 28 |
|
|---|
| 29 | /** Create a new ScrollPane object using the indicated scrollbar
|
|---|
| 30 | * display policy. If the policy is not specified it defaults to
|
|---|
| 31 | * SCROLLBARS_AS_NEEDED. The default size of this component is
|
|---|
| 32 | * 100x100.
|
|---|
| 33 | * @param policy The scrollbar display policy
|
|---|
| 34 | */
|
|---|
| 35 | public ScrollPane ()
|
|---|
| 36 | {
|
|---|
| 37 | this (SCROLLBARS_AS_NEEDED);
|
|---|
| 38 | }
|
|---|
| 39 |
|
|---|
| 40 | public ScrollPane (int policy)
|
|---|
| 41 | {
|
|---|
| 42 | if (policy != SCROLLBARS_AS_NEEDED
|
|---|
| 43 | && policy != SCROLLBARS_ALWAYS
|
|---|
| 44 | && policy != SCROLLBARS_NEVER)
|
|---|
| 45 | throw new IllegalArgumentException ("invalid value for policy");
|
|---|
| 46 |
|
|---|
| 47 | this.policy = policy;
|
|---|
| 48 | setSize (100, 100);
|
|---|
| 49 | }
|
|---|
| 50 |
|
|---|
| 51 | /** Add a component to this ScrollPane.
|
|---|
| 52 | * @param comp The component to add
|
|---|
| 53 | * @param constraints Constraints. This is ignored.
|
|---|
| 54 | * @param pos Position. This must be <= 0, but is otherwise ignored.
|
|---|
| 55 | */
|
|---|
| 56 | protected final void addImpl (Component comp, Object constraints,
|
|---|
| 57 | int pos)
|
|---|
| 58 | {
|
|---|
| 59 | if (pos > 0)
|
|---|
| 60 | throw new IllegalArgumentException ("pos must be <= 0");
|
|---|
| 61 |
|
|---|
| 62 | if (ncomponents > 0)
|
|---|
| 63 | remove (component[0]);
|
|---|
| 64 |
|
|---|
| 65 | if (comp.isLightweight ())
|
|---|
| 66 | {
|
|---|
| 67 | Panel p = new Panel ();
|
|---|
| 68 | p.add (comp);
|
|---|
| 69 | comp = p;
|
|---|
| 70 | }
|
|---|
| 71 |
|
|---|
| 72 | super.addImpl (comp, constraints, pos);
|
|---|
| 73 | }
|
|---|
| 74 |
|
|---|
| 75 | /** This creates the component's peer. */
|
|---|
| 76 | public void addNotify ()
|
|---|
| 77 | {
|
|---|
| 78 | if (peer == null)
|
|---|
| 79 | peer = getToolkit ().createScrollPane (this);
|
|---|
| 80 | super.addNotify ();
|
|---|
| 81 | }
|
|---|
| 82 |
|
|---|
| 83 | /** Lays out the components in this container. */
|
|---|
| 84 | public void doLayout ()
|
|---|
| 85 | {
|
|---|
| 86 | ScrollPanePeer spp = (ScrollPanePeer) peer;
|
|---|
| 87 | Dimension c = component[0].getPreferredSize ();
|
|---|
| 88 | component[0].setSize (c.width, c.height);
|
|---|
| 89 | spp.childResized (c.width, c.height);
|
|---|
| 90 | // Update the scrollbar position to the closest valid value.
|
|---|
| 91 | setScrollPosition (hscroll.getValue (), vscroll.getValue ());
|
|---|
| 92 | }
|
|---|
| 93 |
|
|---|
| 94 | /** Returns an Adjustable representing the horizontal scrollbar.
|
|---|
| 95 | * The methods setMaximum, setMinimum, and setVisibleAmount should
|
|---|
| 96 | * not be called on this Adjustable. They will throw AWTError if
|
|---|
| 97 | * called.
|
|---|
| 98 | */
|
|---|
| 99 | public Adjustable getHAdjustable ()
|
|---|
| 100 | {
|
|---|
| 101 | return hscroll;
|
|---|
| 102 | }
|
|---|
| 103 |
|
|---|
| 104 | /** Returns the height of the horizontal scrollbar. */
|
|---|
| 105 | public int getHScrollbarHeight ()
|
|---|
| 106 | {
|
|---|
| 107 | if (peer == null)
|
|---|
| 108 | return 0;
|
|---|
| 109 | ScrollPanePeer spp = (ScrollPanePeer) peer;
|
|---|
| 110 | return spp.getHScrollbarHeight ();
|
|---|
| 111 | }
|
|---|
| 112 |
|
|---|
| 113 | /** Returns the scrollbar display policy. */
|
|---|
| 114 | public int getScrollbarDisplayPolicy ()
|
|---|
| 115 | {
|
|---|
| 116 | return policy;
|
|---|
| 117 | }
|
|---|
| 118 |
|
|---|
| 119 | /** Returns the viewport's scroll position. */
|
|---|
| 120 | public Point getScrollPosition ()
|
|---|
| 121 | {
|
|---|
| 122 | return new Point (hscroll.getValue (), vscroll.getValue ());
|
|---|
| 123 | }
|
|---|
| 124 |
|
|---|
| 125 | /** Returns an Adjustable representing the vertical scrollbar.
|
|---|
| 126 | * The methods setMaximum, setMinimum, and setVisibleAmount should
|
|---|
| 127 | * not be called on this Adjustable. They will throw AWTError if
|
|---|
| 128 | * called.
|
|---|
| 129 | */
|
|---|
| 130 | public Adjustable getVAdjustable ()
|
|---|
| 131 | {
|
|---|
| 132 | return vscroll;
|
|---|
| 133 | }
|
|---|
| 134 |
|
|---|
| 135 | /** Returns the size of the viewport. */
|
|---|
| 136 | public Dimension getViewportSize ()
|
|---|
| 137 | {
|
|---|
| 138 | // Note: according to the online docs, the Insets are
|
|---|
| 139 | // automatically updated by the peer to include the scrollbar
|
|---|
| 140 | // sizes.
|
|---|
| 141 | Insets ins = getInsets ();
|
|---|
| 142 | int myw = width - ins.left - ins.right;
|
|---|
| 143 | int myh = height - ins.top - ins.bottom;
|
|---|
| 144 |
|
|---|
| 145 | Dimension cs;
|
|---|
| 146 | if (ncomponents > 0)
|
|---|
| 147 | cs = component[0].getPreferredSize ();
|
|---|
| 148 | else
|
|---|
| 149 | cs = new Dimension (myw, myh);
|
|---|
| 150 |
|
|---|
| 151 | // A little optimization -- reuse the Dimension.
|
|---|
| 152 | cs.setSize (myw, myh);
|
|---|
| 153 | return cs;
|
|---|
| 154 | }
|
|---|
| 155 |
|
|---|
| 156 | /** Returns the width of the vertical scrollbar. */
|
|---|
| 157 | public int getVScrollbarWidth ()
|
|---|
| 158 | {
|
|---|
| 159 | if (peer == null)
|
|---|
| 160 | return 0;
|
|---|
| 161 | ScrollPanePeer spp = (ScrollPanePeer) peer;
|
|---|
| 162 | return spp.getVScrollbarWidth ();
|
|---|
| 163 | }
|
|---|
| 164 |
|
|---|
| 165 | /** Generates a String representation of this ScrollPane's state. */
|
|---|
| 166 | public String paramString ()
|
|---|
| 167 | {
|
|---|
| 168 | return ("[" + getClass ().getName ()
|
|---|
| 169 | + ": " + ((ncomponents > 0) ? component[0].paramString () : "")
|
|---|
| 170 | + "]");
|
|---|
| 171 | }
|
|---|
| 172 |
|
|---|
| 173 | /** Set the layout manager for this component. ScrollPane has its
|
|---|
| 174 | * own layout manager and overrides this method so that the layout
|
|---|
| 175 | * manager cannot be changed.
|
|---|
| 176 | * @param m The new layout manager (ignored)
|
|---|
| 177 | */
|
|---|
| 178 | public final void setLayout (LayoutManager m)
|
|---|
| 179 | {
|
|---|
| 180 | // Nothing.
|
|---|
| 181 | }
|
|---|
| 182 |
|
|---|
| 183 | /** Sets the scroll position for this ScrollPane. If the point if
|
|---|
| 184 | * out of range it is silently moved within range.
|
|---|
| 185 | * @param x The x coordinate
|
|---|
| 186 | * @param y The y coordinate
|
|---|
| 187 | */
|
|---|
| 188 | public void setScrollPosition (int x, int y)
|
|---|
| 189 | {
|
|---|
| 190 | // According to the JCL we throw a NullPointerException if there
|
|---|
| 191 | // is no child.
|
|---|
| 192 | if (ncomponents == 0)
|
|---|
| 193 | throw new NullPointerException ("no child in ScrollPane");
|
|---|
| 194 |
|
|---|
| 195 | Dimension child_d = component[0].getPreferredSize ();
|
|---|
| 196 | Dimension our_d = getViewportSize ();
|
|---|
| 197 |
|
|---|
| 198 | int xmax = Math.max (0, child_d.width - our_d.width);
|
|---|
| 199 | int ymax = Math.max (0, child_d.height - our_d.height);
|
|---|
| 200 |
|
|---|
| 201 | if (x < 0)
|
|---|
| 202 | x = 0;
|
|---|
| 203 | else if (x > xmax)
|
|---|
| 204 | x = xmax;
|
|---|
| 205 | if (y < 0)
|
|---|
| 206 | y = 0;
|
|---|
| 207 | else if (y > ymax)
|
|---|
| 208 | y = ymax;
|
|---|
| 209 |
|
|---|
| 210 | ScrollPanePeer spp = (ScrollPanePeer) peer;
|
|---|
| 211 | spp.setScrollPosition (x, y);
|
|---|
| 212 | }
|
|---|
| 213 |
|
|---|
| 214 | /** Sets the scroll position for this ScrollPane. If the point if
|
|---|
| 215 | * out of range it is silently moved within range.
|
|---|
| 216 | * @param p The new point
|
|---|
| 217 | */
|
|---|
| 218 | public void setScrollPosition (Point p)
|
|---|
| 219 | {
|
|---|
| 220 | setScrollPosition (p.x, p.y);
|
|---|
| 221 | }
|
|---|
| 222 |
|
|---|
| 223 | // This implements the Adjustable for each scrollbar. The
|
|---|
| 224 | // expectation is that the peer will look at these objects directly
|
|---|
| 225 | // and modify the values in them when the user manipulates the
|
|---|
| 226 | // scrollbars. This has to be done from CNI to bypass Java
|
|---|
| 227 | // protection rules. The peer should also take care of calling the
|
|---|
| 228 | // adjustment listeners.
|
|---|
| 229 | class ScrollPaneAdjustable implements Adjustable
|
|---|
| 230 | {
|
|---|
| 231 | AdjustmentListener listeners;
|
|---|
| 232 | int orient;
|
|---|
| 233 | int unit;
|
|---|
| 234 | int block;
|
|---|
| 235 | int value;
|
|---|
| 236 |
|
|---|
| 237 | public ScrollPaneAdjustable (int orient)
|
|---|
| 238 | {
|
|---|
| 239 | this.orient = orient;
|
|---|
| 240 | }
|
|---|
| 241 |
|
|---|
| 242 | public void addAdjustmentListener (AdjustmentListener l)
|
|---|
| 243 | {
|
|---|
| 244 | listeners = AWTEventMulticaster.add (listeners, l);
|
|---|
| 245 | }
|
|---|
| 246 |
|
|---|
| 247 | public int getBlockIncrement ()
|
|---|
| 248 | {
|
|---|
| 249 | return block;
|
|---|
| 250 | }
|
|---|
| 251 |
|
|---|
| 252 | public int getMaximum ()
|
|---|
| 253 | {
|
|---|
| 254 | Dimension child_d = component[0].getPreferredSize ();
|
|---|
| 255 | Dimension our_d = getViewportSize ();
|
|---|
| 256 |
|
|---|
| 257 | int xmax = Math.max (0, child_d.width - our_d.width);
|
|---|
| 258 | int ymax = Math.max (0, child_d.height - our_d.height);
|
|---|
| 259 |
|
|---|
| 260 | return (orient == Adjustable.HORIZONTAL) ? xmax : ymax;
|
|---|
| 261 | }
|
|---|
| 262 |
|
|---|
| 263 | public int getMinimum ()
|
|---|
| 264 | {
|
|---|
| 265 | return 0;
|
|---|
| 266 | }
|
|---|
| 267 |
|
|---|
| 268 | public int getOrientation ()
|
|---|
| 269 | {
|
|---|
| 270 | return orient;
|
|---|
| 271 | }
|
|---|
| 272 |
|
|---|
| 273 | public int getUnitIncrement ()
|
|---|
| 274 | {
|
|---|
| 275 | return unit;
|
|---|
| 276 | }
|
|---|
| 277 |
|
|---|
| 278 | public int getValue ()
|
|---|
| 279 | {
|
|---|
| 280 | return value;
|
|---|
| 281 | }
|
|---|
| 282 |
|
|---|
| 283 | public int getVisibleAmount ()
|
|---|
| 284 | {
|
|---|
| 285 | Dimension d = getViewportSize ();
|
|---|
| 286 | return (orient == Adjustable.HORIZONTAL) ? d.width : d.height;
|
|---|
| 287 | }
|
|---|
| 288 |
|
|---|
| 289 | public void removeAdjustmentListener (AdjustmentListener l)
|
|---|
| 290 | {
|
|---|
| 291 | listeners = AWTEventMulticaster.remove (listeners, l);
|
|---|
| 292 | }
|
|---|
| 293 |
|
|---|
| 294 | public void setBlockIncrement (int b)
|
|---|
| 295 | {
|
|---|
| 296 | throw new AWTError ("can't use setBlockIncrement on this Adjustable");
|
|---|
| 297 | }
|
|---|
| 298 |
|
|---|
| 299 | public void setMaximum (int max)
|
|---|
| 300 | {
|
|---|
| 301 | throw new AWTError ("can't use setMaximum on this Adjustable");
|
|---|
| 302 | }
|
|---|
| 303 |
|
|---|
| 304 | public void setMinimum (int min)
|
|---|
| 305 | {
|
|---|
| 306 | throw new AWTError ("can't use setMinimum on this Adjustable");
|
|---|
| 307 | }
|
|---|
| 308 |
|
|---|
| 309 | public void setUnitIncrement (int u)
|
|---|
| 310 | {
|
|---|
| 311 | unit = u;
|
|---|
| 312 | if (peer != null)
|
|---|
| 313 | {
|
|---|
| 314 | ScrollPanePeer spp = (ScrollPanePeer) peer;
|
|---|
| 315 | spp.setUnitIncrement (this, u);
|
|---|
| 316 | }
|
|---|
| 317 | }
|
|---|
| 318 |
|
|---|
| 319 | public void setValue (int v)
|
|---|
| 320 | {
|
|---|
| 321 | value = v;
|
|---|
| 322 | if (peer != null)
|
|---|
| 323 | {
|
|---|
| 324 | ScrollPanePeer spp = (ScrollPanePeer) peer;
|
|---|
| 325 | spp.setValue (this, v);
|
|---|
| 326 | }
|
|---|
| 327 | }
|
|---|
| 328 |
|
|---|
| 329 | public void setVisibleAmount (int v)
|
|---|
| 330 | {
|
|---|
| 331 | throw new AWTError ("can't use setVisibleAmount on this Adjustable");
|
|---|
| 332 | }
|
|---|
| 333 | }
|
|---|
| 334 |
|
|---|
| 335 | ScrollPaneAdjustable hscroll
|
|---|
| 336 | = new ScrollPaneAdjustable (Adjustable.HORIZONTAL);
|
|---|
| 337 | ScrollPaneAdjustable vscroll
|
|---|
| 338 | = new ScrollPaneAdjustable (Adjustable.VERTICAL);
|
|---|
| 339 | int policy;
|
|---|
| 340 | }
|
|---|