author | ohair |
Tue, 25 May 2010 15:58:33 -0700 | |
changeset 5506 | 202f599c92aa |
parent 715 | f16baef3a20e |
child 20458 | f2423fb3fd19 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
5506 | 2 |
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package javax.swing; |
|
27 |
||
28 |
||
29 |
import javax.swing.border.*; |
|
30 |
||
31 |
import java.awt.LayoutManager; |
|
32 |
import java.awt.Component; |
|
33 |
import java.awt.Container; |
|
34 |
import java.awt.Rectangle; |
|
35 |
import java.awt.Dimension; |
|
36 |
import java.awt.Insets; |
|
37 |
import java.io.Serializable; |
|
38 |
||
39 |
||
40 |
/** |
|
41 |
* The layout manager used by <code>JScrollPane</code>. |
|
42 |
* <code>JScrollPaneLayout</code> is |
|
43 |
* responsible for nine components: a viewport, two scrollbars, |
|
44 |
* a row header, a column header, and four "corner" components. |
|
45 |
* <p> |
|
46 |
* <strong>Warning:</strong> |
|
47 |
* Serialized objects of this class will not be compatible with |
|
48 |
* future Swing releases. The current serialization support is |
|
49 |
* appropriate for short term storage or RMI between applications running |
|
50 |
* the same version of Swing. As of 1.4, support for long term storage |
|
51 |
* of all JavaBeans<sup><font size="-2">TM</font></sup> |
|
52 |
* has been added to the <code>java.beans</code> package. |
|
53 |
* Please see {@link java.beans.XMLEncoder}. |
|
54 |
* |
|
55 |
* @see JScrollPane |
|
56 |
* @see JViewport |
|
57 |
* |
|
58 |
* @author Hans Muller |
|
59 |
*/ |
|
60 |
public class ScrollPaneLayout |
|
61 |
implements LayoutManager, ScrollPaneConstants, Serializable |
|
62 |
{ |
|
63 |
||
64 |
/** |
|
65 |
* The scrollpane's viewport child. |
|
66 |
* Default is an empty <code>JViewport</code>. |
|
67 |
* @see JScrollPane#setViewport |
|
68 |
*/ |
|
69 |
protected JViewport viewport; |
|
70 |
||
71 |
||
72 |
/** |
|
73 |
* The scrollpane's vertical scrollbar child. |
|
74 |
* Default is a <code>JScrollBar</code>. |
|
75 |
* @see JScrollPane#setVerticalScrollBar |
|
76 |
*/ |
|
77 |
protected JScrollBar vsb; |
|
78 |
||
79 |
||
80 |
/** |
|
81 |
* The scrollpane's horizontal scrollbar child. |
|
82 |
* Default is a <code>JScrollBar</code>. |
|
83 |
* @see JScrollPane#setHorizontalScrollBar |
|
84 |
*/ |
|
85 |
protected JScrollBar hsb; |
|
86 |
||
87 |
||
88 |
/** |
|
89 |
* The row header child. Default is <code>null</code>. |
|
90 |
* @see JScrollPane#setRowHeader |
|
91 |
*/ |
|
92 |
protected JViewport rowHead; |
|
93 |
||
94 |
||
95 |
/** |
|
96 |
* The column header child. Default is <code>null</code>. |
|
97 |
* @see JScrollPane#setColumnHeader |
|
98 |
*/ |
|
99 |
protected JViewport colHead; |
|
100 |
||
101 |
||
102 |
/** |
|
103 |
* The component to display in the lower left corner. |
|
104 |
* Default is <code>null</code>. |
|
105 |
* @see JScrollPane#setCorner |
|
106 |
*/ |
|
107 |
protected Component lowerLeft; |
|
108 |
||
109 |
||
110 |
/** |
|
111 |
* The component to display in the lower right corner. |
|
112 |
* Default is <code>null</code>. |
|
113 |
* @see JScrollPane#setCorner |
|
114 |
*/ |
|
115 |
protected Component lowerRight; |
|
116 |
||
117 |
||
118 |
/** |
|
119 |
* The component to display in the upper left corner. |
|
120 |
* Default is <code>null</code>. |
|
121 |
* @see JScrollPane#setCorner |
|
122 |
*/ |
|
123 |
protected Component upperLeft; |
|
124 |
||
125 |
||
126 |
/** |
|
127 |
* The component to display in the upper right corner. |
|
128 |
* Default is <code>null</code>. |
|
129 |
* @see JScrollPane#setCorner |
|
130 |
*/ |
|
131 |
protected Component upperRight; |
|
132 |
||
133 |
||
134 |
/** |
|
135 |
* The display policy for the vertical scrollbar. |
|
136 |
* The default is <code>ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED</code>. |
|
137 |
* <p> |
|
138 |
* This field is obsolete, please use the <code>JScrollPane</code> field instead. |
|
139 |
* |
|
140 |
* @see JScrollPane#setVerticalScrollBarPolicy |
|
141 |
*/ |
|
142 |
protected int vsbPolicy = VERTICAL_SCROLLBAR_AS_NEEDED; |
|
143 |
||
144 |
||
145 |
/** |
|
146 |
* The display policy for the horizontal scrollbar. |
|
147 |
* The default is <code>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED</code>. |
|
148 |
* <p> |
|
149 |
* This field is obsolete, please use the <code>JScrollPane</code> field instead. |
|
150 |
* |
|
151 |
* @see JScrollPane#setHorizontalScrollBarPolicy |
|
152 |
*/ |
|
153 |
protected int hsbPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED; |
|
154 |
||
155 |
||
156 |
/** |
|
157 |
* This method is invoked after the ScrollPaneLayout is set as the |
|
158 |
* LayoutManager of a <code>JScrollPane</code>. |
|
159 |
* It initializes all of the internal fields that |
|
160 |
* are ordinarily set by <code>addLayoutComponent</code>. For example: |
|
161 |
* <pre> |
|
162 |
* ScrollPaneLayout mySPLayout = new ScrollPanelLayout() { |
|
163 |
* public void layoutContainer(Container p) { |
|
164 |
* super.layoutContainer(p); |
|
165 |
* // do some extra work here ... |
|
166 |
* } |
|
167 |
* }; |
|
168 |
* scrollpane.setLayout(mySPLayout): |
|
169 |
* </pre> |
|
170 |
*/ |
|
171 |
public void syncWithScrollPane(JScrollPane sp) { |
|
172 |
viewport = sp.getViewport(); |
|
173 |
vsb = sp.getVerticalScrollBar(); |
|
174 |
hsb = sp.getHorizontalScrollBar(); |
|
175 |
rowHead = sp.getRowHeader(); |
|
176 |
colHead = sp.getColumnHeader(); |
|
177 |
lowerLeft = sp.getCorner(LOWER_LEFT_CORNER); |
|
178 |
lowerRight = sp.getCorner(LOWER_RIGHT_CORNER); |
|
179 |
upperLeft = sp.getCorner(UPPER_LEFT_CORNER); |
|
180 |
upperRight = sp.getCorner(UPPER_RIGHT_CORNER); |
|
181 |
vsbPolicy = sp.getVerticalScrollBarPolicy(); |
|
182 |
hsbPolicy = sp.getHorizontalScrollBarPolicy(); |
|
183 |
} |
|
184 |
||
185 |
||
186 |
/** |
|
187 |
* Removes an existing component. When a new component, such as |
|
188 |
* the left corner, or vertical scrollbar, is added, the old one, |
|
189 |
* if it exists, must be removed. |
|
190 |
* <p> |
|
191 |
* This method returns <code>newC</code>. If <code>oldC</code> is |
|
192 |
* not equal to <code>newC</code> and is non-<code>null</code>, |
|
193 |
* it will be removed from its parent. |
|
194 |
* |
|
195 |
* @param oldC the <code>Component</code> to replace |
|
196 |
* @param newC the <code>Component</code> to add |
|
197 |
* @return the <code>newC</code> |
|
198 |
*/ |
|
199 |
protected Component addSingletonComponent(Component oldC, Component newC) |
|
200 |
{ |
|
201 |
if ((oldC != null) && (oldC != newC)) { |
|
202 |
oldC.getParent().remove(oldC); |
|
203 |
} |
|
204 |
return newC; |
|
205 |
} |
|
206 |
||
207 |
||
208 |
/** |
|
209 |
* Adds the specified component to the layout. The layout is |
|
210 |
* identified using one of: |
|
211 |
* <ul> |
|
212 |
* <li>ScrollPaneConstants.VIEWPORT |
|
213 |
* <li>ScrollPaneConstants.VERTICAL_SCROLLBAR |
|
214 |
* <li>ScrollPaneConstants.HORIZONTAL_SCROLLBAR |
|
215 |
* <li>ScrollPaneConstants.ROW_HEADER |
|
216 |
* <li>ScrollPaneConstants.COLUMN_HEADER |
|
217 |
* <li>ScrollPaneConstants.LOWER_LEFT_CORNER |
|
218 |
* <li>ScrollPaneConstants.LOWER_RIGHT_CORNER |
|
219 |
* <li>ScrollPaneConstants.UPPER_LEFT_CORNER |
|
220 |
* <li>ScrollPaneConstants.UPPER_RIGHT_CORNER |
|
221 |
* </ul> |
|
222 |
* |
|
223 |
* @param s the component identifier |
|
224 |
* @param c the the component to be added |
|
225 |
* @exception IllegalArgumentException if <code>s</code> is an invalid key |
|
226 |
*/ |
|
227 |
public void addLayoutComponent(String s, Component c) |
|
228 |
{ |
|
229 |
if (s.equals(VIEWPORT)) { |
|
230 |
viewport = (JViewport)addSingletonComponent(viewport, c); |
|
231 |
} |
|
232 |
else if (s.equals(VERTICAL_SCROLLBAR)) { |
|
233 |
vsb = (JScrollBar)addSingletonComponent(vsb, c); |
|
234 |
} |
|
235 |
else if (s.equals(HORIZONTAL_SCROLLBAR)) { |
|
236 |
hsb = (JScrollBar)addSingletonComponent(hsb, c); |
|
237 |
} |
|
238 |
else if (s.equals(ROW_HEADER)) { |
|
239 |
rowHead = (JViewport)addSingletonComponent(rowHead, c); |
|
240 |
} |
|
241 |
else if (s.equals(COLUMN_HEADER)) { |
|
242 |
colHead = (JViewport)addSingletonComponent(colHead, c); |
|
243 |
} |
|
244 |
else if (s.equals(LOWER_LEFT_CORNER)) { |
|
245 |
lowerLeft = addSingletonComponent(lowerLeft, c); |
|
246 |
} |
|
247 |
else if (s.equals(LOWER_RIGHT_CORNER)) { |
|
248 |
lowerRight = addSingletonComponent(lowerRight, c); |
|
249 |
} |
|
250 |
else if (s.equals(UPPER_LEFT_CORNER)) { |
|
251 |
upperLeft = addSingletonComponent(upperLeft, c); |
|
252 |
} |
|
253 |
else if (s.equals(UPPER_RIGHT_CORNER)) { |
|
254 |
upperRight = addSingletonComponent(upperRight, c); |
|
255 |
} |
|
256 |
else { |
|
257 |
throw new IllegalArgumentException("invalid layout key " + s); |
|
258 |
} |
|
259 |
} |
|
260 |
||
261 |
||
262 |
/** |
|
263 |
* Removes the specified component from the layout. |
|
264 |
* |
|
265 |
* @param c the component to remove |
|
266 |
*/ |
|
267 |
public void removeLayoutComponent(Component c) |
|
268 |
{ |
|
269 |
if (c == viewport) { |
|
270 |
viewport = null; |
|
271 |
} |
|
272 |
else if (c == vsb) { |
|
273 |
vsb = null; |
|
274 |
} |
|
275 |
else if (c == hsb) { |
|
276 |
hsb = null; |
|
277 |
} |
|
278 |
else if (c == rowHead) { |
|
279 |
rowHead = null; |
|
280 |
} |
|
281 |
else if (c == colHead) { |
|
282 |
colHead = null; |
|
283 |
} |
|
284 |
else if (c == lowerLeft) { |
|
285 |
lowerLeft = null; |
|
286 |
} |
|
287 |
else if (c == lowerRight) { |
|
288 |
lowerRight = null; |
|
289 |
} |
|
290 |
else if (c == upperLeft) { |
|
291 |
upperLeft = null; |
|
292 |
} |
|
293 |
else if (c == upperRight) { |
|
294 |
upperRight = null; |
|
295 |
} |
|
296 |
} |
|
297 |
||
298 |
||
299 |
/** |
|
300 |
* Returns the vertical scrollbar-display policy. |
|
301 |
* |
|
302 |
* @return an integer giving the display policy |
|
303 |
* @see #setVerticalScrollBarPolicy |
|
304 |
*/ |
|
305 |
public int getVerticalScrollBarPolicy() { |
|
306 |
return vsbPolicy; |
|
307 |
} |
|
308 |
||
309 |
||
310 |
/** |
|
311 |
* Sets the vertical scrollbar-display policy. The options |
|
312 |
* are: |
|
313 |
* <ul> |
|
314 |
* <li>ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED |
|
315 |
* <li>ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER |
|
316 |
* <li>ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS |
|
317 |
* </ul> |
|
318 |
* Note: Applications should use the <code>JScrollPane</code> version |
|
319 |
* of this method. It only exists for backwards compatibility |
|
320 |
* with the Swing 1.0.2 (and earlier) versions of this class. |
|
321 |
* |
|
322 |
* @param x an integer giving the display policy |
|
323 |
* @exception IllegalArgumentException if <code>x</code> is an invalid |
|
324 |
* vertical scroll bar policy, as listed above |
|
325 |
*/ |
|
326 |
public void setVerticalScrollBarPolicy(int x) { |
|
327 |
switch (x) { |
|
328 |
case VERTICAL_SCROLLBAR_AS_NEEDED: |
|
329 |
case VERTICAL_SCROLLBAR_NEVER: |
|
330 |
case VERTICAL_SCROLLBAR_ALWAYS: |
|
331 |
vsbPolicy = x; |
|
332 |
break; |
|
333 |
default: |
|
334 |
throw new IllegalArgumentException("invalid verticalScrollBarPolicy"); |
|
335 |
} |
|
336 |
} |
|
337 |
||
338 |
||
339 |
/** |
|
340 |
* Returns the horizontal scrollbar-display policy. |
|
341 |
* |
|
342 |
* @return an integer giving the display policy |
|
343 |
* @see #setHorizontalScrollBarPolicy |
|
344 |
*/ |
|
345 |
public int getHorizontalScrollBarPolicy() { |
|
346 |
return hsbPolicy; |
|
347 |
} |
|
348 |
||
349 |
/** |
|
350 |
* Sets the horizontal scrollbar-display policy. |
|
351 |
* The options are:<ul> |
|
352 |
* <li>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED |
|
353 |
* <li>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER |
|
354 |
* <li>ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS |
|
355 |
* </ul> |
|
356 |
* Note: Applications should use the <code>JScrollPane</code> version |
|
357 |
* of this method. It only exists for backwards compatibility |
|
358 |
* with the Swing 1.0.2 (and earlier) versions of this class. |
|
359 |
* |
|
360 |
* @param x an int giving the display policy |
|
361 |
* @exception IllegalArgumentException if <code>x</code> is not a valid |
|
362 |
* horizontal scrollbar policy, as listed above |
|
363 |
*/ |
|
364 |
public void setHorizontalScrollBarPolicy(int x) { |
|
365 |
switch (x) { |
|
366 |
case HORIZONTAL_SCROLLBAR_AS_NEEDED: |
|
367 |
case HORIZONTAL_SCROLLBAR_NEVER: |
|
368 |
case HORIZONTAL_SCROLLBAR_ALWAYS: |
|
369 |
hsbPolicy = x; |
|
370 |
break; |
|
371 |
default: |
|
372 |
throw new IllegalArgumentException("invalid horizontalScrollBarPolicy"); |
|
373 |
} |
|
374 |
} |
|
375 |
||
376 |
||
377 |
/** |
|
378 |
* Returns the <code>JViewport</code> object that displays the |
|
379 |
* scrollable contents. |
|
380 |
* @return the <code>JViewport</code> object that displays the scrollable contents |
|
381 |
* @see JScrollPane#getViewport |
|
382 |
*/ |
|
383 |
public JViewport getViewport() { |
|
384 |
return viewport; |
|
385 |
} |
|
386 |
||
387 |
||
388 |
/** |
|
389 |
* Returns the <code>JScrollBar</code> object that handles horizontal scrolling. |
|
390 |
* @return the <code>JScrollBar</code> object that handles horizontal scrolling |
|
391 |
* @see JScrollPane#getHorizontalScrollBar |
|
392 |
*/ |
|
393 |
public JScrollBar getHorizontalScrollBar() { |
|
394 |
return hsb; |
|
395 |
} |
|
396 |
||
397 |
/** |
|
398 |
* Returns the <code>JScrollBar</code> object that handles vertical scrolling. |
|
399 |
* @return the <code>JScrollBar</code> object that handles vertical scrolling |
|
400 |
* @see JScrollPane#getVerticalScrollBar |
|
401 |
*/ |
|
402 |
public JScrollBar getVerticalScrollBar() { |
|
403 |
return vsb; |
|
404 |
} |
|
405 |
||
406 |
||
407 |
/** |
|
408 |
* Returns the <code>JViewport</code> object that is the row header. |
|
409 |
* @return the <code>JViewport</code> object that is the row header |
|
410 |
* @see JScrollPane#getRowHeader |
|
411 |
*/ |
|
412 |
public JViewport getRowHeader() { |
|
413 |
return rowHead; |
|
414 |
} |
|
415 |
||
416 |
||
417 |
/** |
|
418 |
* Returns the <code>JViewport</code> object that is the column header. |
|
419 |
* @return the <code>JViewport</code> object that is the column header |
|
420 |
* @see JScrollPane#getColumnHeader |
|
421 |
*/ |
|
422 |
public JViewport getColumnHeader() { |
|
423 |
return colHead; |
|
424 |
} |
|
425 |
||
426 |
||
427 |
/** |
|
428 |
* Returns the <code>Component</code> at the specified corner. |
|
429 |
* @param key the <code>String</code> specifying the corner |
|
430 |
* @return the <code>Component</code> at the specified corner, as defined in |
|
431 |
* {@link ScrollPaneConstants}; if <code>key</code> is not one of the |
|
432 |
* four corners, <code>null</code> is returned |
|
433 |
* @see JScrollPane#getCorner |
|
434 |
*/ |
|
435 |
public Component getCorner(String key) { |
|
436 |
if (key.equals(LOWER_LEFT_CORNER)) { |
|
437 |
return lowerLeft; |
|
438 |
} |
|
439 |
else if (key.equals(LOWER_RIGHT_CORNER)) { |
|
440 |
return lowerRight; |
|
441 |
} |
|
442 |
else if (key.equals(UPPER_LEFT_CORNER)) { |
|
443 |
return upperLeft; |
|
444 |
} |
|
445 |
else if (key.equals(UPPER_RIGHT_CORNER)) { |
|
446 |
return upperRight; |
|
447 |
} |
|
448 |
else { |
|
449 |
return null; |
|
450 |
} |
|
451 |
} |
|
452 |
||
453 |
||
454 |
/** |
|
455 |
* The preferred size of a <code>ScrollPane</code> is the size of the insets, |
|
456 |
* plus the preferred size of the viewport, plus the preferred size of |
|
457 |
* the visible headers, plus the preferred size of the scrollbars |
|
458 |
* that will appear given the current view and the current |
|
459 |
* scrollbar displayPolicies. |
|
460 |
* <p>Note that the rowHeader is calculated as part of the preferred width |
|
461 |
* and the colHeader is calculated as part of the preferred size. |
|
462 |
* |
|
463 |
* @param parent the <code>Container</code> that will be laid out |
|
464 |
* @return a <code>Dimension</code> object specifying the preferred size of the |
|
465 |
* viewport and any scrollbars |
|
466 |
* @see ViewportLayout |
|
467 |
* @see LayoutManager |
|
468 |
*/ |
|
469 |
public Dimension preferredLayoutSize(Container parent) |
|
470 |
{ |
|
471 |
/* Sync the (now obsolete) policy fields with the |
|
472 |
* JScrollPane. |
|
473 |
*/ |
|
474 |
JScrollPane scrollPane = (JScrollPane)parent; |
|
475 |
vsbPolicy = scrollPane.getVerticalScrollBarPolicy(); |
|
476 |
hsbPolicy = scrollPane.getHorizontalScrollBarPolicy(); |
|
477 |
||
478 |
Insets insets = parent.getInsets(); |
|
479 |
int prefWidth = insets.left + insets.right; |
|
480 |
int prefHeight = insets.top + insets.bottom; |
|
481 |
||
482 |
/* Note that viewport.getViewSize() is equivalent to |
|
483 |
* viewport.getView().getPreferredSize() modulo a null |
|
484 |
* view or a view whose size was explicitly set. |
|
485 |
*/ |
|
486 |
||
487 |
Dimension extentSize = null; |
|
488 |
Dimension viewSize = null; |
|
489 |
Component view = null; |
|
490 |
||
412
002786c2e5bb
6612531: api/javax_swing/ScrollPaneLayout/index.html#xxxLayoutSize (ScrollPaneLayout2024) throws NPE
mlapshin
parents:
2
diff
changeset
|
491 |
if (viewport != null) { |
2 | 492 |
extentSize = viewport.getPreferredSize(); |
493 |
view = viewport.getView(); |
|
412
002786c2e5bb
6612531: api/javax_swing/ScrollPaneLayout/index.html#xxxLayoutSize (ScrollPaneLayout2024) throws NPE
mlapshin
parents:
2
diff
changeset
|
494 |
if (view != null) { |
002786c2e5bb
6612531: api/javax_swing/ScrollPaneLayout/index.html#xxxLayoutSize (ScrollPaneLayout2024) throws NPE
mlapshin
parents:
2
diff
changeset
|
495 |
viewSize = view.getPreferredSize(); |
002786c2e5bb
6612531: api/javax_swing/ScrollPaneLayout/index.html#xxxLayoutSize (ScrollPaneLayout2024) throws NPE
mlapshin
parents:
2
diff
changeset
|
496 |
} else { |
002786c2e5bb
6612531: api/javax_swing/ScrollPaneLayout/index.html#xxxLayoutSize (ScrollPaneLayout2024) throws NPE
mlapshin
parents:
2
diff
changeset
|
497 |
viewSize = new Dimension(0, 0); |
002786c2e5bb
6612531: api/javax_swing/ScrollPaneLayout/index.html#xxxLayoutSize (ScrollPaneLayout2024) throws NPE
mlapshin
parents:
2
diff
changeset
|
498 |
} |
2 | 499 |
} |
500 |
||
501 |
/* If there's a viewport add its preferredSize. |
|
502 |
*/ |
|
503 |
||
504 |
if (extentSize != null) { |
|
505 |
prefWidth += extentSize.width; |
|
506 |
prefHeight += extentSize.height; |
|
507 |
} |
|
508 |
||
509 |
/* If there's a JScrollPane.viewportBorder, add its insets. |
|
510 |
*/ |
|
511 |
||
512 |
Border viewportBorder = scrollPane.getViewportBorder(); |
|
513 |
if (viewportBorder != null) { |
|
514 |
Insets vpbInsets = viewportBorder.getBorderInsets(parent); |
|
515 |
prefWidth += vpbInsets.left + vpbInsets.right; |
|
516 |
prefHeight += vpbInsets.top + vpbInsets.bottom; |
|
517 |
} |
|
518 |
||
519 |
/* If a header exists and it's visible, factor its |
|
520 |
* preferred size in. |
|
521 |
*/ |
|
522 |
||
523 |
if ((rowHead != null) && rowHead.isVisible()) { |
|
524 |
prefWidth += rowHead.getPreferredSize().width; |
|
525 |
} |
|
526 |
||
527 |
if ((colHead != null) && colHead.isVisible()) { |
|
528 |
prefHeight += colHead.getPreferredSize().height; |
|
529 |
} |
|
530 |
||
531 |
/* If a scrollbar is going to appear, factor its preferred size in. |
|
532 |
* If the scrollbars policy is AS_NEEDED, this can be a little |
|
533 |
* tricky: |
|
534 |
* |
|
535 |
* - If the view is a Scrollable then scrollableTracksViewportWidth |
|
536 |
* and scrollableTracksViewportHeight can be used to effectively |
|
537 |
* disable scrolling (if they're true) in their respective dimensions. |
|
538 |
* |
|
539 |
* - Assuming that a scrollbar hasn't been disabled by the |
|
540 |
* previous constraint, we need to decide if the scrollbar is going |
|
541 |
* to appear to correctly compute the JScrollPanes preferred size. |
|
542 |
* To do this we compare the preferredSize of the viewport (the |
|
543 |
* extentSize) to the preferredSize of the view. Although we're |
|
544 |
* not responsible for laying out the view we'll assume that the |
|
545 |
* JViewport will always give it its preferredSize. |
|
546 |
*/ |
|
547 |
||
548 |
if ((vsb != null) && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) { |
|
549 |
if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) { |
|
550 |
prefWidth += vsb.getPreferredSize().width; |
|
551 |
} |
|
552 |
else if ((viewSize != null) && (extentSize != null)) { |
|
553 |
boolean canScroll = true; |
|
554 |
if (view instanceof Scrollable) { |
|
555 |
canScroll = !((Scrollable)view).getScrollableTracksViewportHeight(); |
|
556 |
} |
|
557 |
if (canScroll && (viewSize.height > extentSize.height)) { |
|
558 |
prefWidth += vsb.getPreferredSize().width; |
|
559 |
} |
|
560 |
} |
|
561 |
} |
|
562 |
||
563 |
if ((hsb != null) && (hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER)) { |
|
564 |
if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) { |
|
565 |
prefHeight += hsb.getPreferredSize().height; |
|
566 |
} |
|
567 |
else if ((viewSize != null) && (extentSize != null)) { |
|
568 |
boolean canScroll = true; |
|
569 |
if (view instanceof Scrollable) { |
|
570 |
canScroll = !((Scrollable)view).getScrollableTracksViewportWidth(); |
|
571 |
} |
|
572 |
if (canScroll && (viewSize.width > extentSize.width)) { |
|
573 |
prefHeight += hsb.getPreferredSize().height; |
|
574 |
} |
|
575 |
} |
|
576 |
} |
|
577 |
||
578 |
return new Dimension(prefWidth, prefHeight); |
|
579 |
} |
|
580 |
||
581 |
||
582 |
/** |
|
583 |
* The minimum size of a <code>ScrollPane</code> is the size of the insets |
|
584 |
* plus minimum size of the viewport, plus the scrollpane's |
|
585 |
* viewportBorder insets, plus the minimum size |
|
586 |
* of the visible headers, plus the minimum size of the |
|
587 |
* scrollbars whose displayPolicy isn't NEVER. |
|
588 |
* |
|
589 |
* @param parent the <code>Container</code> that will be laid out |
|
590 |
* @return a <code>Dimension</code> object specifying the minimum size |
|
591 |
*/ |
|
592 |
public Dimension minimumLayoutSize(Container parent) |
|
593 |
{ |
|
594 |
/* Sync the (now obsolete) policy fields with the |
|
595 |
* JScrollPane. |
|
596 |
*/ |
|
597 |
JScrollPane scrollPane = (JScrollPane)parent; |
|
598 |
vsbPolicy = scrollPane.getVerticalScrollBarPolicy(); |
|
599 |
hsbPolicy = scrollPane.getHorizontalScrollBarPolicy(); |
|
600 |
||
601 |
Insets insets = parent.getInsets(); |
|
602 |
int minWidth = insets.left + insets.right; |
|
603 |
int minHeight = insets.top + insets.bottom; |
|
604 |
||
605 |
/* If there's a viewport add its minimumSize. |
|
606 |
*/ |
|
607 |
||
608 |
if (viewport != null) { |
|
609 |
Dimension size = viewport.getMinimumSize(); |
|
610 |
minWidth += size.width; |
|
611 |
minHeight += size.height; |
|
612 |
} |
|
613 |
||
614 |
/* If there's a JScrollPane.viewportBorder, add its insets. |
|
615 |
*/ |
|
616 |
||
617 |
Border viewportBorder = scrollPane.getViewportBorder(); |
|
618 |
if (viewportBorder != null) { |
|
619 |
Insets vpbInsets = viewportBorder.getBorderInsets(parent); |
|
620 |
minWidth += vpbInsets.left + vpbInsets.right; |
|
621 |
minHeight += vpbInsets.top + vpbInsets.bottom; |
|
622 |
} |
|
623 |
||
624 |
/* If a header exists and it's visible, factor its |
|
625 |
* minimum size in. |
|
626 |
*/ |
|
627 |
||
628 |
if ((rowHead != null) && rowHead.isVisible()) { |
|
629 |
Dimension size = rowHead.getMinimumSize(); |
|
630 |
minWidth += size.width; |
|
631 |
minHeight = Math.max(minHeight, size.height); |
|
632 |
} |
|
633 |
||
634 |
if ((colHead != null) && colHead.isVisible()) { |
|
635 |
Dimension size = colHead.getMinimumSize(); |
|
636 |
minWidth = Math.max(minWidth, size.width); |
|
637 |
minHeight += size.height; |
|
638 |
} |
|
639 |
||
640 |
/* If a scrollbar might appear, factor its minimum |
|
641 |
* size in. |
|
642 |
*/ |
|
643 |
||
644 |
if ((vsb != null) && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) { |
|
645 |
Dimension size = vsb.getMinimumSize(); |
|
646 |
minWidth += size.width; |
|
647 |
minHeight = Math.max(minHeight, size.height); |
|
648 |
} |
|
649 |
||
650 |
if ((hsb != null) && (hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER)) { |
|
651 |
Dimension size = hsb.getMinimumSize(); |
|
652 |
minWidth = Math.max(minWidth, size.width); |
|
653 |
minHeight += size.height; |
|
654 |
} |
|
655 |
||
656 |
return new Dimension(minWidth, minHeight); |
|
657 |
} |
|
658 |
||
659 |
||
660 |
/** |
|
661 |
* Lays out the scrollpane. The positioning of components depends on |
|
662 |
* the following constraints: |
|
663 |
* <ul> |
|
664 |
* <li> The row header, if present and visible, gets its preferred |
|
665 |
* width and the viewport's height. |
|
666 |
* |
|
667 |
* <li> The column header, if present and visible, gets its preferred |
|
668 |
* height and the viewport's width. |
|
669 |
* |
|
670 |
* <li> If a vertical scrollbar is needed, i.e. if the viewport's extent |
|
671 |
* height is smaller than its view height or if the <code>displayPolicy</code> |
|
672 |
* is ALWAYS, it's treated like the row header with respect to its |
|
673 |
* dimensions and is made visible. |
|
674 |
* |
|
675 |
* <li> If a horizontal scrollbar is needed, it is treated like the |
|
676 |
* column header (see the paragraph above regarding the vertical scrollbar). |
|
677 |
* |
|
678 |
* <li> If the scrollpane has a non-<code>null</code> |
|
679 |
* <code>viewportBorder</code>, then space is allocated for that. |
|
680 |
* |
|
681 |
* <li> The viewport gets the space available after accounting for |
|
682 |
* the previous constraints. |
|
683 |
* |
|
684 |
* <li> The corner components, if provided, are aligned with the |
|
685 |
* ends of the scrollbars and headers. If there is a vertical |
|
686 |
* scrollbar, the right corners appear; if there is a horizontal |
|
687 |
* scrollbar, the lower corners appear; a row header gets left |
|
688 |
* corners, and a column header gets upper corners. |
|
689 |
* </ul> |
|
690 |
* |
|
691 |
* @param parent the <code>Container</code> to lay out |
|
692 |
*/ |
|
693 |
public void layoutContainer(Container parent) |
|
694 |
{ |
|
695 |
/* Sync the (now obsolete) policy fields with the |
|
696 |
* JScrollPane. |
|
697 |
*/ |
|
698 |
JScrollPane scrollPane = (JScrollPane)parent; |
|
699 |
vsbPolicy = scrollPane.getVerticalScrollBarPolicy(); |
|
700 |
hsbPolicy = scrollPane.getHorizontalScrollBarPolicy(); |
|
701 |
||
702 |
Rectangle availR = scrollPane.getBounds(); |
|
703 |
availR.x = availR.y = 0; |
|
704 |
||
705 |
Insets insets = parent.getInsets(); |
|
706 |
availR.x = insets.left; |
|
707 |
availR.y = insets.top; |
|
708 |
availR.width -= insets.left + insets.right; |
|
709 |
availR.height -= insets.top + insets.bottom; |
|
710 |
||
711 |
/* Get the scrollPane's orientation. |
|
712 |
*/ |
|
713 |
boolean leftToRight = SwingUtilities.isLeftToRight(scrollPane); |
|
714 |
||
715 |
/* If there's a visible column header remove the space it |
|
716 |
* needs from the top of availR. The column header is treated |
|
717 |
* as if it were fixed height, arbitrary width. |
|
718 |
*/ |
|
719 |
||
720 |
Rectangle colHeadR = new Rectangle(0, availR.y, 0, 0); |
|
721 |
||
722 |
if ((colHead != null) && (colHead.isVisible())) { |
|
723 |
int colHeadHeight = Math.min(availR.height, |
|
724 |
colHead.getPreferredSize().height); |
|
725 |
colHeadR.height = colHeadHeight; |
|
726 |
availR.y += colHeadHeight; |
|
727 |
availR.height -= colHeadHeight; |
|
728 |
} |
|
729 |
||
730 |
/* If there's a visible row header remove the space it needs |
|
731 |
* from the left or right of availR. The row header is treated |
|
732 |
* as if it were fixed width, arbitrary height. |
|
733 |
*/ |
|
734 |
||
735 |
Rectangle rowHeadR = new Rectangle(0, 0, 0, 0); |
|
736 |
||
737 |
if ((rowHead != null) && (rowHead.isVisible())) { |
|
738 |
int rowHeadWidth = Math.min(availR.width, |
|
739 |
rowHead.getPreferredSize().width); |
|
740 |
rowHeadR.width = rowHeadWidth; |
|
741 |
availR.width -= rowHeadWidth; |
|
742 |
if ( leftToRight ) { |
|
743 |
rowHeadR.x = availR.x; |
|
744 |
availR.x += rowHeadWidth; |
|
745 |
} else { |
|
746 |
rowHeadR.x = availR.x + availR.width; |
|
747 |
} |
|
748 |
} |
|
749 |
||
750 |
/* If there's a JScrollPane.viewportBorder, remove the |
|
751 |
* space it occupies for availR. |
|
752 |
*/ |
|
753 |
||
754 |
Border viewportBorder = scrollPane.getViewportBorder(); |
|
755 |
Insets vpbInsets; |
|
756 |
if (viewportBorder != null) { |
|
757 |
vpbInsets = viewportBorder.getBorderInsets(parent); |
|
758 |
availR.x += vpbInsets.left; |
|
759 |
availR.y += vpbInsets.top; |
|
760 |
availR.width -= vpbInsets.left + vpbInsets.right; |
|
761 |
availR.height -= vpbInsets.top + vpbInsets.bottom; |
|
762 |
} |
|
763 |
else { |
|
764 |
vpbInsets = new Insets(0,0,0,0); |
|
765 |
} |
|
766 |
||
767 |
||
768 |
/* At this point availR is the space available for the viewport |
|
769 |
* and scrollbars. rowHeadR is correct except for its height and y |
|
770 |
* and colHeadR is correct except for its width and x. Once we're |
|
771 |
* through computing the dimensions of these three parts we can |
|
772 |
* go back and set the dimensions of rowHeadR.height, rowHeadR.y, |
|
773 |
* colHeadR.width, colHeadR.x and the bounds for the corners. |
|
774 |
* |
|
775 |
* We'll decide about putting up scrollbars by comparing the |
|
776 |
* viewport views preferred size with the viewports extent |
|
777 |
* size (generally just its size). Using the preferredSize is |
|
778 |
* reasonable because layout proceeds top down - so we expect |
|
779 |
* the viewport to be laid out next. And we assume that the |
|
780 |
* viewports layout manager will give the view it's preferred |
|
781 |
* size. One exception to this is when the view implements |
|
782 |
* Scrollable and Scrollable.getViewTracksViewport{Width,Height} |
|
783 |
* methods return true. If the view is tracking the viewports |
|
784 |
* width we don't bother with a horizontal scrollbar, similarly |
|
785 |
* if view.getViewTracksViewport(Height) is true we don't bother |
|
786 |
* with a vertical scrollbar. |
|
787 |
*/ |
|
788 |
||
789 |
Component view = (viewport != null) ? viewport.getView() : null; |
|
790 |
Dimension viewPrefSize = |
|
791 |
(view != null) ? view.getPreferredSize() |
|
792 |
: new Dimension(0,0); |
|
793 |
||
794 |
Dimension extentSize = |
|
795 |
(viewport != null) ? viewport.toViewCoordinates(availR.getSize()) |
|
796 |
: new Dimension(0,0); |
|
797 |
||
798 |
boolean viewTracksViewportWidth = false; |
|
799 |
boolean viewTracksViewportHeight = false; |
|
800 |
boolean isEmpty = (availR.width < 0 || availR.height < 0); |
|
801 |
Scrollable sv; |
|
802 |
// Don't bother checking the Scrollable methods if there is no room |
|
803 |
// for the viewport, we aren't going to show any scrollbars in this |
|
804 |
// case anyway. |
|
805 |
if (!isEmpty && view instanceof Scrollable) { |
|
806 |
sv = (Scrollable)view; |
|
807 |
viewTracksViewportWidth = sv.getScrollableTracksViewportWidth(); |
|
808 |
viewTracksViewportHeight = sv.getScrollableTracksViewportHeight(); |
|
809 |
} |
|
810 |
else { |
|
811 |
sv = null; |
|
812 |
} |
|
813 |
||
814 |
/* If there's a vertical scrollbar and we need one, allocate |
|
815 |
* space for it (we'll make it visible later). A vertical |
|
816 |
* scrollbar is considered to be fixed width, arbitrary height. |
|
817 |
*/ |
|
818 |
||
819 |
Rectangle vsbR = new Rectangle(0, availR.y - vpbInsets.top, 0, 0); |
|
820 |
||
821 |
boolean vsbNeeded; |
|
822 |
if (isEmpty) { |
|
823 |
vsbNeeded = false; |
|
824 |
} |
|
825 |
else if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) { |
|
826 |
vsbNeeded = true; |
|
827 |
} |
|
828 |
else if (vsbPolicy == VERTICAL_SCROLLBAR_NEVER) { |
|
829 |
vsbNeeded = false; |
|
830 |
} |
|
831 |
else { // vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED |
|
832 |
vsbNeeded = !viewTracksViewportHeight && (viewPrefSize.height > extentSize.height); |
|
833 |
} |
|
834 |
||
835 |
||
836 |
if ((vsb != null) && vsbNeeded) { |
|
837 |
adjustForVSB(true, availR, vsbR, vpbInsets, leftToRight); |
|
838 |
extentSize = viewport.toViewCoordinates(availR.getSize()); |
|
839 |
} |
|
840 |
||
841 |
/* If there's a horizontal scrollbar and we need one, allocate |
|
842 |
* space for it (we'll make it visible later). A horizontal |
|
843 |
* scrollbar is considered to be fixed height, arbitrary width. |
|
844 |
*/ |
|
845 |
||
846 |
Rectangle hsbR = new Rectangle(availR.x - vpbInsets.left, 0, 0, 0); |
|
847 |
boolean hsbNeeded; |
|
848 |
if (isEmpty) { |
|
849 |
hsbNeeded = false; |
|
850 |
} |
|
851 |
else if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) { |
|
852 |
hsbNeeded = true; |
|
853 |
} |
|
854 |
else if (hsbPolicy == HORIZONTAL_SCROLLBAR_NEVER) { |
|
855 |
hsbNeeded = false; |
|
856 |
} |
|
857 |
else { // hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED |
|
858 |
hsbNeeded = !viewTracksViewportWidth && (viewPrefSize.width > extentSize.width); |
|
859 |
} |
|
860 |
||
861 |
if ((hsb != null) && hsbNeeded) { |
|
862 |
adjustForHSB(true, availR, hsbR, vpbInsets); |
|
863 |
||
864 |
/* If we added the horizontal scrollbar then we've implicitly |
|
865 |
* reduced the vertical space available to the viewport. |
|
866 |
* As a consequence we may have to add the vertical scrollbar, |
|
867 |
* if that hasn't been done so already. Of course we |
|
868 |
* don't bother with any of this if the vsbPolicy is NEVER. |
|
869 |
*/ |
|
870 |
if ((vsb != null) && !vsbNeeded && |
|
871 |
(vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) { |
|
872 |
||
873 |
extentSize = viewport.toViewCoordinates(availR.getSize()); |
|
874 |
vsbNeeded = viewPrefSize.height > extentSize.height; |
|
875 |
||
876 |
if (vsbNeeded) { |
|
877 |
adjustForVSB(true, availR, vsbR, vpbInsets, leftToRight); |
|
878 |
} |
|
879 |
} |
|
880 |
} |
|
881 |
||
882 |
/* Set the size of the viewport first, and then recheck the Scrollable |
|
883 |
* methods. Some components base their return values for the Scrollable |
|
884 |
* methods on the size of the Viewport, so that if we don't |
|
885 |
* ask after resetting the bounds we may have gotten the wrong |
|
886 |
* answer. |
|
887 |
*/ |
|
888 |
||
889 |
if (viewport != null) { |
|
890 |
viewport.setBounds(availR); |
|
891 |
||
892 |
if (sv != null) { |
|
893 |
extentSize = viewport.toViewCoordinates(availR.getSize()); |
|
894 |
||
895 |
boolean oldHSBNeeded = hsbNeeded; |
|
896 |
boolean oldVSBNeeded = vsbNeeded; |
|
897 |
viewTracksViewportWidth = sv. |
|
898 |
getScrollableTracksViewportWidth(); |
|
899 |
viewTracksViewportHeight = sv. |
|
900 |
getScrollableTracksViewportHeight(); |
|
901 |
if (vsb != null && vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED) { |
|
902 |
boolean newVSBNeeded = !viewTracksViewportHeight && |
|
903 |
(viewPrefSize.height > extentSize.height); |
|
904 |
if (newVSBNeeded != vsbNeeded) { |
|
905 |
vsbNeeded = newVSBNeeded; |
|
906 |
adjustForVSB(vsbNeeded, availR, vsbR, vpbInsets, |
|
907 |
leftToRight); |
|
908 |
extentSize = viewport.toViewCoordinates |
|
909 |
(availR.getSize()); |
|
910 |
} |
|
911 |
} |
|
912 |
if (hsb != null && hsbPolicy ==HORIZONTAL_SCROLLBAR_AS_NEEDED){ |
|
913 |
boolean newHSBbNeeded = !viewTracksViewportWidth && |
|
914 |
(viewPrefSize.width > extentSize.width); |
|
915 |
if (newHSBbNeeded != hsbNeeded) { |
|
916 |
hsbNeeded = newHSBbNeeded; |
|
917 |
adjustForHSB(hsbNeeded, availR, hsbR, vpbInsets); |
|
918 |
if ((vsb != null) && !vsbNeeded && |
|
919 |
(vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) { |
|
920 |
||
921 |
extentSize = viewport.toViewCoordinates |
|
922 |
(availR.getSize()); |
|
923 |
vsbNeeded = viewPrefSize.height > |
|
924 |
extentSize.height; |
|
925 |
||
926 |
if (vsbNeeded) { |
|
927 |
adjustForVSB(true, availR, vsbR, vpbInsets, |
|
928 |
leftToRight); |
|
929 |
} |
|
930 |
} |
|
931 |
} |
|
932 |
} |
|
933 |
if (oldHSBNeeded != hsbNeeded || |
|
934 |
oldVSBNeeded != vsbNeeded) { |
|
935 |
viewport.setBounds(availR); |
|
936 |
// You could argue that we should recheck the |
|
937 |
// Scrollable methods again until they stop changing, |
|
938 |
// but they might never stop changing, so we stop here |
|
939 |
// and don't do any additional checks. |
|
940 |
} |
|
941 |
} |
|
942 |
} |
|
943 |
||
944 |
/* We now have the final size of the viewport: availR. |
|
945 |
* Now fixup the header and scrollbar widths/heights. |
|
946 |
*/ |
|
947 |
vsbR.height = availR.height + vpbInsets.top + vpbInsets.bottom; |
|
948 |
hsbR.width = availR.width + vpbInsets.left + vpbInsets.right; |
|
949 |
rowHeadR.height = availR.height + vpbInsets.top + vpbInsets.bottom; |
|
950 |
rowHeadR.y = availR.y - vpbInsets.top; |
|
951 |
colHeadR.width = availR.width + vpbInsets.left + vpbInsets.right; |
|
952 |
colHeadR.x = availR.x - vpbInsets.left; |
|
953 |
||
954 |
/* Set the bounds of the remaining components. The scrollbars |
|
955 |
* are made invisible if they're not needed. |
|
956 |
*/ |
|
957 |
||
958 |
if (rowHead != null) { |
|
959 |
rowHead.setBounds(rowHeadR); |
|
960 |
} |
|
961 |
||
962 |
if (colHead != null) { |
|
963 |
colHead.setBounds(colHeadR); |
|
964 |
} |
|
965 |
||
966 |
if (vsb != null) { |
|
967 |
if (vsbNeeded) { |
|
968 |
if (colHead != null && |
|
969 |
UIManager.getBoolean("ScrollPane.fillUpperCorner")) |
|
970 |
{ |
|
971 |
if ((leftToRight && upperRight == null) || |
|
972 |
(!leftToRight && upperLeft == null)) |
|
973 |
{ |
|
974 |
// This is used primarily for GTK L&F, which needs to |
|
975 |
// extend the vertical scrollbar to fill the upper |
|
976 |
// corner near the column header. Note that we skip |
|
977 |
// this step (and use the default behavior) if the |
|
978 |
// user has set a custom corner component. |
|
979 |
vsbR.y = colHeadR.y; |
|
980 |
vsbR.height += colHeadR.height; |
|
981 |
} |
|
982 |
} |
|
983 |
vsb.setVisible(true); |
|
984 |
vsb.setBounds(vsbR); |
|
985 |
} |
|
986 |
else { |
|
987 |
vsb.setVisible(false); |
|
988 |
} |
|
989 |
} |
|
990 |
||
991 |
if (hsb != null) { |
|
992 |
if (hsbNeeded) { |
|
993 |
if (rowHead != null && |
|
994 |
UIManager.getBoolean("ScrollPane.fillLowerCorner")) |
|
995 |
{ |
|
996 |
if ((leftToRight && lowerLeft == null) || |
|
997 |
(!leftToRight && lowerRight == null)) |
|
998 |
{ |
|
999 |
// This is used primarily for GTK L&F, which needs to |
|
1000 |
// extend the horizontal scrollbar to fill the lower |
|
1001 |
// corner near the row header. Note that we skip |
|
1002 |
// this step (and use the default behavior) if the |
|
1003 |
// user has set a custom corner component. |
|
1004 |
if (leftToRight) { |
|
1005 |
hsbR.x = rowHeadR.x; |
|
1006 |
} |
|
1007 |
hsbR.width += rowHeadR.width; |
|
1008 |
} |
|
1009 |
} |
|
1010 |
hsb.setVisible(true); |
|
1011 |
hsb.setBounds(hsbR); |
|
1012 |
} |
|
1013 |
else { |
|
1014 |
hsb.setVisible(false); |
|
1015 |
} |
|
1016 |
} |
|
1017 |
||
1018 |
if (lowerLeft != null) { |
|
1019 |
lowerLeft.setBounds(leftToRight ? rowHeadR.x : vsbR.x, |
|
1020 |
hsbR.y, |
|
1021 |
leftToRight ? rowHeadR.width : vsbR.width, |
|
1022 |
hsbR.height); |
|
1023 |
} |
|
1024 |
||
1025 |
if (lowerRight != null) { |
|
1026 |
lowerRight.setBounds(leftToRight ? vsbR.x : rowHeadR.x, |
|
1027 |
hsbR.y, |
|
1028 |
leftToRight ? vsbR.width : rowHeadR.width, |
|
1029 |
hsbR.height); |
|
1030 |
} |
|
1031 |
||
1032 |
if (upperLeft != null) { |
|
1033 |
upperLeft.setBounds(leftToRight ? rowHeadR.x : vsbR.x, |
|
1034 |
colHeadR.y, |
|
1035 |
leftToRight ? rowHeadR.width : vsbR.width, |
|
1036 |
colHeadR.height); |
|
1037 |
} |
|
1038 |
||
1039 |
if (upperRight != null) { |
|
1040 |
upperRight.setBounds(leftToRight ? vsbR.x : rowHeadR.x, |
|
1041 |
colHeadR.y, |
|
1042 |
leftToRight ? vsbR.width : rowHeadR.width, |
|
1043 |
colHeadR.height); |
|
1044 |
} |
|
1045 |
} |
|
1046 |
||
1047 |
/** |
|
1048 |
* Adjusts the <code>Rectangle</code> <code>available</code> based on if |
|
1049 |
* the vertical scrollbar is needed (<code>wantsVSB</code>). |
|
1050 |
* The location of the vsb is updated in <code>vsbR</code>, and |
|
1051 |
* the viewport border insets (<code>vpbInsets</code>) are used to offset |
|
1052 |
* the vsb. This is only called when <code>wantsVSB</code> has |
|
1053 |
* changed, eg you shouldn't invoke adjustForVSB(true) twice. |
|
1054 |
*/ |
|
1055 |
private void adjustForVSB(boolean wantsVSB, Rectangle available, |
|
1056 |
Rectangle vsbR, Insets vpbInsets, |
|
1057 |
boolean leftToRight) { |
|
1058 |
int oldWidth = vsbR.width; |
|
1059 |
if (wantsVSB) { |
|
1060 |
int vsbWidth = Math.max(0, Math.min(vsb.getPreferredSize().width, |
|
1061 |
available.width)); |
|
1062 |
||
1063 |
available.width -= vsbWidth; |
|
1064 |
vsbR.width = vsbWidth; |
|
1065 |
||
1066 |
if( leftToRight ) { |
|
1067 |
vsbR.x = available.x + available.width + vpbInsets.right; |
|
1068 |
} else { |
|
1069 |
vsbR.x = available.x - vpbInsets.left; |
|
1070 |
available.x += vsbWidth; |
|
1071 |
} |
|
1072 |
} |
|
1073 |
else { |
|
1074 |
available.width += oldWidth; |
|
1075 |
} |
|
1076 |
} |
|
1077 |
||
1078 |
/** |
|
1079 |
* Adjusts the <code>Rectangle</code> <code>available</code> based on if |
|
1080 |
* the horizontal scrollbar is needed (<code>wantsHSB</code>). |
|
1081 |
* The location of the hsb is updated in <code>hsbR</code>, and |
|
1082 |
* the viewport border insets (<code>vpbInsets</code>) are used to offset |
|
1083 |
* the hsb. This is only called when <code>wantsHSB</code> has |
|
1084 |
* changed, eg you shouldn't invoked adjustForHSB(true) twice. |
|
1085 |
*/ |
|
1086 |
private void adjustForHSB(boolean wantsHSB, Rectangle available, |
|
1087 |
Rectangle hsbR, Insets vpbInsets) { |
|
1088 |
int oldHeight = hsbR.height; |
|
1089 |
if (wantsHSB) { |
|
1090 |
int hsbHeight = Math.max(0, Math.min(available.height, |
|
1091 |
hsb.getPreferredSize().height)); |
|
1092 |
||
1093 |
available.height -= hsbHeight; |
|
1094 |
hsbR.y = available.y + available.height + vpbInsets.bottom; |
|
1095 |
hsbR.height = hsbHeight; |
|
1096 |
} |
|
1097 |
else { |
|
1098 |
available.height += oldHeight; |
|
1099 |
} |
|
1100 |
} |
|
1101 |
||
1102 |
||
1103 |
||
1104 |
/** |
|
1105 |
* Returns the bounds of the border around the specified scroll pane's |
|
1106 |
* viewport. |
|
1107 |
* |
|
1108 |
* @return the size and position of the viewport border |
|
1109 |
* @deprecated As of JDK version Swing1.1 |
|
1110 |
* replaced by <code>JScrollPane.getViewportBorderBounds()</code>. |
|
1111 |
*/ |
|
1112 |
@Deprecated |
|
1113 |
public Rectangle getViewportBorderBounds(JScrollPane scrollpane) { |
|
1114 |
return scrollpane.getViewportBorderBounds(); |
|
1115 |
} |
|
1116 |
||
1117 |
/** |
|
1118 |
* The UI resource version of <code>ScrollPaneLayout</code>. |
|
1119 |
*/ |
|
1120 |
public static class UIResource extends ScrollPaneLayout implements javax.swing.plaf.UIResource {} |
|
1121 |
} |