modules/controls/src/main/java/javafx/scene/control/skin/ScrollBarSkin.java

Print this page
rev 9240 : 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization

@@ -21,36 +21,50 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
 
-package com.sun.javafx.scene.control.skin;
+package javafx.scene.control.skin;
 
+import com.sun.javafx.scene.control.Properties;
+import com.sun.javafx.scene.control.behavior.BehaviorBase;
+import javafx.beans.value.ObservableValue;
 import javafx.geometry.Orientation;
 import javafx.geometry.Point2D;
 import javafx.scene.AccessibleAction;
 import javafx.scene.AccessibleAttribute;
 import javafx.scene.AccessibleRole;
+import javafx.scene.control.Accordion;
+import javafx.scene.control.Button;
+import javafx.scene.control.Control;
 import javafx.scene.control.ScrollBar;
+import javafx.scene.control.SkinBase;
 import javafx.scene.input.MouseButton;
 import javafx.scene.input.ScrollEvent;
 import javafx.scene.layout.Region;
 import javafx.scene.layout.StackPane;
 import javafx.scene.Node;
 import com.sun.javafx.util.Utils;
 import com.sun.javafx.scene.control.behavior.ScrollBarBehavior;
 
-public class ScrollBarSkin extends BehaviorSkinBase<ScrollBar, ScrollBarBehavior> {
+import java.util.function.Consumer;
+
+/**
+ * Default skin implementation for the {@link ScrollBar} control.
+ *
+ * @see ScrollBar
+ * @since 9
+ */
+public class ScrollBarSkin extends SkinBase<ScrollBar> {
 
     /***************************************************************************
      *                                                                         *
-     * UI Subcomponents                                                        *
+     * Private fields                                                          *
      *                                                                         *
      **************************************************************************/
 
-    public final static int DEFAULT_LENGTH = 100;
-    public final static int DEFAULT_WIDTH = 20;
+    private final ScrollBarBehavior behavior;
 
     private StackPane thumb;
     private StackPane trackBackground;
     private StackPane track;
     private EndButton incButton;

@@ -62,28 +76,246 @@
     private double preDragThumbPos;
     private Point2D dragStart; // in the track's coord system
 
     private double trackPos;
 
+
+
     /***************************************************************************
      *                                                                         *
      * Constructors                                                            *
      *                                                                         *
      **************************************************************************/
 
-    public ScrollBarSkin(ScrollBar scrollbar) {
-        super(scrollbar, new ScrollBarBehavior(scrollbar));
+    /**
+     * Creates a new ScrollBarSkin instance, installing the necessary child
+     * nodes into the Control {@link Control#getChildren() children} list, as
+     * well as the necessary input mappings for handling key, mouse, etc events.
+     *
+     * @param control The control that this skin should be installed onto.
+     */
+    public ScrollBarSkin(ScrollBar control) {
+        super(control);
+
+        // install default input map for the ScrollBar control
+        this.behavior = new ScrollBarBehavior(control);
+//        control.setInputMap(behavior.getInputMap());
+
         initialize();
         getSkinnable().requestLayout();
+
         // Register listeners
-        registerChangeListener(scrollbar.minProperty(), "MIN");
-        registerChangeListener(scrollbar.maxProperty(), "MAX");
-        registerChangeListener(scrollbar.valueProperty(), "VALUE");
-        registerChangeListener(scrollbar.orientationProperty(), "ORIENTATION");
-        registerChangeListener(scrollbar.visibleAmountProperty(), "VISIBLE_AMOUNT");
+        final Consumer<ObservableValue<?>> consumer = e -> {
+            positionThumb();
+            getSkinnable().requestLayout();
+        };
+        registerChangeListener(control.minProperty(), consumer);
+        registerChangeListener(control.maxProperty(), consumer);
+        registerChangeListener(control.visibleAmountProperty(), consumer);
+        registerChangeListener(control.valueProperty(), e -> positionThumb());
+        registerChangeListener(control.orientationProperty(), e -> getSkinnable().requestLayout());
+    }
+
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Public API                                                              *
+     *                                                                         *
+     **************************************************************************/
+
+    /** {@inheritDoc} */
+    @Override public void dispose() {
+        super.dispose();
+
+        if (behavior != null) {
+            behavior.dispose();
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void layoutChildren(final double x, final double y,
+                                            final double w, final double h) {
+
+        final ScrollBar s = getSkinnable();
+
+        /**
+         * Compute the percentage length of thumb as (visibleAmount/range)
+         * if max isn't greater than min then there is nothing to do here
+         */
+        double visiblePortion;
+        if (s.getMax() > s.getMin()) {
+            visiblePortion = s.getVisibleAmount()/(s.getMax() - s.getMin());
+        }
+        else {
+            visiblePortion = 1.0;
+        }
+
+        if (s.getOrientation() == Orientation.VERTICAL) {
+            if (!Properties.IS_TOUCH_SUPPORTED) {
+                double decHeight = snapSize(decButton.prefHeight(-1));
+                double incHeight = snapSize(incButton.prefHeight(-1));
+
+                decButton.resize(w, decHeight);
+                incButton.resize(w, incHeight);
+
+                trackLength = snapSize(h - (decHeight + incHeight));
+                thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
+
+                trackBackground.resizeRelocate(snapPosition(x), snapPosition(y), w, trackLength+decHeight+incHeight);
+                decButton.relocate(snapPosition(x), snapPosition(y));
+                incButton.relocate(snapPosition(x), snapPosition(y + h - incHeight));
+                track.resizeRelocate(snapPosition(x), snapPosition(y + decHeight), w, trackLength);
+                thumb.resize(snapSize(x >= 0 ? w : w + x), thumbLength); // Account for negative padding (see also RT-10719)
+                positionThumb();
+            }
+            else {
+                trackLength = snapSize(h);
+                thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
+
+                track.resizeRelocate(snapPosition(x), snapPosition(y), w, trackLength);
+                thumb.resize(snapSize(x >= 0 ? w : w + x), thumbLength); // Account for negative padding (see also RT-10719)
+                positionThumb();
+            }
+        } else {
+            if (!Properties.IS_TOUCH_SUPPORTED) {
+                double decWidth = snapSize(decButton.prefWidth(-1));
+                double incWidth = snapSize(incButton.prefWidth(-1));
+
+                decButton.resize(decWidth, h);
+                incButton.resize(incWidth, h);
+
+                trackLength = snapSize(w - (decWidth + incWidth));
+                thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
+
+                trackBackground.resizeRelocate(snapPosition(x), snapPosition(y), trackLength+decWidth+incWidth, h);
+                decButton.relocate(snapPosition(x), snapPosition(y));
+                incButton.relocate(snapPosition(x + w - incWidth), snapPosition(y));
+                track.resizeRelocate(snapPosition(x + decWidth), snapPosition(y), trackLength, h);
+                thumb.resize(thumbLength, snapSize(y >= 0 ? h : h + y)); // Account for negative padding (see also RT-10719)
+                positionThumb();
+            }
+            else {
+                trackLength = snapSize(w);
+                thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
+
+                track.resizeRelocate(snapPosition(x), snapPosition(y), trackLength, h);
+                thumb.resize(thumbLength, snapSize(y >= 0 ? h : h + y)); // Account for negative padding (see also RT-10719)
+                positionThumb();
     }
 
+            s.resize(snapSize(s.getWidth()), snapSize(s.getHeight()));
+        }
+
+        // things should be invisible only when well below minimum length
+        if (s.getOrientation() == Orientation.VERTICAL && h >= (computeMinHeight(-1, (int)y , snappedRightInset(), snappedBottomInset(), (int)x) - (y+snappedBottomInset())) ||
+                s.getOrientation() == Orientation.HORIZONTAL && w >= (computeMinWidth(-1, (int)y , snappedRightInset(), snappedBottomInset(), (int)x) - (x+snappedRightInset()))) {
+            trackBackground.setVisible(true);
+            track.setVisible(true);
+            thumb.setVisible(true);
+            if (!Properties.IS_TOUCH_SUPPORTED) {
+                incButton.setVisible(true);
+                decButton.setVisible(true);
+            }
+        }
+        else {
+            trackBackground.setVisible(false);
+            track.setVisible(false);
+            thumb.setVisible(false);
+
+            if (!Properties.IS_TOUCH_SUPPORTED) {
+                /*
+                ** once the space is big enough for one button we
+                ** can look at drawing
+                */
+                if (h >= decButton.computeMinWidth(-1)) {
+                    decButton.setVisible(true);
+                }
+                else {
+                    decButton.setVisible(false);
+                }
+                if (h >= incButton.computeMinWidth(-1)) {
+                    incButton.setVisible(true);
+                }
+                else {
+                    incButton.setVisible(false);
+                }
+            }
+        }
+    }
+
+    /*
+     * Minimum length is the length of the end buttons plus twice the
+     * minimum thumb length, which should be enough for a reasonably-sized
+     * track. Minimum breadth is determined by the breadths of the
+     * end buttons.
+     */
+    /** {@inheritDoc} */
+    @Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
+            return getBreadth();
+        } else {
+            if (!Properties.IS_TOUCH_SUPPORTED) {
+                return decButton.minWidth(-1) + incButton.minWidth(-1) + minTrackLength()+leftInset+rightInset;
+            } else {
+                return minTrackLength()+leftInset+rightInset;
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
+            if (!Properties.IS_TOUCH_SUPPORTED) {
+                return decButton.minHeight(-1) + incButton.minHeight(-1) + minTrackLength()+topInset+bottomInset;
+            } else {
+                return minTrackLength()+topInset+bottomInset;
+            }
+        } else {
+            return getBreadth();
+        }
+    }
+
+    /*
+     * Preferred size. The breadth is determined by the breadth of
+     * the end buttons. The length is a constant default length.
+     * Usually applications or other components will either set a
+     * specific length using LayoutInfo or will stretch the length
+     * of the scrollbar to fit a container.
+     */
+    /** {@inheritDoc} */
+    @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        final ScrollBar s = getSkinnable();
+        return s.getOrientation() == Orientation.VERTICAL ? getBreadth() : Properties.DEFAULT_LENGTH+leftInset+rightInset;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected double computePrefHeight(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        final ScrollBar s = getSkinnable();
+        return s.getOrientation() == Orientation.VERTICAL ? Properties.DEFAULT_LENGTH+topInset+bottomInset : getBreadth();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+        final ScrollBar s = getSkinnable();
+        return s.getOrientation() == Orientation.VERTICAL ? s.prefWidth(-1) : Double.MAX_VALUE;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+        final ScrollBar s = getSkinnable();
+        return s.getOrientation() == Orientation.VERTICAL ? Double.MAX_VALUE : s.prefHeight(-1);
+    }
+
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Private implementation                                                  *
+     *                                                                         *
+     **************************************************************************/
+
     /**
      * Initializes the ScrollBarSkin. Creates the scene and sets up all the
      * bindings for the group.
      */
     private void initialize() {

@@ -105,11 +337,11 @@
         };
         thumb.getStyleClass().setAll("thumb");
         thumb.setAccessibleRole(AccessibleRole.THUMB);
 
 
-        if (!IS_TOUCH_SUPPORTED) {
+        if (!Properties.IS_TOUCH_SUPPORTED) {
             
             incButton = new EndButton("increment-button", "increment-arrow") {
                 @Override
                 public void executeAccessibleAction(AccessibleAction action, Object... parameters) {
                     switch (action) {

@@ -124,20 +356,20 @@
             incButton.setOnMousePressed(me -> {
                 /*
                 ** if the tracklenght isn't greater than do nothing....
                 */
                 if (!thumb.isVisible() || trackLength > thumbLength) {
-                    getBehavior().incButtonPressed();
+                    behavior.incButtonPressed();
                 }
                 me.consume();
             });
             incButton.setOnMouseReleased(me -> {
                 /*
                 ** if the tracklenght isn't greater than do nothing....
                 */
                 if (!thumb.isVisible() || trackLength > thumbLength) {
-                    getBehavior().incButtonReleased();
+                    behavior.incButtonReleased();
                 }
                 me.consume();
             });
 
             decButton = new EndButton("decrement-button", "decrement-arrow") {

@@ -155,44 +387,44 @@
             decButton.setOnMousePressed(me -> {
                 /*
                 ** if the tracklenght isn't greater than do nothing....
                 */
                 if (!thumb.isVisible() || trackLength > thumbLength) {
-                    getBehavior().decButtonPressed();
+                    behavior.decButtonPressed();
                 }
                 me.consume();
             });
             decButton.setOnMouseReleased(me -> {
                 /*
                 ** if the tracklenght isn't greater than do nothing....
                 */
                 if (!thumb.isVisible() || trackLength > thumbLength) {
-                    getBehavior().decButtonReleased();
+                    behavior.decButtonReleased();
                 }
                 me.consume();
             });
         }
 
 
         track.setOnMousePressed(me -> {
             if (!thumb.isPressed() && me.getButton() == MouseButton.PRIMARY) {
                 if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
                     if (trackLength != 0) {
-                        getBehavior().trackPress(me.getY() / trackLength);
+                        behavior.trackPress(me.getY() / trackLength);
                         me.consume();
                     }
                 } else {
                     if (trackLength != 0) {
-                        getBehavior().trackPress(me.getX() / trackLength);
+                        behavior.trackPress(me.getX() / trackLength);
                         me.consume();
                     }
                 }
             }
         });
 
         track.setOnMouseReleased(me -> {
-            getBehavior().trackRelease();
+            behavior.trackRelease();
             me.consume();
         });
 
         thumb.setOnMousePressed(me -> {
             if (me.isSynthesized()) {

@@ -230,11 +462,11 @@
                     if (dragStart == null) {
                         // we're getting dragged without getting a mouse press
                         dragStart = thumb.localToParent(me.getX(), me.getY());
                     }
                     double dragPos = getSkinnable().getOrientation() == Orientation.VERTICAL ? cur.getY() - dragStart.getY(): cur.getX() - dragStart.getX();
-                    getBehavior().thumbDragged(preDragThumbPos + dragPos / (trackLength - thumbLength));
+                    behavior.thumbDragged(preDragThumbPos + dragPos / (trackLength - thumbLength));
                 }
 
                 me.consume();
             }
         });

@@ -267,11 +499,11 @@
                         if (dragStart == null) {
                             // we're getting dragged without getting a mouse press
                             dragStart = thumb.localToParent(event.getX(), event.getY());
                         }
                         double dragPos = getSkinnable().getOrientation() == Orientation.VERTICAL ? cur.getY() - dragStart.getY(): cur.getX() - dragStart.getX();
-                        getBehavior().thumbDragged(/*todo*/ preDragThumbPos + dragPos / (trackLength - thumbLength));
+                        behavior.thumbDragged(/*todo*/ preDragThumbPos + dragPos / (trackLength - thumbLength));
                     }
 
                     event.consume();
                     return;
                 }

@@ -308,11 +540,11 @@
                 * TODO: this fix causes RT-23406 ([ScrollBar, touch] Dragging scrollbar from the
                 * track on touchscreen causes flickering)
                 */
                 if (event.isDirect()) {
                     if (trackLength > thumbLength) {
-                        getBehavior().thumbDragged((getSkinnable().getOrientation() == Orientation.VERTICAL ? event.getY(): event.getX()) / trackLength);
+                        behavior.thumbDragged((getSkinnable().getOrientation() == Orientation.VERTICAL ? event.getY() : event.getX()) / trackLength);
                         event.consume();
                     }
                 }
                 else {
                     if (delta > 0.0 && sb.getValue() > sb.getMin()) {

@@ -325,60 +557,39 @@
                 }
             }
         });
 
         getChildren().clear();
-        if (!IS_TOUCH_SUPPORTED) {
+        if (!Properties.IS_TOUCH_SUPPORTED) {
             getChildren().addAll(trackBackground, incButton, decButton, track, thumb);
         }
         else {
             getChildren().addAll(track, thumb);
         }
     }
 
 
-
-    @Override protected void handleControlPropertyChanged(String p) {
-        super.handleControlPropertyChanged(p);
-        if ("ORIENTATION".equals(p)) {
-            getSkinnable().requestLayout();
-        } else if ("MIN".equals(p) || "MAX".equals(p) || "VISIBLE_AMOUNT".equals(p)) {
-            positionThumb();
-            getSkinnable().requestLayout();
-        } else if ("VALUE".equals(p)) {
-            positionThumb();
-        }
-    }
-
-    /***************************************************************************
-     *                                                                         *
-     * Layout                                                                  *
-     *                                                                         *
-     **************************************************************************/
-
-    private static final double DEFAULT_EMBEDDED_SB_BREADTH = 8.0;
-
     /*
      * Gets the breadth of the scrollbar. The "breadth" is the distance
      * across the scrollbar, i.e. if vertical the width, otherwise the height.
      * On desktop this is determined by the greater of the breadths of the end-buttons.
      * Embedded doesn't have end-buttons, so currently we use a default breadth.
      * We should change this when we get width/height css properties.
      */
     double getBreadth() {
-        if (!IS_TOUCH_SUPPORTED) {
+        if (!Properties.IS_TOUCH_SUPPORTED) {
             if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
                 return Math.max(decButton.prefWidth(-1), incButton.prefWidth(-1)) +snappedLeftInset()+snappedRightInset();
             } else {
                 return Math.max(decButton.prefHeight(-1), incButton.prefHeight(-1)) +snappedTopInset()+snappedBottomInset();
             }
         }
         else {
             if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
-                return Math.max(DEFAULT_EMBEDDED_SB_BREADTH, DEFAULT_EMBEDDED_SB_BREADTH)+snappedLeftInset()+snappedRightInset();
+                return Math.max(Properties.DEFAULT_EMBEDDED_SB_BREADTH, Properties.DEFAULT_EMBEDDED_SB_BREADTH)+snappedLeftInset()+snappedRightInset();
             } else {
-                return Math.max(DEFAULT_EMBEDDED_SB_BREADTH, DEFAULT_EMBEDDED_SB_BREADTH)+snappedTopInset()+snappedBottomInset();
+                return Math.max(Properties.DEFAULT_EMBEDDED_SB_BREADTH, Properties.DEFAULT_EMBEDDED_SB_BREADTH)+snappedTopInset()+snappedBottomInset();
             }
         }
     }
 
     double minThumbLength() {

@@ -387,76 +598,19 @@
 
     double minTrackLength() {
         return 2.0f * getBreadth();
     }
 
-    /*
-     * Minimum length is the length of the end buttons plus twice the
-     * minimum thumb length, which should be enough for a reasonably-sized
-     * track. Minimum breadth is determined by the breadths of the
-     * end buttons.
-     */
-    @Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
-        if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
-            return getBreadth();
-        } else {
-            if (!IS_TOUCH_SUPPORTED) {
-                return decButton.minWidth(-1) + incButton.minWidth(-1) + minTrackLength()+leftInset+rightInset;
-            } else {
-                return minTrackLength()+leftInset+rightInset;
-            }
-        }
-    }
-
-    @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
-        if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
-            if (!IS_TOUCH_SUPPORTED) {
-                return decButton.minHeight(-1) + incButton.minHeight(-1) + minTrackLength()+topInset+bottomInset;
-            } else {
-                return minTrackLength()+topInset+bottomInset;
-            }
-        } else {
-            return getBreadth();
-        }
-    }
-
-    /*
-     * Preferred size. The breadth is determined by the breadth of
-     * the end buttons. The length is a constant default length.
-     * Usually applications or other components will either set a
-     * specific length using LayoutInfo or will stretch the length
-     * of the scrollbar to fit a container.
-     */
-    @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
-        final ScrollBar s = getSkinnable();
-        return s.getOrientation() == Orientation.VERTICAL ? getBreadth() : DEFAULT_LENGTH+leftInset+rightInset;
-    }
-
-    @Override protected double computePrefHeight(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
-        final ScrollBar s = getSkinnable();
-        return s.getOrientation() == Orientation.VERTICAL ? DEFAULT_LENGTH+topInset+bottomInset : getBreadth();
-    }
-
-    @Override protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
-        final ScrollBar s = getSkinnable();
-        return s.getOrientation() == Orientation.VERTICAL ? s.prefWidth(-1) : Double.MAX_VALUE;
-    }
-
-    @Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
-        final ScrollBar s = getSkinnable();
-        return s.getOrientation() == Orientation.VERTICAL ? Double.MAX_VALUE : s.prefHeight(-1);
-    }
-
     /**
      * Called when ever either min, max or value changes, so thumb's layoutX, Y is recomputed.
      */
     void positionThumb() {
         ScrollBar s = getSkinnable();
         double clampedValue = Utils.clamp(s.getMin(), s.getValue(), s.getMax());
         trackPos = (s.getMax() - s.getMin() > 0) ? ((trackLength - thumbLength) * (clampedValue - s.getMin()) / (s.getMax() - s.getMin())) : (0.0F);
         
-        if (!IS_TOUCH_SUPPORTED) {
+        if (!Properties.IS_TOUCH_SUPPORTED) {
             if (s.getOrientation() == Orientation.VERTICAL) {
                 trackPos += decButton.prefHeight(-1);
             } else {
                 trackPos += decButton.prefWidth(-1);
             }

@@ -464,137 +618,34 @@
         
         thumb.setTranslateX( snapPosition(s.getOrientation() == Orientation.VERTICAL ? snappedLeftInset() : trackPos + snappedLeftInset()));
         thumb.setTranslateY( snapPosition(s.getOrientation() == Orientation.VERTICAL ? trackPos + snappedTopInset() : snappedTopInset()));
     }
     
-    @Override protected void layoutChildren(final double x, final double y,
-            final double w, final double h) {
-        
-        final ScrollBar s = getSkinnable();
-        
-        /**
-         * Compute the percentage length of thumb as (visibleAmount/range)
-         * if max isn't greater than min then there is nothing to do here
-         */
-        double visiblePortion;
-        if (s.getMax() > s.getMin()) {
-            visiblePortion = s.getVisibleAmount()/(s.getMax() - s.getMin());
-        }
-        else {
-            visiblePortion = 1.0;
-        }
-
-        if (s.getOrientation() == Orientation.VERTICAL) {
-            if (!IS_TOUCH_SUPPORTED) {
-                double decHeight = snapSize(decButton.prefHeight(-1));
-                double incHeight = snapSize(incButton.prefHeight(-1));
-
-                decButton.resize(w, decHeight);
-                incButton.resize(w, incHeight);
-
-                trackLength = snapSize(h - (decHeight + incHeight));
-                thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
-
-                trackBackground.resizeRelocate(snapPosition(x), snapPosition(y), w, trackLength+decHeight+incHeight);
-                decButton.relocate(snapPosition(x), snapPosition(y));
-                incButton.relocate(snapPosition(x), snapPosition(y + h - incHeight));
-                track.resizeRelocate(snapPosition(x), snapPosition(y + decHeight), w, trackLength);
-                thumb.resize(snapSize(x >= 0 ? w : w + x), thumbLength); // Account for negative padding (see also RT-10719)
-                positionThumb();
-            }
-            else {
-                trackLength = snapSize(h);
-                thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
-
-                track.resizeRelocate(snapPosition(x), snapPosition(y), w, trackLength);
-                thumb.resize(snapSize(x >= 0 ? w : w + x), thumbLength); // Account for negative padding (see also RT-10719)
-                positionThumb();
-            }
-        } else {
-            if (!IS_TOUCH_SUPPORTED) {
-                double decWidth = snapSize(decButton.prefWidth(-1));
-                double incWidth = snapSize(incButton.prefWidth(-1));
-
-                decButton.resize(decWidth, h);
-                incButton.resize(incWidth, h);
-
-                trackLength = snapSize(w - (decWidth + incWidth));
-                thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
-
-                trackBackground.resizeRelocate(snapPosition(x), snapPosition(y), trackLength+decWidth+incWidth, h);
-                decButton.relocate(snapPosition(x), snapPosition(y));
-                incButton.relocate(snapPosition(x + w - incWidth), snapPosition(y));
-                track.resizeRelocate(snapPosition(x + decWidth), snapPosition(y), trackLength, h);
-                thumb.resize(thumbLength, snapSize(y >= 0 ? h : h + y)); // Account for negative padding (see also RT-10719)
-                positionThumb();
-            }
-            else {
-                trackLength = snapSize(w);
-                thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
-
-                track.resizeRelocate(snapPosition(x), snapPosition(y), trackLength, h);
-                thumb.resize(thumbLength, snapSize(y >= 0 ? h : h + y)); // Account for negative padding (see also RT-10719)
-                positionThumb();
-            }
-
-            s.resize(snapSize(s.getWidth()), snapSize(s.getHeight()));
-        }
-        
-        // things should be invisible only when well below minimum length
-        if (s.getOrientation() == Orientation.VERTICAL && h >= (computeMinHeight(-1, (int)y , snappedRightInset(), snappedBottomInset(), (int)x) - (y+snappedBottomInset())) ||
-            s.getOrientation() == Orientation.HORIZONTAL && w >= (computeMinWidth(-1, (int)y , snappedRightInset(), snappedBottomInset(), (int)x) - (x+snappedRightInset()))) {
-            trackBackground.setVisible(true);
-            track.setVisible(true);
-            thumb.setVisible(true);
-            if (!IS_TOUCH_SUPPORTED) {
-                incButton.setVisible(true);
-                decButton.setVisible(true);
-            }
-        }
-        else {
-            trackBackground.setVisible(false);
-            track.setVisible(false);
-            thumb.setVisible(false);
-
-            if (!IS_TOUCH_SUPPORTED) {
-                /*
-                ** once the space is big enough for one button we 
-                ** can look at drawing
-                */
-                if (h >= decButton.computeMinWidth(-1)) {
-                    decButton.setVisible(true);
-                }
-                else {
-                    decButton.setVisible(false);
-                }
-                if (h >= incButton.computeMinWidth(-1)) {
-                    incButton.setVisible(true);
-                }
-                else {
-                    incButton.setVisible(false);
-                }
-            }
-        }
-    }
-
-    
-    public Node getThumb() {
+    private Node getThumb() {
         return thumb;
     }
     
-    public Node getTrack() {
+    private Node getTrack() {
         return track;
     }
     
-    public Node getIncButton() {
+    private Node getIncrementButton() {
         return incButton;
     }
     
-    public Node getDecButton() {
+    private Node getDecrementButton() {
         return decButton;
     }
     
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Support classes                                                         *
+     *                                                                         *
+     **************************************************************************/
+
     private static class EndButton extends Region {
         private Region arrow;
 
         private EndButton(String styleClass, String arrowStyleClass) {
             getStyleClass().setAll(styleClass);