2
* Copyright (c) 2005-2010 Laf-Widget Kirill Grouchnikov. All Rights Reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
7
* o Redistributions of source code must retain the above copyright notice,
8
* this list of conditions and the following disclaimer.
10
* o Redistributions in binary form must reproduce the above copyright notice,
11
* this list of conditions and the following disclaimer in the documentation
12
* and/or other materials provided with the distribution.
14
* o Neither the name of Laf-Widget Kirill Grouchnikov nor the names of
15
* its contributors may be used to endorse or promote products derived
16
* from this software without specific prior written permission.
18
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
package org.pushingpixels.lafwidget.scroll;
33
import javax.swing.border.Border;
37
* A hideous hack to allow the display of the selector's button even when only
38
* one scrollBar is visible.
40
* Contributed by the original author under BSD license. Also appears in the <a
41
* href="https://jdnc-incubator.dev.java.net">JDNC Incubator</a>.
43
* @author weebib (Pierre LE LANNIC)
45
public class TweakedScrollPaneLayout extends ScrollPaneLayout {
46
private void superlayoutContainer(Container parent) {
47
JScrollPane scrollPane = (JScrollPane) parent;
48
vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
49
hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
51
Rectangle availR = scrollPane.getBounds();
52
Insets insets = parent.getInsets();
53
availR.x = insets.left;
54
availR.y = insets.top;
55
availR.width -= insets.left + insets.right;
56
availR.height -= insets.top + insets.bottom;
58
boolean leftToRight = scrollPane.getComponentOrientation()
61
Rectangle colHeadR = new Rectangle(0, availR.y, 0, 0);
63
if ((colHead != null) && (colHead.isVisible())) {
64
int colHeadHeight = Math.min(availR.height, colHead
65
.getPreferredSize().height);
66
colHeadR.height = colHeadHeight;
67
availR.y += colHeadHeight;
68
availR.height -= colHeadHeight;
71
Rectangle rowHeadR = new Rectangle(0, 0, 0, 0);
73
if ((rowHead != null) && (rowHead.isVisible())) {
74
int rowHeadWidth = Math.min(availR.width, rowHead
75
.getPreferredSize().width);
76
rowHeadR.width = rowHeadWidth;
77
availR.width -= rowHeadWidth;
79
rowHeadR.x = availR.x;
80
availR.x += rowHeadWidth;
82
rowHeadR.x = availR.x + availR.width;
86
Border viewportBorder = scrollPane.getViewportBorder();
88
if (viewportBorder != null) {
89
vpbInsets = viewportBorder.getBorderInsets(parent);
90
availR.x += vpbInsets.left;
91
availR.y += vpbInsets.top;
92
availR.width -= vpbInsets.left + vpbInsets.right;
93
availR.height -= vpbInsets.top + vpbInsets.bottom;
95
vpbInsets = new Insets(0, 0, 0, 0);
98
Component view = (viewport != null) ? viewport.getView() : null;
99
Dimension viewPrefSize = (view != null) ? view.getPreferredSize()
100
: new Dimension(0, 0);
102
Dimension extentSize = (viewport != null) ? viewport
103
.toViewCoordinates(availR.getSize()) : new Dimension(0, 0);
105
boolean viewTracksViewportWidth = false;
106
boolean viewTracksViewportHeight = false;
107
boolean isEmpty = (availR.width < 0 || availR.height < 0);
109
if (!isEmpty && view instanceof Scrollable) {
110
sv = (Scrollable) view;
111
viewTracksViewportWidth = sv.getScrollableTracksViewportWidth();
112
viewTracksViewportHeight = sv.getScrollableTracksViewportHeight();
117
Rectangle vsbR = new Rectangle(0, availR.y - vpbInsets.top, 0, 0);
122
} else if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
124
} else if (vsbPolicy == VERTICAL_SCROLLBAR_NEVER) {
126
} else { // vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED
127
vsbNeeded = !viewTracksViewportHeight
128
&& (viewPrefSize.height > extentSize.height);
131
if ((vsb != null) && vsbNeeded) {
132
adjustForVSB(true, availR, vsbR, vpbInsets, leftToRight);
133
extentSize = viewport.toViewCoordinates(availR.getSize());
136
Rectangle hsbR = new Rectangle(availR.x - vpbInsets.left, 0, 0, 0);
140
} else if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) {
142
} else if (hsbPolicy == HORIZONTAL_SCROLLBAR_NEVER) {
144
} else { // hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED
145
hsbNeeded = !viewTracksViewportWidth
146
&& (viewPrefSize.width > extentSize.width);
148
if ((hsb != null) && hsbNeeded) {
149
adjustForHSB(true, availR, hsbR, vpbInsets);
150
if ((vsb != null) && !vsbNeeded
151
&& (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
152
extentSize = viewport.toViewCoordinates(availR.getSize());
153
vsbNeeded = viewPrefSize.height > extentSize.height;
155
adjustForVSB(true, availR, vsbR, vpbInsets, leftToRight);
157
// Hack to correct Bug 6411225
158
// I don't actually measure the consequences of this bug
162
hsbR.x += vsbR.width;
170
if (viewport != null) {
171
viewport.setBounds(availR);
174
extentSize = viewport.toViewCoordinates(availR.getSize());
176
boolean oldHSBNeeded = hsbNeeded;
177
boolean oldVSBNeeded = vsbNeeded;
178
viewTracksViewportWidth = sv.getScrollableTracksViewportWidth();
179
viewTracksViewportHeight = sv
180
.getScrollableTracksViewportHeight();
181
if (vsb != null && vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED) {
182
boolean newVSBNeeded = !viewTracksViewportHeight
183
&& (viewPrefSize.height > extentSize.height);
184
if (newVSBNeeded != vsbNeeded) {
185
vsbNeeded = newVSBNeeded;
186
adjustForVSB(vsbNeeded, availR, vsbR, vpbInsets,
188
extentSize = viewport.toViewCoordinates(availR
192
if (hsb != null && hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED) {
193
boolean newHSBbNeeded = !viewTracksViewportWidth
194
&& (viewPrefSize.width > extentSize.width);
195
if (newHSBbNeeded != hsbNeeded) {
196
hsbNeeded = newHSBbNeeded;
197
adjustForHSB(hsbNeeded, availR, hsbR, vpbInsets);
198
if ((vsb != null) && !vsbNeeded
199
&& (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
200
extentSize = viewport.toViewCoordinates(availR
202
vsbNeeded = viewPrefSize.height > extentSize.height;
204
adjustForVSB(true, availR, vsbR, vpbInsets,
210
if (oldHSBNeeded != hsbNeeded || oldVSBNeeded != vsbNeeded) {
211
viewport.setBounds(availR);
215
vsbR.height = availR.height + vpbInsets.top + vpbInsets.bottom;
216
hsbR.width = availR.width + vpbInsets.left + vpbInsets.right;
217
rowHeadR.height = availR.height + vpbInsets.top + vpbInsets.bottom;
218
rowHeadR.y = availR.y - vpbInsets.top;
219
colHeadR.width = availR.width + vpbInsets.left + vpbInsets.right;
220
colHeadR.x = availR.x - vpbInsets.left;
222
if (rowHead != null) {
223
rowHead.setBounds(rowHeadR);
226
if (colHead != null) {
227
colHead.setBounds(colHeadR);
232
vsb.setVisible(true);
235
vsb.setVisible(false);
241
hsb.setVisible(true);
244
hsb.setVisible(false);
248
// bug 6411225 ????????
250
if (lowerLeft != null) {
251
lowerLeft.setBounds(leftToRight ? rowHeadR.x : vsbR.x, hsbR.y,
252
leftToRight ? rowHeadR.width : vsbR.width, hsbR.height);
255
if (lowerRight != null) {
256
lowerRight.setBounds(leftToRight ? vsbR.x : rowHeadR.x, hsbR.y,
257
leftToRight ? vsbR.width : rowHeadR.width, hsbR.height);
260
if (upperLeft != null) {
261
upperLeft.setBounds(leftToRight ? rowHeadR.x : vsbR.x, colHeadR.y,
262
leftToRight ? rowHeadR.width : vsbR.width, colHeadR.height);
265
if (upperRight != null) {
266
upperRight.setBounds(leftToRight ? vsbR.x : rowHeadR.x, colHeadR.y,
267
leftToRight ? vsbR.width : rowHeadR.width, colHeadR.height);
271
private void adjustForVSB(boolean wantsVSB, Rectangle available,
272
Rectangle vsbR, Insets vpbInsets, boolean leftToRight) {
273
int oldWidth = vsbR.width;
275
int vsbWidth = Math.max(0, Math.min(vsb.getPreferredSize().width,
278
available.width -= vsbWidth;
279
vsbR.width = vsbWidth;
282
vsbR.x = available.x + available.width + vpbInsets.right;
284
vsbR.x = available.x - vpbInsets.left;
285
available.x += vsbWidth;
288
available.width += oldWidth;
292
private void adjustForHSB(boolean wantsHSB, Rectangle available,
293
Rectangle hsbR, Insets vpbInsets) {
294
int oldHeight = hsbR.height;
296
int hsbHeight = Math.max(0, Math.min(available.height, hsb
297
.getPreferredSize().height));
299
available.height -= hsbHeight;
300
hsbR.y = available.y + available.height + vpbInsets.bottom;
301
hsbR.height = hsbHeight;
303
available.height += oldHeight;
308
public void layoutContainer(Container parent) {
309
superlayoutContainer(parent);
310
boolean isLeftToRight = parent.getComponentOrientation()
312
if (isLeftToRight && lowerRight == null)
314
if (!isLeftToRight && lowerLeft == null)
317
boolean onlyVsb = (vsb != null) && vsb.isVisible()
318
&& ((hsb == null) || ((hsb != null) && (!hsb.isVisible())));
320
Rectangle vsbBounds = vsb.getBounds();
321
int delta = (hsb == null) ? (Integer) (UIManager
322
.get("ScrollBar.width")) : hsb
323
.getPreferredSize().height;
324
vsbBounds.height -= delta;
325
vsb.setBounds(vsbBounds);
327
lowerRight.setBounds(vsbBounds.x, vsbBounds.y
328
+ vsbBounds.height, vsbBounds.width, delta);
329
lowerRight.setVisible(true);
331
lowerLeft.setBounds(vsbBounds.x,
332
vsbBounds.y + vsbBounds.height, vsbBounds.width, delta);
333
lowerLeft.setVisible(true);
336
boolean onlyHsb = (hsb != null) && hsb.isVisible()
337
&& ((vsb == null) || ((vsb != null) && (!vsb.isVisible())));
339
Rectangle hsbBounds = hsb.getBounds();
340
int delta = (vsb == null) ? (Integer) (UIManager
341
.get("ScrollBar.width")) : vsb
342
.getPreferredSize().width;
343
hsbBounds.width -= delta;
344
if (!isLeftToRight) {
345
hsbBounds.x += delta;
347
hsb.setBounds(hsbBounds);
349
lowerRight.setBounds(hsbBounds.x + hsbBounds.width,
350
hsbBounds.y, delta, hsbBounds.height);
351
lowerRight.setVisible(true);
353
lowerLeft.setBounds(hsbBounds.x - delta, hsbBounds.y, delta,
355
lowerLeft.setVisible(true);
b'\\ No newline at end of file'