jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java
changeset 2658 43e06bc950ec
parent 2 90ce3da70b43
child 4394 92a8ec883f5d
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java	Fri Apr 17 16:28:02 2009 +0400
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java	Sat Apr 25 21:17:50 2009 +0400
@@ -112,6 +112,24 @@
      */
     private int scrollBarValue;
 
+    /**
+     * Distance between the increment button and the track. This may be a negative
+     * number. If negative, then an overlap between the button and track will occur,
+     * which is useful for shaped buttons.
+     *
+     * TODO This should be made protected in a feature release
+     */
+    private int incrGap;
+
+    /**
+     * Distance between the decrement button and the track. This may be a negative
+     * number. If negative, then an overlap between the button and track will occur,
+     * which is useful for shaped buttons.
+     *
+     * TODO This should be made protected in a feature release
+     */
+    private int decrGap;
+
     static void loadActionMap(LazyActionMap map) {
         map.put(new Actions(Actions.POSITIVE_UNIT_INCREMENT));
         map.put(new Actions(Actions.POSITIVE_BLOCK_INCREMENT));
@@ -186,6 +204,31 @@
         LookAndFeel.installProperty(scrollbar, "opaque", Boolean.TRUE);
 
         scrollBarValue = scrollbar.getValue();
+
+        incrGap = UIManager.getInt("ScrollBar.incrementButtonGap");
+        decrGap = UIManager.getInt("ScrollBar.decrementButtonGap");
+
+        // TODO this can be removed when incrGap/decrGap become protected
+        // handle scaling for sizeVarients for special case components. The
+        // key "JComponent.sizeVariant" scales for large/small/mini
+        // components are based on Apples LAF
+        String scaleKey = (String)scrollbar.getClientProperty(
+                "JComponent.sizeVariant");
+        if (scaleKey != null){
+            if ("large".equals(scaleKey)){
+                scrollBarWidth *= 1.15;
+                incrGap *= 1.15;
+                decrGap *= 1.15;
+            } else if ("small".equals(scaleKey)){
+                scrollBarWidth *= 0.857;
+                incrGap *= 0.857;
+                decrGap *= 0.714;
+            } else if ("mini".equals(scaleKey)){
+                scrollBarWidth *= 0.714;
+                incrGap *= 0.714;
+                decrGap *= 0.714;
+            }
+        }
     }
 
 
@@ -442,20 +485,23 @@
         g.setColor(trackHighlightColor);
 
         if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {
+            //paint the distance between the start of the track and top of the thumb
             int x = insets.left;
-            int y = decrButton.getY() + decrButton.getHeight();
+            int y = trackRect.y;
             int w = scrollbar.getWidth() - (insets.left + insets.right);
             int h = thumbR.y - y;
             g.fillRect(x, y, w, h);
-        }
-        else    {
+        } else {
+            //if left-to-right, fill the area between the start of the track and
+            //the left edge of the thumb. If right-to-left, fill the area between
+            //the end of the thumb and end of the track.
             int x, w;
             if (scrollbar.getComponentOrientation().isLeftToRight()) {
-                x = decrButton.getX() + decrButton.getWidth();
+               x = trackRect.x;
                 w = thumbR.x - x;
             } else {
                 x = thumbR.x + thumbR.width;
-                w = decrButton.getX() - x;
+                w = trackRect.x + trackRect.width - x;
             }
             int y = insets.top;
             int h = scrollbar.getHeight() - (insets.top + insets.bottom);
@@ -471,19 +517,23 @@
         g.setColor(trackHighlightColor);
 
         if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {
+            //fill the area between the bottom of the thumb and the end of the track.
             int x = insets.left;
             int y = thumbR.y + thumbR.height;
             int w = scrollbar.getWidth() - (insets.left + insets.right);
-            int h = incrButton.getY() - y;
+            int h = trackRect.y + trackRect.height - y;
             g.fillRect(x, y, w, h);
         }
         else {
+            //if left-to-right, fill the area between the right of the thumb and the
+            //end of the track. If right-to-left, then fill the area to the left of
+            //the thumb and the start of the track.
             int x, w;
             if (scrollbar.getComponentOrientation().isLeftToRight()) {
                 x = thumbR.x + thumbR.width;
-                w = incrButton.getX() - x;
+                w = trackRect.x + trackRect.width - x;
             } else {
-                x = incrButton.getX() + incrButton.getWidth();
+                x = trackRect.x;
                 w = thumbR.x - x;
             }
             int y = insets.top;
@@ -610,11 +660,13 @@
         int incrButtonY = sbSize.height - (sbInsets.bottom + incrButtonH);
 
         /* The thumb must fit within the height left over after we
-         * subtract the preferredSize of the buttons and the insets.
+         * subtract the preferredSize of the buttons and the insets
+         * and the gaps
          */
         int sbInsetsH = sbInsets.top + sbInsets.bottom;
         int sbButtonsH = decrButtonH + incrButtonH;
-        float trackH = sbSize.height - (sbInsetsH + sbButtonsH);
+        int gaps = decrGap + incrGap;
+        float trackH = sbSize.height - (sbInsetsH + sbButtonsH) - gaps;
 
         /* Compute the height and origin of the thumb.   The case
          * where the thumb is at the bottom edge is handled specially
@@ -632,11 +684,11 @@
         thumbH = Math.max(thumbH, getMinimumThumbSize().height);
         thumbH = Math.min(thumbH, getMaximumThumbSize().height);
 
-        int thumbY = incrButtonY - thumbH;
+        int thumbY = incrButtonY - incrGap - thumbH;
         if (value < (sb.getMaximum() - sb.getVisibleAmount())) {
             float thumbRange = trackH - thumbH;
             thumbY = (int)(0.5f + (thumbRange * ((value - min) / (range - extent))));
-            thumbY +=  decrButtonY + decrButtonH;
+            thumbY +=  decrButtonY + decrButtonH + decrGap;
         }
 
         /* If the buttons don't fit, allocate half of the available
@@ -652,8 +704,8 @@
 
         /* Update the trackRect field.
          */
-        int itrackY = decrButtonY + decrButtonH;
-        int itrackH = incrButtonY - itrackY;
+        int itrackY = decrButtonY + decrButtonH + decrGap;
+        int itrackH = incrButtonY - incrGap - itrackY;
         trackRect.setBounds(itemX, itrackY, itemW, itrackH);
 
         /* If the thumb isn't going to fit, zero it's bounds.  Otherwise
@@ -671,11 +723,11 @@
             }
         }
         else {
-            if ((thumbY + thumbH) > incrButtonY) {
-                thumbY = incrButtonY - thumbH;
+            if ((thumbY + thumbH) > incrButtonY - incrGap) {
+                thumbY = incrButtonY - incrGap - thumbH;
             }
-            if (thumbY  < (decrButtonY + decrButtonH)) {
-                thumbY = decrButtonY + decrButtonH + 1;
+            if (thumbY  < (decrButtonY + decrButtonH + decrGap)) {
+                thumbY = decrButtonY + decrButtonH + decrGap + 1;
             }
             setThumbBounds(itemX, thumbY, itemW, thumbH);
         }
@@ -710,13 +762,16 @@
         }
         int leftButtonX = sbInsets.left;
         int rightButtonX = sbSize.width - (sbInsets.right + rightButtonW);
+        int leftGap = ltr ? decrGap : incrGap;
+        int rightGap = ltr ? incrGap : decrGap;
 
         /* The thumb must fit within the width left over after we
-         * subtract the preferredSize of the buttons and the insets.
+         * subtract the preferredSize of the buttons and the insets
+         * and the gaps
          */
         int sbInsetsW = sbInsets.left + sbInsets.right;
         int sbButtonsW = leftButtonW + rightButtonW;
-        float trackW = sbSize.width - (sbInsetsW + sbButtonsW);
+        float trackW = sbSize.width - (sbInsetsW + sbButtonsW) - (leftGap + rightGap);
 
         /* Compute the width and origin of the thumb.  Enforce
          * the thumbs min/max dimensions.  The case where the thumb
@@ -735,7 +790,7 @@
         thumbW = Math.max(thumbW, getMinimumThumbSize().width);
         thumbW = Math.min(thumbW, getMaximumThumbSize().width);
 
-        int thumbX = ltr ? rightButtonX - thumbW : leftButtonX + leftButtonW;
+        int thumbX = ltr ? rightButtonX - rightGap - thumbW : leftButtonX + leftButtonW + leftGap;
         if (value < (max - sb.getVisibleAmount())) {
             float thumbRange = trackW - thumbW;
             if( ltr ) {
@@ -743,7 +798,7 @@
             } else {
                 thumbX = (int)(0.5f + (thumbRange * ((max - extent - value) / (range - extent))));
             }
-            thumbX +=  leftButtonX + leftButtonW;
+            thumbX += leftButtonX + leftButtonW + leftGap;
         }
 
         /* If the buttons don't fit, allocate half of the available
@@ -752,7 +807,7 @@
         int sbAvailButtonW = (sbSize.width - sbInsetsW);
         if (sbAvailButtonW < sbButtonsW) {
             rightButtonW = leftButtonW = sbAvailButtonW / 2;
-            rightButtonX = sbSize.width - (sbInsets.right + rightButtonW);
+            rightButtonX = sbSize.width - (sbInsets.right + rightButtonW + rightGap);
         }
 
         (ltr ? decrButton : incrButton).setBounds(leftButtonX, itemY, leftButtonW, itemH);
@@ -760,8 +815,8 @@
 
         /* Update the trackRect field.
          */
-        int itrackX = leftButtonX + leftButtonW;
-        int itrackW = rightButtonX - itrackX;
+        int itrackX = leftButtonX + leftButtonW + leftGap;
+        int itrackW = rightButtonX - rightGap - itrackX;
         trackRect.setBounds(itrackX, itemY, itrackW, itemH);
 
         /* Make sure the thumb fits between the buttons.  Note
@@ -778,11 +833,11 @@
             }
         }
         else {
-            if (thumbX + thumbW > rightButtonX) {
-                thumbX = rightButtonX - thumbW;
+            if (thumbX + thumbW > rightButtonX - rightGap) {
+                thumbX = rightButtonX - rightGap - thumbW;
             }
-            if (thumbX  < leftButtonX + leftButtonW) {
-                thumbX = leftButtonX + leftButtonW + 1;
+            if (thumbX  < leftButtonX + leftButtonW + leftGap) {
+                thumbX = leftButtonX + leftButtonW + leftGap + 1;
             }
             setThumbBounds(thumbX, itemY, thumbW, itemH);
         }
@@ -1151,20 +1206,15 @@
             int thumbMin, thumbMax, thumbPos;
 
             if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {
-                thumbMin = decrButton.getY() + decrButton.getHeight();
-                thumbMax = incrButton.getY() - thumbR.height;
+                thumbMin = trackRect.y;
+                thumbMax = trackRect.y + trackRect.height - thumbR.height;
                 thumbPos = Math.min(thumbMax, Math.max(thumbMin, (e.getY() - offset)));
                 setThumbBounds(thumbR.x, thumbPos, thumbR.width, thumbR.height);
                 trackLength = getTrackBounds().height;
             }
             else {
-                if (scrollbar.getComponentOrientation().isLeftToRight()) {
-                    thumbMin = decrButton.getX() + decrButton.getWidth();
-                    thumbMax = incrButton.getX() - thumbR.width;
-                } else {
-                    thumbMin = incrButton.getX() + incrButton.getWidth();
-                    thumbMax = decrButton.getX() - thumbR.width;
-                }
+                thumbMin = trackRect.x;
+                thumbMax = trackRect.x + trackRect.width - thumbR.width;
                 thumbPos = Math.min(thumbMax, Math.max(thumbMin, (e.getX() - offset)));
                 setThumbBounds(thumbPos, thumbR.y, thumbR.width, thumbR.height);
                 trackLength = getTrackBounds().width;