001: /*
002: * @(#)FlatScrollPaneLayout.java 12/13/2006
003: *
004: * Copyright 2002 - 2006 JIDE Software Inc. All rights reserved.
005: */
006:
007: package com.jidesoft.swing;
008:
009: import javax.swing.*;
010: import javax.swing.border.Border;
011: import java.awt.*;
012:
013: /**
014: * The layout manager used by <code>SimpleScrollPaneLayout</code>.
015: */
016: class SimpleScrollPaneLayout extends ScrollPaneLayout {
017: protected AbstractButton _scrollUp;
018: protected AbstractButton _scrollDown;
019: protected AbstractButton _scrollLeft;
020: protected AbstractButton _scrollRight;
021:
022: @Override
023: public void syncWithScrollPane(JScrollPane sp) {
024: super .syncWithScrollPane(sp);
025: if (sp instanceof SimpleScrollPane) {
026: _scrollUp = ((SimpleScrollPane) sp).getScrollUpButton();
027: _scrollDown = ((SimpleScrollPane) sp).getScrollDownButton();
028: _scrollLeft = ((SimpleScrollPane) sp).getScrollLeftButton();
029: _scrollRight = ((SimpleScrollPane) sp)
030: .getScrollRightButton();
031: }
032: }
033:
034: @Override
035: public void addLayoutComponent(String s, Component c) {
036: if (SimpleScrollPane.SCROLL_UP_BUTTON.equals(s)) {
037: _scrollUp = (AbstractButton) addSingletonComponent(
038: _scrollUp, c);
039: } else if (SimpleScrollPane.SCROLL_DOWN_BUTTON.equals(s)) {
040: _scrollDown = (AbstractButton) addSingletonComponent(
041: _scrollDown, c);
042: } else if (SimpleScrollPane.SCROLL_LEFT_BUTTON.equals(s)) {
043: _scrollLeft = (AbstractButton) addSingletonComponent(
044: _scrollLeft, c);
045: } else if (SimpleScrollPane.SCROLL_RIGHT_BUTTON.equals(s)) {
046: _scrollRight = (AbstractButton) addSingletonComponent(
047: _scrollRight, c);
048: } else {
049: super .addLayoutComponent(s, c);
050: }
051: }
052:
053: @Override
054: public void removeLayoutComponent(Component c) {
055: if (c == _scrollUp) {
056: _scrollUp = null;
057: } else if (c == _scrollDown) {
058: _scrollDown = null;
059: } else if (c == _scrollLeft) {
060: _scrollLeft = null;
061: } else if (c == _scrollRight) {
062: _scrollRight = null;
063: } else {
064: super .removeLayoutComponent(c);
065: }
066: }
067:
068: /**
069: * The preferred size of a <code>ScrollPane</code> is the size of the insets,
070: * plus the preferred size of the viewport, plus the preferred size of
071: * the visible headers, plus the preferred size of the scrollbars
072: * that will appear given the current view and the current
073: * scrollbar displayPolicies.
074: * <p>Note that the rowHeader is calculated as part of the preferred width
075: * and the colHeader is calculated as part of the preferred size.
076: *
077: * @param parent the <code>Container</code> that will be laid out
078: * @return a <code>Dimension</code> object specifying the preferred size of the
079: * viewport and any scrollbars
080: * @see javax.swing.ViewportLayout
081: * @see java.awt.LayoutManager
082: */
083: @Override
084: public Dimension preferredLayoutSize(Container parent) {
085: /* Sync the (now obsolete) policy fields with the
086: * JScrollPane.
087: */
088: JScrollPane scrollPane = (JScrollPane) parent;
089: vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
090: hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
091:
092: Insets insets = parent.getInsets();
093: int prefWidth = insets.left + insets.right;
094: int prefHeight = insets.top + insets.bottom;
095:
096: /* Note that viewport.getViewSize() is equivalent to
097: * viewport.getView().getPreferredSize() modulo a null
098: * view or a view whose size was explicitly set.
099: */
100:
101: Dimension extentSize = null;
102: Dimension viewSize = null;
103: Component view = null;
104:
105: if (viewport != null) {
106: extentSize = viewport.getPreferredSize();
107: viewSize = viewport.getViewSize();
108: view = viewport.getView();
109: }
110:
111: /* If there's a viewport add its preferredSize.
112: */
113:
114: if (extentSize != null) {
115: prefWidth += extentSize.width;
116: prefHeight += extentSize.height;
117: }
118:
119: /* If there's a JScrollPane.viewportBorder, add its insets.
120: */
121:
122: Border viewportBorder = scrollPane.getViewportBorder();
123: if (viewportBorder != null) {
124: Insets vpbInsets = viewportBorder.getBorderInsets(parent);
125: prefWidth += vpbInsets.left + vpbInsets.right;
126: prefHeight += vpbInsets.top + vpbInsets.bottom;
127: }
128:
129: /* If a scrollbar is going to appear, factor its preferred size in.
130: * If the scrollbars policy is AS_NEEDED, this can be a little
131: * tricky:
132: *
133: * - If the view is a Scrollable then scrollableTracksViewportWidth
134: * and scrollableTracksViewportHeight can be used to effectively
135: * disable scrolling (if they're true) in their respective dimensions.
136: *
137: * - Assuming that a scrollbar hasn't been disabled by the
138: * previous constraint, we need to decide if the scrollbar is going
139: * to appear to correctly compute the JScrollPanes preferred size.
140: * To do this we compare the preferredSize of the viewport (the
141: * extentSize) to the preferredSize of the view. Although we're
142: * not responsible for laying out the view we'll assume that the
143: * JViewport will always give it its preferredSize.
144: */
145:
146: if (_scrollUp != null && _scrollDown != null
147: && vsbPolicy != VERTICAL_SCROLLBAR_NEVER) {
148: if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
149: prefHeight += _scrollUp.isVisible() ? _scrollUp
150: .getPreferredSize().height : 0;
151: prefHeight += _scrollDown.isVisible() ? _scrollDown
152: .getPreferredSize().height : 0;
153: } else if ((viewSize != null) && (extentSize != null)) {
154: boolean canScroll = true;
155: if (view instanceof Scrollable) {
156: canScroll = !((Scrollable) view)
157: .getScrollableTracksViewportHeight();
158: }
159: if (canScroll && (viewSize.height > extentSize.height)) {
160: prefHeight += _scrollUp.isVisible() ? _scrollUp
161: .getPreferredSize().height : 0;
162: prefHeight += _scrollDown.isVisible() ? _scrollDown
163: .getPreferredSize().height : 0;
164: }
165: }
166: }
167:
168: if (_scrollLeft != null && _scrollRight != null
169: && hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER) {
170: if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) {
171: prefWidth += _scrollLeft.isVisible() ? _scrollLeft
172: .getPreferredSize().width : 0;
173: prefWidth += _scrollRight.isVisible() ? _scrollRight
174: .getPreferredSize().width : 0;
175: } else if ((viewSize != null) && (extentSize != null)) {
176: boolean canScroll = true;
177: if (view instanceof Scrollable) {
178: canScroll = !((Scrollable) view)
179: .getScrollableTracksViewportWidth();
180: }
181: if (canScroll && (viewSize.width > extentSize.width)) {
182: prefWidth += _scrollLeft.isVisible() ? _scrollLeft
183: .getPreferredSize().width : 0;
184: prefWidth += _scrollRight.isVisible() ? _scrollRight
185: .getPreferredSize().width
186: : 0;
187: }
188: }
189: }
190:
191: return new Dimension(prefWidth, prefHeight);
192: }
193:
194: /**
195: * The minimum size of a <code>ScrollPane</code> is the size of the insets
196: * plus minimum size of the viewport, plus the scrollpane's
197: * viewportBorder insets, plus the minimum size
198: * of the visible headers, plus the minimum size of the
199: * scrollbars whose displayPolicy isn't NEVER.
200: *
201: * @param parent the <code>Container</code> that will be laid out
202: * @return a <code>Dimension</code> object specifying the minimum size
203: */
204: @Override
205: public Dimension minimumLayoutSize(Container parent) {
206: /* Sync the (now obsolete) policy fields with the
207: * JScrollPane.
208: */
209: JScrollPane scrollPane = (JScrollPane) parent;
210: vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
211: hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
212:
213: Insets insets = parent.getInsets();
214: int minWidth = insets.left + insets.right;
215: int minHeight = insets.top + insets.bottom;
216:
217: /* If there's a viewport add its minimumSize.
218: */
219:
220: if (viewport != null) {
221: Dimension size = viewport.getMinimumSize();
222: minWidth += size.width;
223: minHeight += size.height;
224: }
225:
226: /* If there's a JScrollPane.viewportBorder, add its insets.
227: */
228:
229: Border viewportBorder = scrollPane.getViewportBorder();
230: if (viewportBorder != null) {
231: Insets vpbInsets = viewportBorder.getBorderInsets(parent);
232: minWidth += vpbInsets.left + vpbInsets.right;
233: minHeight += vpbInsets.top + vpbInsets.bottom;
234: }
235:
236: /* If a scrollbar might appear, factor its minimum
237: * size in.
238: */
239:
240: if (_scrollUp != null && _scrollDown != null
241: && vsbPolicy != VERTICAL_SCROLLBAR_NEVER) {
242: Dimension size = new Dimension(Math.max(_scrollUp
243: .getMinimumSize().width, _scrollDown
244: .getMinimumSize().width), 0);
245: size.height += _scrollUp.isVisible() ? _scrollUp
246: .getMinimumSize().height : 0;
247: size.height += _scrollDown.isVisible() ? _scrollDown
248: .getMinimumSize().height : 0;
249: minHeight += size.height;
250: minWidth = Math.max(minWidth, size.width);
251: }
252:
253: if (_scrollLeft != null && _scrollLeft != null
254: && hsbPolicy != HORIZONTAL_SCROLLBAR_NEVER) {
255: Dimension size = new Dimension(0, Math.max(_scrollLeft
256: .getMinimumSize().height, _scrollRight
257: .getMinimumSize().height));
258: size.width += _scrollLeft.isVisible() ? _scrollLeft
259: .getMinimumSize().width : 0;
260: size.width += _scrollRight.isVisible() ? _scrollRight
261: .getMinimumSize().width : 0;
262: minWidth += size.width;
263: minHeight = Math.max(minHeight, size.height);
264: }
265:
266: return new Dimension(minWidth, minHeight);
267: }
268:
269: /**
270: * Lays out the scrollpane. The positioning of components depends on
271: * the following constraints:
272: * <ul>
273: * <li> The row header, if present and visible, gets its preferred
274: * width and the viewport's height.
275: * <p/>
276: * <li> The column header, if present and visible, gets its preferred
277: * height and the viewport's width.
278: * <p/>
279: * <li> If a vertical scrollbar is needed, i.e. if the viewport's extent
280: * height is smaller than its view height or if the <code>displayPolicy</code>
281: * is ALWAYS, it's treated like the row header with respect to its
282: * dimensions and is made visible.
283: * <p/>
284: * <li> If a horizontal scrollbar is needed, it is treated like the
285: * column header (see the paragraph above regarding the vertical scrollbar).
286: * <p/>
287: * <li> If the scrollpane has a non-<code>null</code>
288: * <code>viewportBorder</code>, then space is allocated for that.
289: * <p/>
290: * <li> The viewport gets the space available after accounting for
291: * the previous constraints.
292: * <p/>
293: * <li> The corner components, if provided, are aligned with the
294: * ends of the scrollbars and headers. If there is a vertical
295: * scrollbar, the right corners appear; if there is a horizontal
296: * scrollbar, the lower corners appear; a row header gets left
297: * corners, and a column header gets upper corners.
298: * </ul>
299: *
300: * @param parent the <code>Container</code> to lay out
301: */
302: @Override
303: public void layoutContainer(Container parent) {
304: /* Sync the (now obsolete) policy fields with the
305: * JScrollPane.
306: */
307: JScrollPane scrollPane = (JScrollPane) parent;
308: vsbPolicy = scrollPane.getVerticalScrollBarPolicy();
309: hsbPolicy = scrollPane.getHorizontalScrollBarPolicy();
310:
311: Rectangle availR = scrollPane.getBounds();
312: availR.x = availR.y = 0;
313:
314: Insets insets = parent.getInsets();
315: availR.x = insets.left;
316: availR.y = insets.top;
317: availR.width -= insets.left + insets.right;
318: availR.height -= insets.top + insets.bottom;
319:
320: /* If there's a JScrollPane.viewportBorder, remove the
321: * space it occupies for availR.
322: */
323:
324: Border viewportBorder = scrollPane.getViewportBorder();
325: Insets vpbInsets;
326: if (viewportBorder != null) {
327: vpbInsets = viewportBorder.getBorderInsets(parent);
328: availR.x += vpbInsets.left;
329: availR.y += vpbInsets.top;
330: availR.width -= vpbInsets.left + vpbInsets.right;
331: availR.height -= vpbInsets.top + vpbInsets.bottom;
332: } else {
333: vpbInsets = new Insets(0, 0, 0, 0);
334: }
335:
336: /* At this point availR is the space available for the viewport
337: * and scrollbars. rowHeadR is correct except for its height and y
338: * and colHeadR is correct except for its width and x. Once we're
339: * through computing the dimensions of these three parts we can
340: * go back and set the dimensions of rowHeadR.height, rowHeadR.y,
341: * colHeadR.width, colHeadR.x and the bounds for the corners.
342: *
343: * We'll decide about putting up scrollbars by comparing the
344: * viewport views preferred size with the viewports extent
345: * size (generally just its size). Using the preferredSize is
346: * reasonable because layout proceeds top down - so we expect
347: * the viewport to be laid out next. And we assume that the
348: * viewports layout manager will give the view it's preferred
349: * size. One exception to this is when the view implements
350: * Scrollable and Scrollable.getViewTracksViewport{Width,Height}
351: * methods return true. If the view is tracking the viewports
352: * width we don't bother with a horizontal scrollbar, similarly
353: * if view.getViewTracksViewport(Height) is true we don't bother
354: * with a vertical scrollbar.
355: */
356:
357: Component view = (viewport != null) ? viewport.getView() : null;
358: Dimension viewPrefSize = (view != null) ? view
359: .getPreferredSize() : new Dimension(0, 0);
360:
361: Dimension extentSize = (viewport != null) ? viewport
362: .toViewCoordinates(availR.getSize()) : new Dimension(0,
363: 0);
364:
365: boolean viewTracksViewportWidth = false;
366: boolean viewTracksViewportHeight = false;
367: boolean isEmpty = (availR.width < 0 || availR.height < 0);
368: Scrollable sv;
369: // Don't bother checking the Scrollable methods if there is no room
370: // for the viewport, we aren't going to show any scrollbars in this
371: // case anyway.
372: if (!isEmpty && view instanceof Scrollable) {
373: sv = (Scrollable) view;
374: viewTracksViewportWidth = sv
375: .getScrollableTracksViewportWidth();
376: viewTracksViewportHeight = sv
377: .getScrollableTracksViewportHeight();
378: } else {
379: sv = null;
380: }
381:
382: /* If there's a vertical scrollbar and we need one, allocate
383: * space for it (we'll make it visible later). A vertical
384: * scrollbar is considered to be fixed width, arbitrary height.
385: */
386:
387: Rectangle scrollUpR = new Rectangle(0, 0, 0, _scrollUp
388: .getPreferredSize().height);
389: Rectangle scrollDownR = new Rectangle(0, 0, 0, _scrollDown
390: .getPreferredSize().height);
391:
392: boolean vsbNeeded;
393: if (isEmpty) {
394: vsbNeeded = false;
395: } else if (vsbPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
396: vsbNeeded = true;
397: } else if (vsbPolicy == VERTICAL_SCROLLBAR_NEVER) {
398: vsbNeeded = false;
399: } else { // vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED
400: if (!_scrollUp.isEnabled()) {
401: scrollUpR.height = 0;
402: }
403: if (!_scrollDown.isEnabled()) {
404: scrollDownR.height = 0;
405: }
406: vsbNeeded = !viewTracksViewportHeight
407: && (viewPrefSize.height > extentSize.height);
408: }
409:
410: if (_scrollUp != null && _scrollDown != null && vsbNeeded) {
411: adjustForScrollUpAndDown(true, availR, scrollUpR,
412: scrollDownR, vpbInsets);
413: extentSize = viewport.toViewCoordinates(availR.getSize());
414: }
415:
416: /* If there's a horizontal scrollbar and we need one, allocate
417: * space for it (we'll make it visible later). A horizontal
418: * scrollbar is considered to be fixed height, arbitrary width.
419: */
420:
421: Rectangle scrollLeftR = new Rectangle(0, 0, _scrollLeft
422: .getPreferredSize().width, 0);
423: Rectangle scrollRightR = new Rectangle(0, 0, _scrollRight
424: .getPreferredSize().width, 0);
425: boolean hsbNeeded;
426: if (isEmpty) {
427: hsbNeeded = false;
428: } else if (hsbPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) {
429: hsbNeeded = true;
430: } else if (hsbPolicy == HORIZONTAL_SCROLLBAR_NEVER) {
431: hsbNeeded = false;
432: } else { // hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED
433: if (!_scrollLeft.isEnabled()) {
434: scrollLeftR.width = 0;
435: }
436: if (!_scrollRight.isEnabled()) {
437: scrollRightR.width = 0;
438: }
439: hsbNeeded = !viewTracksViewportWidth
440: && (viewPrefSize.width > extentSize.width);
441: }
442:
443: if ((hsb != null) && hsbNeeded) {
444: adjustForScrollLeftAndRight(true, availR, scrollLeftR,
445: scrollRightR, vpbInsets);
446:
447: /* If we added the horizontal scrollbar then we've implicitly
448: * reduced the vertical space available to the viewport.
449: * As a consequence we may have to add the vertical scrollbar,
450: * if that hasn't been done so already. Of course we
451: * don't bother with any of this if the vsbPolicy is NEVER.
452: */
453: if (_scrollUp != null && _scrollDown != null && !vsbNeeded
454: && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
455:
456: extentSize = viewport.toViewCoordinates(availR
457: .getSize());
458: vsbNeeded = viewPrefSize.height > extentSize.height;
459:
460: if (vsbNeeded) {
461: adjustForScrollUpAndDown(true, availR, scrollUpR,
462: scrollDownR, vpbInsets);
463: }
464: }
465: }
466:
467: /* Set the size of the viewport first, and then recheck the Scrollable
468: * methods. Some components base their return values for the Scrollable
469: * methods on the size of the Viewport, so that if we don't
470: * ask after resetting the bounds we may have gotten the wrong
471: * answer.
472: */
473:
474: if (viewport != null) {
475: viewport.setBounds(availR);
476:
477: if (sv != null) {
478: extentSize = viewport.toViewCoordinates(availR
479: .getSize());
480:
481: boolean oldHSBNeeded = hsbNeeded;
482: boolean oldVSBNeeded = vsbNeeded;
483: viewTracksViewportWidth = sv
484: .getScrollableTracksViewportWidth();
485: viewTracksViewportHeight = sv
486: .getScrollableTracksViewportHeight();
487: if (vsb != null
488: && vsbPolicy == VERTICAL_SCROLLBAR_AS_NEEDED) {
489: boolean newVSBNeeded = !viewTracksViewportHeight
490: && (viewPrefSize.height > extentSize.height);
491: if (newVSBNeeded != vsbNeeded) {
492: vsbNeeded = newVSBNeeded;
493: adjustForScrollUpAndDown(vsbNeeded, availR,
494: scrollUpR, scrollDownR, vpbInsets);
495: extentSize = viewport.toViewCoordinates(availR
496: .getSize());
497: }
498: }
499: if (hsb != null
500: && hsbPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED) {
501: boolean newHSBbNeeded = !viewTracksViewportWidth
502: && (viewPrefSize.width > extentSize.width);
503: if (newHSBbNeeded != hsbNeeded) {
504: hsbNeeded = newHSBbNeeded;
505: adjustForScrollLeftAndRight(hsbNeeded, availR,
506: scrollLeftR, scrollRightR, vpbInsets);
507: if ((vsb != null)
508: && !vsbNeeded
509: && (vsbPolicy != VERTICAL_SCROLLBAR_NEVER)) {
510:
511: extentSize = viewport
512: .toViewCoordinates(availR.getSize());
513: vsbNeeded = viewPrefSize.height > extentSize.height;
514:
515: if (vsbNeeded) {
516: adjustForScrollUpAndDown(true, availR,
517: scrollUpR, scrollDownR,
518: vpbInsets);
519: }
520: }
521: }
522: }
523: if (oldHSBNeeded != hsbNeeded
524: || oldVSBNeeded != vsbNeeded) {
525: viewport.setBounds(availR);
526: // You could argue that we should recheck the
527: // Scrollable methods again until they stop changing,
528: // but they might never stop changing, so we stop here
529: // and don't do any additional checks.
530: }
531: }
532: }
533:
534: /* We now have the final size of the viewport: availR.
535: * Now fixup the header and scrollbar widths/heights.
536: */
537: // TODO
538: if (_scrollUp != null && _scrollDown != null) {
539: if (vsbNeeded) {
540: _scrollUp.setVisible(true);
541: _scrollDown.setVisible(true);
542: _scrollUp.setBounds(scrollUpR);
543: _scrollDown.setBounds(scrollDownR);
544: } else {
545: _scrollUp.setVisible(false);
546: _scrollDown.setVisible(false);
547: _scrollUp.setBounds(scrollUpR.x, scrollUpR.y, 0, 0);
548: _scrollDown.setBounds(scrollDownR.x, scrollDownR.y, 0,
549: 0);
550: }
551: }
552:
553: if (_scrollLeft != null && _scrollRight != null) {
554: if (hsbNeeded) {
555: _scrollLeft.setVisible(true);
556: _scrollRight.setVisible(true);
557: _scrollLeft.setBounds(scrollLeftR);
558: _scrollRight.setBounds(scrollRightR);
559: } else {
560: _scrollLeft.setVisible(false);
561: _scrollRight.setVisible(false);
562: _scrollLeft.setBounds(scrollLeftR.x, scrollLeftR.y, 0,
563: 0);
564: _scrollRight.setBounds(scrollRightR.x, scrollRightR.y,
565: 0, 0);
566: }
567: }
568: }
569:
570: /**
571: * Adjusts the <code>Rectangle</code> <code>available</code> based on if
572: * the vertical scrollbar is needed (<code>wantsVSB</code>).
573: * The location of the vsb is updated in <code>vsbR</code>, and
574: * the viewport border insets (<code>vpbInsets</code>) are used to offset
575: * the vsb. This is only called when <code>wantsVSB</code> has
576: * changed, eg you shouldn't invoke adjustForVSB(true) twice.
577: */
578: private void adjustForScrollUpAndDown(boolean wantsVSB,
579: Rectangle available, Rectangle upR, Rectangle downR,
580: Insets vpbInsets) {
581: if (wantsVSB) {
582: int buttonWidth = Math.max(0, Math.max(available.width
583: + vpbInsets.left + vpbInsets.right, Math.max(
584: _scrollUp.getPreferredSize().width, _scrollDown
585: .getPreferredSize().width)));
586:
587: available.height -= upR.height;
588: available.height -= downR.height;
589:
590: upR.width = buttonWidth;
591: downR.width = buttonWidth;
592:
593: upR.x = available.x - vpbInsets.left;
594: downR.x = available.x - vpbInsets.left;
595:
596: upR.y = available.y - vpbInsets.top;
597: available.y += upR.height;
598: downR.y = available.y + available.height + vpbInsets.bottom;
599:
600: }
601: }
602:
603: /**
604: * Adjusts the <code>Rectangle</code> <code>available</code> based on if
605: * the horizontal scrollbar is needed (<code>wantsHSB</code>).
606: * The location of the hsb is updated in <code>hsbR</code>, and
607: * the viewport border insets (<code>vpbInsets</code>) are used to offset
608: * the hsb. This is only called when <code>wantsHSB</code> has
609: * changed, eg you shouldn't invoked adjustForHSB(true) twice.
610: */
611: private void adjustForScrollLeftAndRight(boolean wantsHSB,
612: Rectangle available, Rectangle leftR, Rectangle rightR,
613: Insets vpbInsets) {
614: if (wantsHSB) {
615: int buttonHeight = Math.max(0, Math.max(available.height
616: + vpbInsets.top + vpbInsets.bottom, Math.max(
617: _scrollLeft.getPreferredSize().height, _scrollRight
618: .getPreferredSize().height)));
619:
620: available.width -= leftR.width;
621: available.width -= rightR.width;
622:
623: leftR.height = buttonHeight;
624: rightR.height = buttonHeight;
625:
626: leftR.y = available.y - vpbInsets.top;
627: rightR.y = available.y - vpbInsets.top;
628:
629: leftR.x = available.x - vpbInsets.left;
630: available.x += leftR.width;
631: rightR.x = available.x + available.width + vpbInsets.right;
632:
633: }
634: }
635:
636: /**
637: * The UI resource version of <code>ScrollPaneLayout</code>.
638: */
639: static class UIResource extends SimpleScrollPaneLayout implements
640: javax.swing.plaf.UIResource {
641: }
642: }
|