Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/src/share/classes/javax/swing/JScrollPane.java
+++ new/src/share/classes/javax/swing/JScrollPane.java
1 1 /*
2 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation. Oracle designates this
8 8 * particular file as subject to the "Classpath" exception as provided
9 9 * by Oracle in the LICENSE file that accompanied this code.
10 10 *
11 11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 14 * version 2 for more details (a copy is included in the LICENSE file that
15 15 * accompanied this code).
16 16 *
17 17 * You should have received a copy of the GNU General Public License version
18 18 * 2 along with this work; if not, write to the Free Software Foundation,
19 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 20 *
21 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 22 * or visit www.oracle.com if you need additional information or have any
23 23 * questions.
24 24 */
25 25
26 26 package javax.swing;
27 27
28 28 import javax.swing.plaf.*;
29 29 import javax.swing.border.*;
30 30 import javax.swing.event.*;
31 31 import javax.accessibility.*;
32 32
33 33 import java.awt.Component;
34 34 import java.awt.ComponentOrientation;
35 35 import java.awt.Rectangle;
36 36 import java.awt.Insets;
37 37 import java.awt.LayoutManager;
38 38 import java.awt.Point;
39 39
40 40 import java.io.ObjectOutputStream;
41 41 import java.io.IOException;
42 42
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
43 43 import java.beans.PropertyChangeEvent;
44 44 import java.beans.PropertyChangeListener;
45 45 import java.beans.Transient;
46 46
47 47 /**
48 48 * Provides a scrollable view of a lightweight component.
49 49 * A <code>JScrollPane</code> manages a viewport, optional
50 50 * vertical and horizontal scroll bars, and optional row and
51 51 * column heading viewports.
52 52 * You can find task-oriented documentation of <code>JScrollPane</code> in
53 - * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html">How to Use Scroll Panes</a>,
53 + * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html">How to Use Scroll Panes</a>,
54 54 * a section in <em>The Java Tutorial</em>. Note that
55 55 * <code>JScrollPane</code> does not support heavyweight components.
56 56 *
57 57 * <TABLE STYLE="FLOAT:RIGHT" BORDER="0" SUMMARY="layout">
58 58 * <TR>
59 59 * <TD ALIGN="CENTER">
60 60 * <P STYLE="TEXT-ALIGN:CENTER"><IMG SRC="doc-files/JScrollPane-1.gif"
61 61 * alt="The following text describes this image."
62 62 * WIDTH="256" HEIGHT="248" STYLE="FLOAT:BOTTOM; BORDER:0px">
63 63 * </TD>
64 64 * </TR>
65 65 * </TABLE>
66 66 * The <code>JViewport</code> provides a window,
67 67 * or "viewport" onto a data
68 68 * source -- for example, a text file. That data source is the
69 69 * "scrollable client" (aka data model) displayed by the
70 70 * <code>JViewport</code> view.
71 71 * A <code>JScrollPane</code> basically consists of <code>JScrollBar</code>s,
72 72 * a <code>JViewport</code>, and the wiring between them,
73 73 * as shown in the diagram at right.
74 74 * <p>
75 75 * In addition to the scroll bars and viewport,
76 76 * a <code>JScrollPane</code> can have a
77 77 * column header and a row header. Each of these is a
78 78 * <code>JViewport</code> object that
79 79 * you specify with <code>setRowHeaderView</code>,
80 80 * and <code>setColumnHeaderView</code>.
81 81 * The column header viewport automatically scrolls left and right, tracking
82 82 * the left-right scrolling of the main viewport.
83 83 * (It never scrolls vertically, however.)
84 84 * The row header acts in a similar fashion.
85 85 * <p>
86 86 * Where two scroll bars meet, the row header meets the column header,
87 87 * or a scroll bar meets one of the headers, both components stop short
88 88 * of the corner, leaving a rectangular space which is, by default, empty.
89 89 * These spaces can potentially exist in any number of the four corners.
90 90 * In the previous diagram, the top right space is present and identified
91 91 * by the label "corner component".
92 92 * <p>
93 93 * Any number of these empty spaces can be replaced by using the
94 94 * <code>setCorner</code> method to add a component to a particular corner.
95 95 * (Note: The same component cannot be added to multiple corners.)
96 96 * This is useful if there's
97 97 * some extra decoration or function you'd like to add to the scroll pane.
98 98 * The size of each corner component is entirely determined by the size of the
99 99 * headers and/or scroll bars that surround it.
100 100 * <p>
101 101 * A corner component will only be visible if there is an empty space in that
102 102 * corner for it to exist in. For example, consider a component set into the
103 103 * top right corner of a scroll pane with a column header. If the scroll pane's
104 104 * vertical scrollbar is not present, perhaps because the view component hasn't
105 105 * grown large enough to require it, then the corner component will not be
106 106 * shown (since there is no empty space in that corner created by the meeting
107 107 * of the header and vertical scroll bar). Forcing the scroll bar to always be
108 108 * shown, using
109 109 * <code>setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_ALWAYS)</code>,
110 110 * will ensure that the space for the corner component always exists.
111 111 * <p>
112 112 * To add a border around the main viewport,
113 113 * you can use <code>setViewportBorder</code>.
114 114 * (Of course, you can also add a border around the whole scroll pane using
115 115 * <code>setBorder</code>.)
116 116 * <p>
117 117 * A common operation to want to do is to set the background color that will
118 118 * be used if the main viewport view is smaller than the viewport, or is
119 119 * not opaque. This can be accomplished by setting the background color
120 120 * of the viewport, via <code>scrollPane.getViewport().setBackground()</code>.
121 121 * The reason for setting the color of the viewport and not the scrollpane
122 122 * is that by default <code>JViewport</code> is opaque
123 123 * which, among other things, means it will completely fill
124 124 * in its background using its background color. Therefore when
125 125 * <code>JScrollPane</code> draws its background the viewport will
126 126 * usually draw over it.
127 127 * <p>
128 128 * By default <code>JScrollPane</code> uses <code>ScrollPaneLayout</code>
129 129 * to handle the layout of its child Components. <code>ScrollPaneLayout</code>
130 130 * determines the size to make the viewport view in one of two ways:
131 131 * <ol>
132 132 * <li>If the view implements <code>Scrollable</code>
133 133 * a combination of <code>getPreferredScrollableViewportSize</code>,
134 134 * <code>getScrollableTracksViewportWidth</code> and
135 135 * <code>getScrollableTracksViewportHeight</code>is used, otherwise
136 136 * <li><code>getPreferredSize</code> is used.
137 137 * </ol>
138 138 * <p>
139 139 * <strong>Warning:</strong> Swing is not thread safe. For more
140 140 * information see <a
141 141 * href="package-summary.html#threading">Swing's Threading
142 142 * Policy</a>.
143 143 * <p>
144 144 * <strong>Warning:</strong>
145 145 * Serialized objects of this class will not be compatible with
146 146 * future Swing releases. The current serialization support is
147 147 * appropriate for short term storage or RMI between applications running
148 148 * the same version of Swing. As of 1.4, support for long term storage
149 149 * of all JavaBeans™
150 150 * has been added to the <code>java.beans</code> package.
151 151 * Please see {@link java.beans.XMLEncoder}.
152 152 *
153 153 * @see JScrollBar
154 154 * @see JViewport
155 155 * @see ScrollPaneLayout
156 156 * @see Scrollable
157 157 * @see Component#getPreferredSize
158 158 * @see #setViewportView
159 159 * @see #setRowHeaderView
160 160 * @see #setColumnHeaderView
161 161 * @see #setCorner
162 162 * @see #setViewportBorder
163 163 *
164 164 * @beaninfo
165 165 * attribute: isContainer true
166 166 * attribute: containerDelegate getViewport
167 167 * description: A specialized container that manages a viewport, optional scrollbars and headers
168 168 *
169 169 * @author Hans Muller
170 170 */
171 171 public class JScrollPane extends JComponent implements ScrollPaneConstants, Accessible
172 172 {
173 173 private Border viewportBorder;
174 174
175 175 /**
176 176 * @see #getUIClassID
177 177 * @see #readObject
178 178 */
179 179 private static final String uiClassID = "ScrollPaneUI";
180 180
181 181 /**
182 182 * The display policy for the vertical scrollbar.
183 183 * The default is
184 184 * <code>ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED</code>.
185 185 * @see #setVerticalScrollBarPolicy
186 186 */
187 187 protected int verticalScrollBarPolicy = VERTICAL_SCROLLBAR_AS_NEEDED;
188 188
189 189
190 190 /**
191 191 * The display policy for the horizontal scrollbar.
192 192 * The default is
193 193 * <code>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED</code>.
194 194 * @see #setHorizontalScrollBarPolicy
195 195 */
196 196 protected int horizontalScrollBarPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED;
197 197
198 198
199 199 /**
200 200 * The scrollpane's viewport child. Default is an empty
201 201 * <code>JViewport</code>.
202 202 * @see #setViewport
203 203 */
204 204 protected JViewport viewport;
205 205
206 206
207 207 /**
208 208 * The scrollpane's vertical scrollbar child.
209 209 * Default is a <code>JScrollBar</code>.
210 210 * @see #setVerticalScrollBar
211 211 */
212 212 protected JScrollBar verticalScrollBar;
213 213
214 214
215 215 /**
216 216 * The scrollpane's horizontal scrollbar child.
217 217 * Default is a <code>JScrollBar</code>.
218 218 * @see #setHorizontalScrollBar
219 219 */
220 220 protected JScrollBar horizontalScrollBar;
221 221
222 222
223 223 /**
224 224 * The row header child. Default is <code>null</code>.
225 225 * @see #setRowHeader
226 226 */
227 227 protected JViewport rowHeader;
228 228
229 229
230 230 /**
231 231 * The column header child. Default is <code>null</code>.
232 232 * @see #setColumnHeader
233 233 */
234 234 protected JViewport columnHeader;
235 235
236 236
237 237 /**
238 238 * The component to display in the lower left corner.
239 239 * Default is <code>null</code>.
240 240 * @see #setCorner
241 241 */
242 242 protected Component lowerLeft;
243 243
244 244
245 245 /**
246 246 * The component to display in the lower right corner.
247 247 * Default is <code>null</code>.
248 248 * @see #setCorner
249 249 */
250 250 protected Component lowerRight;
251 251
252 252
253 253 /**
254 254 * The component to display in the upper left corner.
255 255 * Default is <code>null</code>.
256 256 * @see #setCorner
257 257 */
258 258 protected Component upperLeft;
259 259
260 260
261 261 /**
262 262 * The component to display in the upper right corner.
263 263 * Default is <code>null</code>.
264 264 * @see #setCorner
265 265 */
266 266 protected Component upperRight;
267 267
268 268 /*
269 269 * State flag for mouse wheel scrolling
270 270 */
271 271 private boolean wheelScrollState = true;
272 272
273 273 /**
274 274 * Creates a <code>JScrollPane</code> that displays the view
275 275 * component in a viewport
276 276 * whose view position can be controlled with a pair of scrollbars.
277 277 * The scrollbar policies specify when the scrollbars are displayed,
278 278 * For example, if <code>vsbPolicy</code> is
279 279 * <code>VERTICAL_SCROLLBAR_AS_NEEDED</code>
280 280 * then the vertical scrollbar only appears if the view doesn't fit
281 281 * vertically. The available policy settings are listed at
282 282 * {@link #setVerticalScrollBarPolicy} and
283 283 * {@link #setHorizontalScrollBarPolicy}.
284 284 *
285 285 * @see #setViewportView
286 286 *
287 287 * @param view the component to display in the scrollpanes viewport
288 288 * @param vsbPolicy an integer that specifies the vertical
289 289 * scrollbar policy
290 290 * @param hsbPolicy an integer that specifies the horizontal
291 291 * scrollbar policy
292 292 */
293 293 public JScrollPane(Component view, int vsbPolicy, int hsbPolicy)
294 294 {
295 295 setLayout(new ScrollPaneLayout.UIResource());
296 296 setVerticalScrollBarPolicy(vsbPolicy);
297 297 setHorizontalScrollBarPolicy(hsbPolicy);
298 298 setViewport(createViewport());
299 299 setVerticalScrollBar(createVerticalScrollBar());
300 300 setHorizontalScrollBar(createHorizontalScrollBar());
301 301 if (view != null) {
302 302 setViewportView(view);
303 303 }
304 304 setUIProperty("opaque",true);
305 305 updateUI();
306 306
307 307 if (!this.getComponentOrientation().isLeftToRight()) {
308 308 viewport.setViewPosition(new Point(Integer.MAX_VALUE, 0));
309 309 }
310 310 }
311 311
312 312
313 313 /**
314 314 * Creates a <code>JScrollPane</code> that displays the
315 315 * contents of the specified
316 316 * component, where both horizontal and vertical scrollbars appear
317 317 * whenever the component's contents are larger than the view.
318 318 *
319 319 * @see #setViewportView
320 320 * @param view the component to display in the scrollpane's viewport
321 321 */
322 322 public JScrollPane(Component view) {
323 323 this(view, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
324 324 }
325 325
326 326
327 327 /**
328 328 * Creates an empty (no viewport view) <code>JScrollPane</code>
329 329 * with specified
330 330 * scrollbar policies. The available policy settings are listed at
331 331 * {@link #setVerticalScrollBarPolicy} and
332 332 * {@link #setHorizontalScrollBarPolicy}.
333 333 *
334 334 * @see #setViewportView
335 335 *
336 336 * @param vsbPolicy an integer that specifies the vertical
337 337 * scrollbar policy
338 338 * @param hsbPolicy an integer that specifies the horizontal
339 339 * scrollbar policy
340 340 */
341 341 public JScrollPane(int vsbPolicy, int hsbPolicy) {
342 342 this(null, vsbPolicy, hsbPolicy);
343 343 }
344 344
345 345
346 346 /**
347 347 * Creates an empty (no viewport view) <code>JScrollPane</code>
348 348 * where both horizontal and vertical scrollbars appear when needed.
349 349 */
350 350 public JScrollPane() {
351 351 this(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
352 352 }
353 353
354 354
355 355 /**
356 356 * Returns the look and feel (L&F) object that renders this component.
357 357 *
358 358 * @return the <code>ScrollPaneUI</code> object that renders this
359 359 * component
360 360 * @see #setUI
361 361 * @beaninfo
362 362 * bound: true
363 363 * hidden: true
364 364 * attribute: visualUpdate true
365 365 * description: The UI object that implements the Component's LookAndFeel.
366 366 */
367 367 public ScrollPaneUI getUI() {
368 368 return (ScrollPaneUI)ui;
369 369 }
370 370
371 371
372 372 /**
373 373 * Sets the <code>ScrollPaneUI</code> object that provides the
374 374 * look and feel (L&F) for this component.
375 375 *
376 376 * @param ui the <code>ScrollPaneUI</code> L&F object
377 377 * @see #getUI
378 378 */
379 379 public void setUI(ScrollPaneUI ui) {
380 380 super.setUI(ui);
381 381 }
382 382
383 383
384 384 /**
385 385 * Replaces the current <code>ScrollPaneUI</code> object with a version
386 386 * from the current default look and feel.
387 387 * To be called when the default look and feel changes.
388 388 *
389 389 * @see JComponent#updateUI
390 390 * @see UIManager#getUI
391 391 */
392 392 public void updateUI() {
393 393 setUI((ScrollPaneUI)UIManager.getUI(this));
394 394 }
395 395
396 396
397 397 /**
398 398 * Returns the suffix used to construct the name of the L&F class used to
399 399 * render this component.
400 400 *
401 401 * @return the string "ScrollPaneUI"
402 402 * @see JComponent#getUIClassID
403 403 * @see UIDefaults#getUI
404 404 *
405 405 * @beaninfo
406 406 * hidden: true
407 407 */
408 408 public String getUIClassID() {
409 409 return uiClassID;
410 410 }
411 411
412 412
413 413
414 414 /**
415 415 * Sets the layout manager for this <code>JScrollPane</code>.
416 416 * This method overrides <code>setLayout</code> in
417 417 * <code>java.awt.Container</code> to ensure that only
418 418 * <code>LayoutManager</code>s which
419 419 * are subclasses of <code>ScrollPaneLayout</code> can be used in a
420 420 * <code>JScrollPane</code>. If <code>layout</code> is non-null, this
421 421 * will invoke <code>syncWithScrollPane</code> on it.
422 422 *
423 423 * @param layout the specified layout manager
424 424 * @exception ClassCastException if layout is not a
425 425 * <code>ScrollPaneLayout</code>
426 426 * @see java.awt.Container#getLayout
427 427 * @see java.awt.Container#setLayout
428 428 *
429 429 * @beaninfo
430 430 * hidden: true
431 431 */
432 432 public void setLayout(LayoutManager layout) {
433 433 if (layout instanceof ScrollPaneLayout) {
434 434 super.setLayout(layout);
435 435 ((ScrollPaneLayout)layout).syncWithScrollPane(this);
436 436 }
437 437 else if (layout == null) {
438 438 super.setLayout(layout);
439 439 }
440 440 else {
441 441 String s = "layout of JScrollPane must be a ScrollPaneLayout";
442 442 throw new ClassCastException(s);
443 443 }
444 444 }
445 445
446 446 /**
447 447 * Overridden to return true so that any calls to <code>revalidate</code>
448 448 * on any descendants of this <code>JScrollPane</code> will cause the
449 449 * entire tree beginning with this <code>JScrollPane</code> to be
450 450 * validated.
451 451 *
452 452 * @return true
453 453 * @see java.awt.Container#validate
454 454 * @see JComponent#revalidate
455 455 * @see JComponent#isValidateRoot
456 456 * @see java.awt.Container#isValidateRoot
457 457 *
458 458 * @beaninfo
459 459 * hidden: true
460 460 */
461 461 @Override
462 462 public boolean isValidateRoot() {
463 463 return true;
464 464 }
465 465
466 466
467 467 /**
468 468 * Returns the vertical scroll bar policy value.
469 469 * @return the <code>verticalScrollBarPolicy</code> property
470 470 * @see #setVerticalScrollBarPolicy
471 471 */
472 472 public int getVerticalScrollBarPolicy() {
473 473 return verticalScrollBarPolicy;
474 474 }
475 475
476 476
477 477 /**
478 478 * Determines when the vertical scrollbar appears in the scrollpane.
479 479 * Legal values are:
480 480 * <ul>
481 481 * <li><code>ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED</code>
482 482 * <li><code>ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER</code>
483 483 * <li><code>ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS</code>
484 484 * </ul>
485 485 *
486 486 * @param policy one of the three values listed above
487 487 * @exception IllegalArgumentException if <code>policy</code>
488 488 * is not one of the legal values shown above
489 489 * @see #getVerticalScrollBarPolicy
490 490 *
491 491 * @beaninfo
492 492 * preferred: true
493 493 * bound: true
494 494 * description: The scrollpane vertical scrollbar policy
495 495 * enum: VERTICAL_SCROLLBAR_AS_NEEDED ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED
496 496 * VERTICAL_SCROLLBAR_NEVER ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER
497 497 * VERTICAL_SCROLLBAR_ALWAYS ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS
498 498 */
499 499 public void setVerticalScrollBarPolicy(int policy) {
500 500 switch (policy) {
501 501 case VERTICAL_SCROLLBAR_AS_NEEDED:
502 502 case VERTICAL_SCROLLBAR_NEVER:
503 503 case VERTICAL_SCROLLBAR_ALWAYS:
504 504 break;
505 505 default:
506 506 throw new IllegalArgumentException("invalid verticalScrollBarPolicy");
507 507 }
508 508 int old = verticalScrollBarPolicy;
509 509 verticalScrollBarPolicy = policy;
510 510 firePropertyChange("verticalScrollBarPolicy", old, policy);
511 511 revalidate();
512 512 repaint();
513 513 }
514 514
515 515
516 516 /**
517 517 * Returns the horizontal scroll bar policy value.
518 518 * @return the <code>horizontalScrollBarPolicy</code> property
519 519 * @see #setHorizontalScrollBarPolicy
520 520 */
521 521 public int getHorizontalScrollBarPolicy() {
522 522 return horizontalScrollBarPolicy;
523 523 }
524 524
525 525
526 526 /**
527 527 * Determines when the horizontal scrollbar appears in the scrollpane.
528 528 * The options are:<ul>
529 529 * <li><code>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED</code>
530 530 * <li><code>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER</code>
531 531 * <li><code>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS</code>
532 532 * </ul>
533 533 *
534 534 * @param policy one of the three values listed above
535 535 * @exception IllegalArgumentException if <code>policy</code>
536 536 * is not one of the legal values shown above
537 537 * @see #getHorizontalScrollBarPolicy
538 538 *
539 539 * @beaninfo
540 540 * preferred: true
541 541 * bound: true
542 542 * description: The scrollpane scrollbar policy
543 543 * enum: HORIZONTAL_SCROLLBAR_AS_NEEDED ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED
544 544 * HORIZONTAL_SCROLLBAR_NEVER ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
545 545 * HORIZONTAL_SCROLLBAR_ALWAYS ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS
546 546 */
547 547 public void setHorizontalScrollBarPolicy(int policy) {
548 548 switch (policy) {
549 549 case HORIZONTAL_SCROLLBAR_AS_NEEDED:
550 550 case HORIZONTAL_SCROLLBAR_NEVER:
551 551 case HORIZONTAL_SCROLLBAR_ALWAYS:
552 552 break;
553 553 default:
554 554 throw new IllegalArgumentException("invalid horizontalScrollBarPolicy");
555 555 }
556 556 int old = horizontalScrollBarPolicy;
557 557 horizontalScrollBarPolicy = policy;
558 558 firePropertyChange("horizontalScrollBarPolicy", old, policy);
559 559 revalidate();
560 560 repaint();
561 561 }
562 562
563 563
564 564 /**
565 565 * Returns the <code>Border</code> object that surrounds the viewport.
566 566 *
567 567 * @return the <code>viewportBorder</code> property
568 568 * @see #setViewportBorder
569 569 */
570 570 public Border getViewportBorder() {
571 571 return viewportBorder;
572 572 }
573 573
574 574
575 575 /**
576 576 * Adds a border around the viewport. Note that the border isn't
577 577 * set on the viewport directly, <code>JViewport</code> doesn't support
578 578 * the <code>JComponent</code> border property.
579 579 * Similarly setting the <code>JScrollPane</code>s
580 580 * viewport doesn't affect the <code>viewportBorder</code> property.
581 581 * <p>
582 582 * The default value of this property is computed by the look
583 583 * and feel implementation.
584 584 *
585 585 * @param viewportBorder the border to be added
586 586 * @see #getViewportBorder
587 587 * @see #setViewport
588 588 *
589 589 * @beaninfo
590 590 * preferred: true
591 591 * bound: true
592 592 * description: The border around the viewport.
593 593 */
594 594 public void setViewportBorder(Border viewportBorder) {
595 595 Border oldValue = this.viewportBorder;
596 596 this.viewportBorder = viewportBorder;
597 597 firePropertyChange("viewportBorder", oldValue, viewportBorder);
598 598 }
599 599
600 600
601 601 /**
602 602 * Returns the bounds of the viewport's border.
603 603 *
604 604 * @return a <code>Rectangle</code> object specifying the viewport border
605 605 */
606 606 public Rectangle getViewportBorderBounds()
607 607 {
608 608 Rectangle borderR = new Rectangle(getSize());
609 609
610 610 Insets insets = getInsets();
611 611 borderR.x = insets.left;
612 612 borderR.y = insets.top;
613 613 borderR.width -= insets.left + insets.right;
614 614 borderR.height -= insets.top + insets.bottom;
615 615
616 616 boolean leftToRight = SwingUtilities.isLeftToRight(this);
617 617
618 618 /* If there's a visible column header remove the space it
619 619 * needs from the top of borderR.
620 620 */
621 621
622 622 JViewport colHead = getColumnHeader();
623 623 if ((colHead != null) && (colHead.isVisible())) {
624 624 int colHeadHeight = colHead.getHeight();
625 625 borderR.y += colHeadHeight;
626 626 borderR.height -= colHeadHeight;
627 627 }
628 628
629 629 /* If there's a visible row header remove the space it needs
630 630 * from the left of borderR.
631 631 */
632 632
633 633 JViewport rowHead = getRowHeader();
634 634 if ((rowHead != null) && (rowHead.isVisible())) {
635 635 int rowHeadWidth = rowHead.getWidth();
636 636 if ( leftToRight ) {
637 637 borderR.x += rowHeadWidth;
638 638 }
639 639 borderR.width -= rowHeadWidth;
640 640 }
641 641
642 642 /* If there's a visible vertical scrollbar remove the space it needs
643 643 * from the width of borderR.
644 644 */
645 645 JScrollBar vsb = getVerticalScrollBar();
646 646 if ((vsb != null) && (vsb.isVisible())) {
647 647 int vsbWidth = vsb.getWidth();
648 648 if ( !leftToRight ) {
649 649 borderR.x += vsbWidth;
650 650 }
651 651 borderR.width -= vsbWidth;
652 652 }
653 653
654 654 /* If there's a visible horizontal scrollbar remove the space it needs
655 655 * from the height of borderR.
656 656 */
657 657 JScrollBar hsb = getHorizontalScrollBar();
658 658 if ((hsb != null) && (hsb.isVisible())) {
659 659 borderR.height -= hsb.getHeight();
660 660 }
661 661
662 662 return borderR;
663 663 }
664 664
665 665
666 666 /**
667 667 * By default <code>JScrollPane</code> creates scrollbars
668 668 * that are instances
669 669 * of this class. <code>Scrollbar</code> overrides the
670 670 * <code>getUnitIncrement</code> and <code>getBlockIncrement</code>
671 671 * methods so that, if the viewport's view is a <code>Scrollable</code>,
672 672 * the view is asked to compute these values. Unless
673 673 * the unit/block increment have been explicitly set.
674 674 * <p>
675 675 * <strong>Warning:</strong>
676 676 * Serialized objects of this class will not be compatible with
677 677 * future Swing releases. The current serialization support is
678 678 * appropriate for short term storage or RMI between applications running
679 679 * the same version of Swing. As of 1.4, support for long term storage
680 680 * of all JavaBeans™
681 681 * has been added to the <code>java.beans</code> package.
682 682 * Please see {@link java.beans.XMLEncoder}.
683 683 *
684 684 * @see Scrollable
685 685 * @see JScrollPane#createVerticalScrollBar
686 686 * @see JScrollPane#createHorizontalScrollBar
687 687 */
688 688 protected class ScrollBar extends JScrollBar implements UIResource
689 689 {
690 690 /**
691 691 * Set to true when the unit increment has been explicitly set.
692 692 * If this is false the viewport's view is obtained and if it
693 693 * is an instance of <code>Scrollable</code> the unit increment
694 694 * from it is used.
695 695 */
696 696 private boolean unitIncrementSet;
697 697 /**
698 698 * Set to true when the block increment has been explicitly set.
699 699 * If this is false the viewport's view is obtained and if it
700 700 * is an instance of <code>Scrollable</code> the block increment
701 701 * from it is used.
702 702 */
703 703 private boolean blockIncrementSet;
704 704
705 705 /**
706 706 * Creates a scrollbar with the specified orientation.
707 707 * The options are:
708 708 * <ul>
709 709 * <li><code>ScrollPaneConstants.VERTICAL</code>
710 710 * <li><code>ScrollPaneConstants.HORIZONTAL</code>
711 711 * </ul>
712 712 *
713 713 * @param orientation an integer specifying one of the legal
714 714 * orientation values shown above
715 715 * @since 1.4
716 716 */
717 717 public ScrollBar(int orientation) {
718 718 super(orientation);
719 719 this.putClientProperty("JScrollBar.fastWheelScrolling",
720 720 Boolean.TRUE);
721 721 }
722 722
723 723 /**
724 724 * Messages super to set the value, and resets the
725 725 * <code>unitIncrementSet</code> instance variable to true.
726 726 *
727 727 * @param unitIncrement the new unit increment value, in pixels
728 728 */
729 729 public void setUnitIncrement(int unitIncrement) {
730 730 unitIncrementSet = true;
731 731 this.putClientProperty("JScrollBar.fastWheelScrolling", null);
732 732 super.setUnitIncrement(unitIncrement);
733 733 }
734 734
735 735 /**
736 736 * Computes the unit increment for scrolling if the viewport's
737 737 * view is a <code>Scrollable</code> object.
738 738 * Otherwise return <code>super.getUnitIncrement</code>.
739 739 *
740 740 * @param direction less than zero to scroll up/left,
741 741 * greater than zero for down/right
742 742 * @return an integer, in pixels, containing the unit increment
743 743 * @see Scrollable#getScrollableUnitIncrement
744 744 */
745 745 public int getUnitIncrement(int direction) {
746 746 JViewport vp = getViewport();
747 747 if (!unitIncrementSet && (vp != null) &&
748 748 (vp.getView() instanceof Scrollable)) {
749 749 Scrollable view = (Scrollable)(vp.getView());
750 750 Rectangle vr = vp.getViewRect();
751 751 return view.getScrollableUnitIncrement(vr, getOrientation(), direction);
752 752 }
753 753 else {
754 754 return super.getUnitIncrement(direction);
755 755 }
756 756 }
757 757
758 758 /**
759 759 * Messages super to set the value, and resets the
760 760 * <code>blockIncrementSet</code> instance variable to true.
761 761 *
762 762 * @param blockIncrement the new block increment value, in pixels
763 763 */
764 764 public void setBlockIncrement(int blockIncrement) {
765 765 blockIncrementSet = true;
766 766 this.putClientProperty("JScrollBar.fastWheelScrolling", null);
767 767 super.setBlockIncrement(blockIncrement);
768 768 }
769 769
770 770 /**
771 771 * Computes the block increment for scrolling if the viewport's
772 772 * view is a <code>Scrollable</code> object. Otherwise
773 773 * the <code>blockIncrement</code> equals the viewport's width
774 774 * or height. If there's no viewport return
775 775 * <code>super.getBlockIncrement</code>.
776 776 *
777 777 * @param direction less than zero to scroll up/left,
778 778 * greater than zero for down/right
779 779 * @return an integer, in pixels, containing the block increment
780 780 * @see Scrollable#getScrollableBlockIncrement
781 781 */
782 782 public int getBlockIncrement(int direction) {
783 783 JViewport vp = getViewport();
784 784 if (blockIncrementSet || vp == null) {
785 785 return super.getBlockIncrement(direction);
786 786 }
787 787 else if (vp.getView() instanceof Scrollable) {
788 788 Scrollable view = (Scrollable)(vp.getView());
789 789 Rectangle vr = vp.getViewRect();
790 790 return view.getScrollableBlockIncrement(vr, getOrientation(), direction);
791 791 }
792 792 else if (getOrientation() == VERTICAL) {
793 793 return vp.getExtentSize().height;
794 794 }
795 795 else {
796 796 return vp.getExtentSize().width;
797 797 }
798 798 }
799 799
800 800 }
801 801
802 802
803 803 /**
804 804 * Returns a <code>JScrollPane.ScrollBar</code> by default.
805 805 * Subclasses may override this method to force <code>ScrollPaneUI</code>
806 806 * implementations to use a <code>JScrollBar</code> subclass.
807 807 * Used by <code>ScrollPaneUI</code> implementations to
808 808 * create the horizontal scrollbar.
809 809 *
810 810 * @return a <code>JScrollBar</code> with a horizontal orientation
811 811 * @see JScrollBar
812 812 */
813 813 public JScrollBar createHorizontalScrollBar() {
814 814 return new ScrollBar(JScrollBar.HORIZONTAL);
815 815 }
816 816
817 817
818 818 /**
819 819 * Returns the horizontal scroll bar that controls the viewport's
820 820 * horizontal view position.
821 821 *
822 822 * @return the <code>horizontalScrollBar</code> property
823 823 * @see #setHorizontalScrollBar
824 824 */
825 825 @Transient
826 826 public JScrollBar getHorizontalScrollBar() {
827 827 return horizontalScrollBar;
828 828 }
829 829
830 830
831 831 /**
832 832 * Adds the scrollbar that controls the viewport's horizontal view
833 833 * position to the scrollpane.
834 834 * This is usually unnecessary, as <code>JScrollPane</code> creates
835 835 * horizontal and vertical scrollbars by default.
836 836 *
837 837 * @param horizontalScrollBar the horizontal scrollbar to be added
838 838 * @see #createHorizontalScrollBar
839 839 * @see #getHorizontalScrollBar
840 840 *
841 841 * @beaninfo
842 842 * expert: true
843 843 * bound: true
844 844 * description: The horizontal scrollbar.
845 845 */
846 846 public void setHorizontalScrollBar(JScrollBar horizontalScrollBar) {
847 847 JScrollBar old = getHorizontalScrollBar();
848 848 this.horizontalScrollBar = horizontalScrollBar;
849 849 if (horizontalScrollBar != null) {
850 850 add(horizontalScrollBar, HORIZONTAL_SCROLLBAR);
851 851 }
852 852 else if (old != null) {
853 853 remove(old);
854 854 }
855 855 firePropertyChange("horizontalScrollBar", old, horizontalScrollBar);
856 856
857 857 revalidate();
858 858 repaint();
859 859 }
860 860
861 861
862 862 /**
863 863 * Returns a <code>JScrollPane.ScrollBar</code> by default. Subclasses
864 864 * may override this method to force <code>ScrollPaneUI</code>
865 865 * implementations to use a <code>JScrollBar</code> subclass.
866 866 * Used by <code>ScrollPaneUI</code> implementations to create the
867 867 * vertical scrollbar.
868 868 *
869 869 * @return a <code>JScrollBar</code> with a vertical orientation
870 870 * @see JScrollBar
871 871 */
872 872 public JScrollBar createVerticalScrollBar() {
873 873 return new ScrollBar(JScrollBar.VERTICAL);
874 874 }
875 875
876 876
877 877 /**
878 878 * Returns the vertical scroll bar that controls the viewports
879 879 * vertical view position.
880 880 *
881 881 * @return the <code>verticalScrollBar</code> property
882 882 * @see #setVerticalScrollBar
883 883 */
884 884 @Transient
885 885 public JScrollBar getVerticalScrollBar() {
886 886 return verticalScrollBar;
887 887 }
888 888
889 889
890 890 /**
891 891 * Adds the scrollbar that controls the viewports vertical view position
892 892 * to the scrollpane. This is usually unnecessary,
893 893 * as <code>JScrollPane</code> creates vertical and
894 894 * horizontal scrollbars by default.
895 895 *
896 896 * @param verticalScrollBar the new vertical scrollbar to be added
897 897 * @see #createVerticalScrollBar
898 898 * @see #getVerticalScrollBar
899 899 *
900 900 * @beaninfo
901 901 * expert: true
902 902 * bound: true
903 903 * description: The vertical scrollbar.
904 904 */
905 905 public void setVerticalScrollBar(JScrollBar verticalScrollBar) {
906 906 JScrollBar old = getVerticalScrollBar();
907 907 this.verticalScrollBar = verticalScrollBar;
908 908 add(verticalScrollBar, VERTICAL_SCROLLBAR);
909 909 firePropertyChange("verticalScrollBar", old, verticalScrollBar);
910 910
911 911 revalidate();
912 912 repaint();
913 913 }
914 914
915 915
916 916 /**
917 917 * Returns a new <code>JViewport</code> by default.
918 918 * Used to create the
919 919 * viewport (as needed) in <code>setViewportView</code>,
920 920 * <code>setRowHeaderView</code>, and <code>setColumnHeaderView</code>.
921 921 * Subclasses may override this method to return a subclass of
922 922 * <code>JViewport</code>.
923 923 *
924 924 * @return a new <code>JViewport</code>
925 925 */
926 926 protected JViewport createViewport() {
927 927 return new JViewport();
928 928 }
929 929
930 930
931 931 /**
932 932 * Returns the current <code>JViewport</code>.
933 933 *
934 934 * @see #setViewport
935 935 * @return the <code>viewport</code> property
936 936 */
937 937 public JViewport getViewport() {
938 938 return viewport;
939 939 }
940 940
941 941
942 942 /**
943 943 * Removes the old viewport (if there is one); forces the
944 944 * viewPosition of the new viewport to be in the +x,+y quadrant;
945 945 * syncs up the row and column headers (if there are any) with the
946 946 * new viewport; and finally syncs the scrollbars and
947 947 * headers with the new viewport.
948 948 * <p>
949 949 * Most applications will find it more convenient to use
950 950 * <code>setViewportView</code>
951 951 * to add a viewport and a view to the scrollpane.
952 952 *
953 953 * @param viewport the new viewport to be used; if viewport is
954 954 * <code>null</code>, the old viewport is still removed
955 955 * and the new viewport is set to <code>null</code>
956 956 * @see #createViewport
957 957 * @see #getViewport
958 958 * @see #setViewportView
959 959 *
960 960 * @beaninfo
961 961 * expert: true
962 962 * bound: true
963 963 * attribute: visualUpdate true
964 964 * description: The viewport child for this scrollpane
965 965 *
966 966 */
967 967 public void setViewport(JViewport viewport) {
968 968 JViewport old = getViewport();
969 969 this.viewport = viewport;
970 970 if (viewport != null) {
971 971 add(viewport, VIEWPORT);
972 972 }
973 973 else if (old != null) {
974 974 remove(old);
975 975 }
976 976 firePropertyChange("viewport", old, viewport);
977 977
978 978 if (accessibleContext != null) {
979 979 ((AccessibleJScrollPane)accessibleContext).resetViewPort();
980 980 }
981 981
982 982 revalidate();
983 983 repaint();
984 984 }
985 985
986 986
987 987 /**
988 988 * Creates a viewport if necessary and then sets its view. Applications
989 989 * that don't provide the view directly to the <code>JScrollPane</code>
990 990 * constructor
991 991 * should use this method to specify the scrollable child that's going
992 992 * to be displayed in the scrollpane. For example:
993 993 * <pre>
994 994 * JScrollPane scrollpane = new JScrollPane();
995 995 * scrollpane.setViewportView(myBigComponentToScroll);
996 996 * </pre>
997 997 * Applications should not add children directly to the scrollpane.
998 998 *
999 999 * @param view the component to add to the viewport
1000 1000 * @see #setViewport
1001 1001 * @see JViewport#setView
1002 1002 */
1003 1003 public void setViewportView(Component view) {
1004 1004 if (getViewport() == null) {
1005 1005 setViewport(createViewport());
1006 1006 }
1007 1007 getViewport().setView(view);
1008 1008 }
1009 1009
1010 1010
1011 1011
1012 1012 /**
1013 1013 * Returns the row header.
1014 1014 * @return the <code>rowHeader</code> property
1015 1015 * @see #setRowHeader
1016 1016 */
1017 1017 @Transient
1018 1018 public JViewport getRowHeader() {
1019 1019 return rowHeader;
1020 1020 }
1021 1021
1022 1022
1023 1023 /**
1024 1024 * Removes the old rowHeader, if it exists; if the new rowHeader
1025 1025 * isn't <code>null</code>, syncs the y coordinate of its
1026 1026 * viewPosition with
1027 1027 * the viewport (if there is one) and then adds it to the scroll pane.
1028 1028 * <p>
1029 1029 * Most applications will find it more convenient to use
1030 1030 * <code>setRowHeaderView</code>
1031 1031 * to add a row header component and its viewport to the scroll pane.
1032 1032 *
1033 1033 * @param rowHeader the new row header to be used; if <code>null</code>
1034 1034 * the old row header is still removed and the new rowHeader
1035 1035 * is set to <code>null</code>
1036 1036 * @see #getRowHeader
1037 1037 * @see #setRowHeaderView
1038 1038 *
1039 1039 * @beaninfo
1040 1040 * bound: true
1041 1041 * expert: true
1042 1042 * description: The row header child for this scrollpane
1043 1043 */
1044 1044 public void setRowHeader(JViewport rowHeader) {
1045 1045 JViewport old = getRowHeader();
1046 1046 this.rowHeader = rowHeader;
1047 1047 if (rowHeader != null) {
1048 1048 add(rowHeader, ROW_HEADER);
1049 1049 }
1050 1050 else if (old != null) {
1051 1051 remove(old);
1052 1052 }
1053 1053 firePropertyChange("rowHeader", old, rowHeader);
1054 1054 revalidate();
1055 1055 repaint();
1056 1056 }
1057 1057
1058 1058
1059 1059 /**
1060 1060 * Creates a row-header viewport if necessary, sets
1061 1061 * its view and then adds the row-header viewport
1062 1062 * to the scrollpane. For example:
1063 1063 * <pre>
1064 1064 * JScrollPane scrollpane = new JScrollPane();
1065 1065 * scrollpane.setViewportView(myBigComponentToScroll);
1066 1066 * scrollpane.setRowHeaderView(myBigComponentsRowHeader);
1067 1067 * </pre>
1068 1068 *
1069 1069 * @see #setRowHeader
1070 1070 * @see JViewport#setView
1071 1071 * @param view the component to display as the row header
1072 1072 */
1073 1073 public void setRowHeaderView(Component view) {
1074 1074 if (getRowHeader() == null) {
1075 1075 setRowHeader(createViewport());
1076 1076 }
1077 1077 getRowHeader().setView(view);
1078 1078 }
1079 1079
1080 1080
1081 1081
1082 1082 /**
1083 1083 * Returns the column header.
1084 1084 * @return the <code>columnHeader</code> property
1085 1085 * @see #setColumnHeader
1086 1086 */
1087 1087 @Transient
1088 1088 public JViewport getColumnHeader() {
1089 1089 return columnHeader;
1090 1090 }
1091 1091
1092 1092
1093 1093 /**
1094 1094 * Removes the old columnHeader, if it exists; if the new columnHeader
1095 1095 * isn't <code>null</code>, syncs the x coordinate of its viewPosition
1096 1096 * with the viewport (if there is one) and then adds it to the scroll pane.
1097 1097 * <p>
1098 1098 * Most applications will find it more convenient to use
1099 1099 * <code>setColumnHeaderView</code>
1100 1100 * to add a column header component and its viewport to the scroll pane.
1101 1101 *
1102 1102 * @see #getColumnHeader
1103 1103 * @see #setColumnHeaderView
1104 1104 *
1105 1105 * @beaninfo
1106 1106 * bound: true
1107 1107 * description: The column header child for this scrollpane
1108 1108 * attribute: visualUpdate true
1109 1109 */
1110 1110 public void setColumnHeader(JViewport columnHeader) {
1111 1111 JViewport old = getColumnHeader();
1112 1112 this.columnHeader = columnHeader;
1113 1113 if (columnHeader != null) {
1114 1114 add(columnHeader, COLUMN_HEADER);
1115 1115 }
1116 1116 else if (old != null) {
1117 1117 remove(old);
1118 1118 }
1119 1119 firePropertyChange("columnHeader", old, columnHeader);
1120 1120
1121 1121 revalidate();
1122 1122 repaint();
1123 1123 }
1124 1124
1125 1125
1126 1126
1127 1127 /**
1128 1128 * Creates a column-header viewport if necessary, sets
1129 1129 * its view, and then adds the column-header viewport
1130 1130 * to the scrollpane. For example:
1131 1131 * <pre>
1132 1132 * JScrollPane scrollpane = new JScrollPane();
1133 1133 * scrollpane.setViewportView(myBigComponentToScroll);
1134 1134 * scrollpane.setColumnHeaderView(myBigComponentsColumnHeader);
1135 1135 * </pre>
1136 1136 *
1137 1137 * @see #setColumnHeader
1138 1138 * @see JViewport#setView
1139 1139 *
1140 1140 * @param view the component to display as the column header
1141 1141 */
1142 1142 public void setColumnHeaderView(Component view) {
1143 1143 if (getColumnHeader() == null) {
1144 1144 setColumnHeader(createViewport());
1145 1145 }
1146 1146 getColumnHeader().setView(view);
1147 1147 }
1148 1148
1149 1149
1150 1150 /**
1151 1151 * Returns the component at the specified corner. The
1152 1152 * <code>key</code> value specifying the corner is one of:
1153 1153 * <ul>
1154 1154 * <li>ScrollPaneConstants.LOWER_LEFT_CORNER
1155 1155 * <li>ScrollPaneConstants.LOWER_RIGHT_CORNER
1156 1156 * <li>ScrollPaneConstants.UPPER_LEFT_CORNER
1157 1157 * <li>ScrollPaneConstants.UPPER_RIGHT_CORNER
1158 1158 * <li>ScrollPaneConstants.LOWER_LEADING_CORNER
1159 1159 * <li>ScrollPaneConstants.LOWER_TRAILING_CORNER
1160 1160 * <li>ScrollPaneConstants.UPPER_LEADING_CORNER
1161 1161 * <li>ScrollPaneConstants.UPPER_TRAILING_CORNER
1162 1162 * </ul>
1163 1163 *
1164 1164 * @param key one of the values as shown above
1165 1165 * @return the corner component (which may be <code>null</code>)
1166 1166 * identified by the given key, or <code>null</code>
1167 1167 * if the key is invalid
1168 1168 * @see #setCorner
1169 1169 */
1170 1170 public Component getCorner(String key) {
1171 1171 boolean isLeftToRight = getComponentOrientation().isLeftToRight();
1172 1172 if (key.equals(LOWER_LEADING_CORNER)) {
1173 1173 key = isLeftToRight ? LOWER_LEFT_CORNER : LOWER_RIGHT_CORNER;
1174 1174 } else if (key.equals(LOWER_TRAILING_CORNER)) {
1175 1175 key = isLeftToRight ? LOWER_RIGHT_CORNER : LOWER_LEFT_CORNER;
1176 1176 } else if (key.equals(UPPER_LEADING_CORNER)) {
1177 1177 key = isLeftToRight ? UPPER_LEFT_CORNER : UPPER_RIGHT_CORNER;
1178 1178 } else if (key.equals(UPPER_TRAILING_CORNER)) {
1179 1179 key = isLeftToRight ? UPPER_RIGHT_CORNER : UPPER_LEFT_CORNER;
1180 1180 }
1181 1181 if (key.equals(LOWER_LEFT_CORNER)) {
1182 1182 return lowerLeft;
1183 1183 }
1184 1184 else if (key.equals(LOWER_RIGHT_CORNER)) {
1185 1185 return lowerRight;
1186 1186 }
1187 1187 else if (key.equals(UPPER_LEFT_CORNER)) {
1188 1188 return upperLeft;
1189 1189 }
1190 1190 else if (key.equals(UPPER_RIGHT_CORNER)) {
1191 1191 return upperRight;
1192 1192 }
1193 1193 else {
1194 1194 return null;
1195 1195 }
1196 1196 }
1197 1197
1198 1198
1199 1199 /**
1200 1200 * Adds a child that will appear in one of the scroll panes
1201 1201 * corners, if there's room. For example with both scrollbars
1202 1202 * showing (on the right and bottom edges of the scrollpane)
1203 1203 * the lower left corner component will be shown in the space
1204 1204 * between ends of the two scrollbars. Legal values for
1205 1205 * the <b>key</b> are:
1206 1206 * <ul>
1207 1207 * <li>ScrollPaneConstants.LOWER_LEFT_CORNER
1208 1208 * <li>ScrollPaneConstants.LOWER_RIGHT_CORNER
1209 1209 * <li>ScrollPaneConstants.UPPER_LEFT_CORNER
1210 1210 * <li>ScrollPaneConstants.UPPER_RIGHT_CORNER
1211 1211 * <li>ScrollPaneConstants.LOWER_LEADING_CORNER
1212 1212 * <li>ScrollPaneConstants.LOWER_TRAILING_CORNER
1213 1213 * <li>ScrollPaneConstants.UPPER_LEADING_CORNER
1214 1214 * <li>ScrollPaneConstants.UPPER_TRAILING_CORNER
1215 1215 * </ul>
1216 1216 * <p>
1217 1217 * Although "corner" doesn't match any beans property
1218 1218 * signature, <code>PropertyChange</code> events are generated with the
1219 1219 * property name set to the corner key.
1220 1220 *
1221 1221 * @param key identifies which corner the component will appear in
1222 1222 * @param corner one of the following components:
1223 1223 * <ul>
1224 1224 * <li>lowerLeft
1225 1225 * <li>lowerRight
1226 1226 * <li>upperLeft
1227 1227 * <li>upperRight
1228 1228 * </ul>
1229 1229 * @exception IllegalArgumentException if corner key is invalid
1230 1230 */
1231 1231 public void setCorner(String key, Component corner)
1232 1232 {
1233 1233 Component old;
1234 1234 boolean isLeftToRight = getComponentOrientation().isLeftToRight();
1235 1235 if (key.equals(LOWER_LEADING_CORNER)) {
1236 1236 key = isLeftToRight ? LOWER_LEFT_CORNER : LOWER_RIGHT_CORNER;
1237 1237 } else if (key.equals(LOWER_TRAILING_CORNER)) {
1238 1238 key = isLeftToRight ? LOWER_RIGHT_CORNER : LOWER_LEFT_CORNER;
1239 1239 } else if (key.equals(UPPER_LEADING_CORNER)) {
1240 1240 key = isLeftToRight ? UPPER_LEFT_CORNER : UPPER_RIGHT_CORNER;
1241 1241 } else if (key.equals(UPPER_TRAILING_CORNER)) {
1242 1242 key = isLeftToRight ? UPPER_RIGHT_CORNER : UPPER_LEFT_CORNER;
1243 1243 }
1244 1244 if (key.equals(LOWER_LEFT_CORNER)) {
1245 1245 old = lowerLeft;
1246 1246 lowerLeft = corner;
1247 1247 }
1248 1248 else if (key.equals(LOWER_RIGHT_CORNER)) {
1249 1249 old = lowerRight;
1250 1250 lowerRight = corner;
1251 1251 }
1252 1252 else if (key.equals(UPPER_LEFT_CORNER)) {
1253 1253 old = upperLeft;
1254 1254 upperLeft = corner;
1255 1255 }
1256 1256 else if (key.equals(UPPER_RIGHT_CORNER)) {
1257 1257 old = upperRight;
1258 1258 upperRight = corner;
1259 1259 }
1260 1260 else {
1261 1261 throw new IllegalArgumentException("invalid corner key");
1262 1262 }
1263 1263 if (old != null) {
1264 1264 remove(old);
1265 1265 }
1266 1266 if (corner != null) {
1267 1267 add(corner, key);
1268 1268 }
1269 1269 firePropertyChange(key, old, corner);
1270 1270 revalidate();
1271 1271 repaint();
1272 1272 }
1273 1273
1274 1274 /**
1275 1275 * Sets the orientation for the vertical and horizontal
1276 1276 * scrollbars as determined by the
1277 1277 * <code>ComponentOrientation</code> argument.
1278 1278 *
1279 1279 * @param co one of the following values:
1280 1280 * <ul>
1281 1281 * <li>java.awt.ComponentOrientation.LEFT_TO_RIGHT
1282 1282 * <li>java.awt.ComponentOrientation.RIGHT_TO_LEFT
1283 1283 * <li>java.awt.ComponentOrientation.UNKNOWN
1284 1284 * </ul>
1285 1285 * @see java.awt.ComponentOrientation
1286 1286 */
1287 1287 public void setComponentOrientation( ComponentOrientation co ) {
1288 1288 super.setComponentOrientation( co );
1289 1289 if( verticalScrollBar != null )
1290 1290 verticalScrollBar.setComponentOrientation( co );
1291 1291 if( horizontalScrollBar != null )
1292 1292 horizontalScrollBar.setComponentOrientation( co );
1293 1293 }
1294 1294
1295 1295 /**
1296 1296 * Indicates whether or not scrolling will take place in response to the
1297 1297 * mouse wheel. Wheel scrolling is enabled by default.
1298 1298 *
1299 1299 * @see #setWheelScrollingEnabled
1300 1300 * @since 1.4
1301 1301 * @beaninfo
1302 1302 * bound: true
1303 1303 * description: Flag for enabling/disabling mouse wheel scrolling
1304 1304 */
1305 1305 public boolean isWheelScrollingEnabled() {return wheelScrollState;}
1306 1306
1307 1307 /**
1308 1308 * Enables/disables scrolling in response to movement of the mouse wheel.
1309 1309 * Wheel scrolling is enabled by default.
1310 1310 *
1311 1311 * @param handleWheel <code>true</code> if scrolling should be done
1312 1312 * automatically for a MouseWheelEvent,
1313 1313 * <code>false</code> otherwise.
1314 1314 * @see #isWheelScrollingEnabled
1315 1315 * @see java.awt.event.MouseWheelEvent
1316 1316 * @see java.awt.event.MouseWheelListener
1317 1317 * @since 1.4
1318 1318 * @beaninfo
1319 1319 * bound: true
1320 1320 * description: Flag for enabling/disabling mouse wheel scrolling
1321 1321 */
1322 1322 public void setWheelScrollingEnabled(boolean handleWheel) {
1323 1323 boolean old = wheelScrollState;
1324 1324 wheelScrollState = handleWheel;
1325 1325 firePropertyChange("wheelScrollingEnabled", old, handleWheel);
1326 1326 }
1327 1327
1328 1328 /**
1329 1329 * See <code>readObject</code> and <code>writeObject</code> in
1330 1330 * <code>JComponent</code> for more
1331 1331 * information about serialization in Swing.
1332 1332 */
1333 1333 private void writeObject(ObjectOutputStream s) throws IOException {
1334 1334 s.defaultWriteObject();
1335 1335 if (getUIClassID().equals(uiClassID)) {
1336 1336 byte count = JComponent.getWriteObjCounter(this);
1337 1337 JComponent.setWriteObjCounter(this, --count);
1338 1338 if (count == 0 && ui != null) {
1339 1339 ui.installUI(this);
1340 1340 }
1341 1341 }
1342 1342 }
1343 1343
1344 1344
1345 1345 /**
1346 1346 * Returns a string representation of this <code>JScrollPane</code>.
1347 1347 * This method
1348 1348 * is intended to be used only for debugging purposes, and the
1349 1349 * content and format of the returned string may vary between
1350 1350 * implementations. The returned string may be empty but may not
1351 1351 * be <code>null</code>.
1352 1352 *
1353 1353 * @return a string representation of this <code>JScrollPane</code>.
1354 1354 */
1355 1355 protected String paramString() {
1356 1356 String viewportBorderString = (viewportBorder != null ?
1357 1357 viewportBorder.toString() : "");
1358 1358 String viewportString = (viewport != null ?
1359 1359 viewport.toString() : "");
1360 1360 String verticalScrollBarPolicyString;
1361 1361 if (verticalScrollBarPolicy == VERTICAL_SCROLLBAR_AS_NEEDED) {
1362 1362 verticalScrollBarPolicyString = "VERTICAL_SCROLLBAR_AS_NEEDED";
1363 1363 } else if (verticalScrollBarPolicy == VERTICAL_SCROLLBAR_NEVER) {
1364 1364 verticalScrollBarPolicyString = "VERTICAL_SCROLLBAR_NEVER";
1365 1365 } else if (verticalScrollBarPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
1366 1366 verticalScrollBarPolicyString = "VERTICAL_SCROLLBAR_ALWAYS";
1367 1367 } else verticalScrollBarPolicyString = "";
1368 1368 String horizontalScrollBarPolicyString;
1369 1369 if (horizontalScrollBarPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED) {
1370 1370 horizontalScrollBarPolicyString = "HORIZONTAL_SCROLLBAR_AS_NEEDED";
1371 1371 } else if (horizontalScrollBarPolicy == HORIZONTAL_SCROLLBAR_NEVER) {
1372 1372 horizontalScrollBarPolicyString = "HORIZONTAL_SCROLLBAR_NEVER";
1373 1373 } else if (horizontalScrollBarPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) {
1374 1374 horizontalScrollBarPolicyString = "HORIZONTAL_SCROLLBAR_ALWAYS";
1375 1375 } else horizontalScrollBarPolicyString = "";
1376 1376 String horizontalScrollBarString = (horizontalScrollBar != null ?
1377 1377 horizontalScrollBar.toString()
1378 1378 : "");
1379 1379 String verticalScrollBarString = (verticalScrollBar != null ?
1380 1380 verticalScrollBar.toString() : "");
1381 1381 String columnHeaderString = (columnHeader != null ?
1382 1382 columnHeader.toString() : "");
1383 1383 String rowHeaderString = (rowHeader != null ?
1384 1384 rowHeader.toString() : "");
1385 1385 String lowerLeftString = (lowerLeft != null ?
1386 1386 lowerLeft.toString() : "");
1387 1387 String lowerRightString = (lowerRight != null ?
1388 1388 lowerRight.toString() : "");
1389 1389 String upperLeftString = (upperLeft != null ?
1390 1390 upperLeft.toString() : "");
1391 1391 String upperRightString = (upperRight != null ?
1392 1392 upperRight.toString() : "");
1393 1393
1394 1394 return super.paramString() +
1395 1395 ",columnHeader=" + columnHeaderString +
1396 1396 ",horizontalScrollBar=" + horizontalScrollBarString +
1397 1397 ",horizontalScrollBarPolicy=" + horizontalScrollBarPolicyString +
1398 1398 ",lowerLeft=" + lowerLeftString +
1399 1399 ",lowerRight=" + lowerRightString +
1400 1400 ",rowHeader=" + rowHeaderString +
1401 1401 ",upperLeft=" + upperLeftString +
1402 1402 ",upperRight=" + upperRightString +
1403 1403 ",verticalScrollBar=" + verticalScrollBarString +
1404 1404 ",verticalScrollBarPolicy=" + verticalScrollBarPolicyString +
1405 1405 ",viewport=" + viewportString +
1406 1406 ",viewportBorder=" + viewportBorderString;
1407 1407 }
1408 1408
1409 1409 /////////////////
1410 1410 // Accessibility support
1411 1411 ////////////////
1412 1412
1413 1413 /**
1414 1414 * Gets the AccessibleContext associated with this JScrollPane.
1415 1415 * For scroll panes, the AccessibleContext takes the form of an
1416 1416 * AccessibleJScrollPane.
1417 1417 * A new AccessibleJScrollPane instance is created if necessary.
1418 1418 *
1419 1419 * @return an AccessibleJScrollPane that serves as the
1420 1420 * AccessibleContext of this JScrollPane
1421 1421 */
1422 1422 public AccessibleContext getAccessibleContext() {
1423 1423 if (accessibleContext == null) {
1424 1424 accessibleContext = new AccessibleJScrollPane();
1425 1425 }
1426 1426 return accessibleContext;
1427 1427 }
1428 1428
1429 1429 /**
1430 1430 * This class implements accessibility support for the
1431 1431 * <code>JScrollPane</code> class. It provides an implementation of the
1432 1432 * Java Accessibility API appropriate to scroll pane user-interface
1433 1433 * elements.
1434 1434 * <p>
1435 1435 * <strong>Warning:</strong>
1436 1436 * Serialized objects of this class will not be compatible with
1437 1437 * future Swing releases. The current serialization support is
1438 1438 * appropriate for short term storage or RMI between applications running
1439 1439 * the same version of Swing. As of 1.4, support for long term storage
1440 1440 * of all JavaBeans™
1441 1441 * has been added to the <code>java.beans</code> package.
1442 1442 * Please see {@link java.beans.XMLEncoder}.
1443 1443 */
1444 1444 protected class AccessibleJScrollPane extends AccessibleJComponent
1445 1445 implements ChangeListener, PropertyChangeListener {
1446 1446
1447 1447 protected JViewport viewPort = null;
1448 1448
1449 1449 /*
1450 1450 * Resets the viewport ChangeListener and PropertyChangeListener
1451 1451 */
1452 1452 public void resetViewPort() {
1453 1453 if (viewPort != null) {
1454 1454 viewPort.removeChangeListener(this);
1455 1455 viewPort.removePropertyChangeListener(this);
1456 1456 }
1457 1457 viewPort = JScrollPane.this.getViewport();
1458 1458 if (viewPort != null) {
1459 1459 viewPort.addChangeListener(this);
1460 1460 viewPort.addPropertyChangeListener(this);
1461 1461 }
1462 1462 }
1463 1463
1464 1464 /**
1465 1465 * AccessibleJScrollPane constructor
1466 1466 */
1467 1467 public AccessibleJScrollPane() {
1468 1468 super();
1469 1469
1470 1470 resetViewPort();
1471 1471
1472 1472 // initialize the AccessibleRelationSets for the JScrollPane
1473 1473 // and JScrollBar(s)
1474 1474 JScrollBar scrollBar = getHorizontalScrollBar();
1475 1475 if (scrollBar != null) {
1476 1476 setScrollBarRelations(scrollBar);
1477 1477 }
1478 1478 scrollBar = getVerticalScrollBar();
1479 1479 if (scrollBar != null) {
1480 1480 setScrollBarRelations(scrollBar);
1481 1481 }
1482 1482 }
1483 1483
1484 1484 /**
1485 1485 * Get the role of this object.
1486 1486 *
1487 1487 * @return an instance of AccessibleRole describing the role of the
1488 1488 * object
1489 1489 * @see AccessibleRole
1490 1490 */
1491 1491 public AccessibleRole getAccessibleRole() {
1492 1492 return AccessibleRole.SCROLL_PANE;
1493 1493 }
1494 1494
1495 1495 /**
1496 1496 * Invoked when the target of the listener has changed its state.
1497 1497 *
1498 1498 * @param e a <code>ChangeEvent</code> object. Must not be null.
1499 1499 *
1500 1500 * @throws NullPointerException if the parameter is null.
1501 1501 */
1502 1502 public void stateChanged(ChangeEvent e) {
1503 1503 if (e == null) {
1504 1504 throw new NullPointerException();
1505 1505 }
1506 1506 firePropertyChange(ACCESSIBLE_VISIBLE_DATA_PROPERTY,
1507 1507 Boolean.valueOf(false),
1508 1508 Boolean.valueOf(true));
1509 1509 }
1510 1510
1511 1511 /**
1512 1512 * This method gets called when a bound property is changed.
1513 1513 * @param e A <code>PropertyChangeEvent</code> object describing
1514 1514 * the event source and the property that has changed. Must not be null.
1515 1515 *
1516 1516 * @throws NullPointerException if the parameter is null.
1517 1517 * @since 1.5
1518 1518 */
1519 1519 public void propertyChange(PropertyChangeEvent e) {
1520 1520 String propertyName = e.getPropertyName();
1521 1521 if (propertyName == "horizontalScrollBar" ||
1522 1522 propertyName == "verticalScrollBar") {
1523 1523
1524 1524 if (e.getNewValue() instanceof JScrollBar) {
1525 1525 setScrollBarRelations((JScrollBar)e.getNewValue());
1526 1526 }
1527 1527 }
1528 1528 }
1529 1529
1530 1530
1531 1531 /*
1532 1532 * Sets the CONTROLLER_FOR and CONTROLLED_BY AccessibleRelations for
1533 1533 * the JScrollPane and JScrollBar. JScrollBar must not be null.
1534 1534 */
1535 1535 void setScrollBarRelations(JScrollBar scrollBar) {
1536 1536 /*
1537 1537 * The JScrollBar is a CONTROLLER_FOR the JScrollPane.
1538 1538 * The JScrollPane is CONTROLLED_BY the JScrollBar.
1539 1539 */
1540 1540 AccessibleRelation controlledBy =
1541 1541 new AccessibleRelation(AccessibleRelation.CONTROLLED_BY,
1542 1542 scrollBar);
1543 1543 AccessibleRelation controllerFor =
1544 1544 new AccessibleRelation(AccessibleRelation.CONTROLLER_FOR,
1545 1545 JScrollPane.this);
1546 1546
1547 1547 // set the relation set for the scroll bar
1548 1548 AccessibleContext ac = scrollBar.getAccessibleContext();
1549 1549 ac.getAccessibleRelationSet().add(controllerFor);
1550 1550
1551 1551 // set the relation set for the scroll pane
1552 1552 getAccessibleRelationSet().add(controlledBy);
1553 1553 }
1554 1554 }
1555 1555 }
↓ open down ↓ |
1492 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX