/** * Gets the scale factor that allows us to translate pixel values to scroll bar values and vice * versa. This assumes that the range of pixels spans from the last pixel of * <tt>scrollUpButton</tt> to the first pixel of <tt>scrollDownButton</tt> and excludes the pixels * taken up by <tt>handle</tt>. * * <p>To map from scroll bar values (<i>real values</i>) to pixel values, you multiply by the * value scale. To map from pixel values back to real values, you divide by the value scale. * * @return <tt><number of legal pixel values> / <number of legal real values></tt> */ private float getValueScale() { ScrollBar scrollBar = (ScrollBar) getComponent(); float valueScale; int start = scrollBar.getStart(); int end = scrollBar.getEnd(); int extent = scrollBar.getExtent(); int maxLegalRealValue = end - extent; int numLegalRealValues = maxLegalRealValue - start + 1; int numLegalPixelValues; if (scrollBar.getOrientation() == Orientation.HORIZONTAL) { int availableWidth = getWidth() - scrollUpButton.getWidth() - scrollDownButton.getWidth() + 2; numLegalPixelValues = availableWidth - handle.getWidth() + 1; } else { int availableHeight = getHeight() - scrollUpButton.getHeight() - scrollDownButton.getHeight() + 2; numLegalPixelValues = availableHeight - handle.getHeight() + 1; } // the number of segments is one less than the number of values valueScale = numLegalPixelValues / ((float) numLegalRealValues - 1); return valueScale; }
/** * Initiates automatic block scrolling. This only happens if the handle is visible since whether * the user clicked before or after the handle determines the direction of the scrolling. * * @param component The scroll bar. * @param button The button that was pressed. * @param x The x-coordinate of the event in the scroll bar's coordinate space. * @param y The y-coordinate of the event in the scroll bar's coordinate space. */ @Override public boolean mouseDown(Component component, Mouse.Button button, int x, int y) { boolean consumed = super.mouseDown(component, button, x, y); if (button == Mouse.Button.LEFT && handle.isVisible()) { ScrollBar scrollBar = (ScrollBar) getComponent(); // Begin automatic block scrolling. Calculate the direction of // the scroll by checking to see if the user pressed the mouse // in the area "before" the handle or "after" it. int direction; int realStopValue; if (scrollBar.getOrientation() == Orientation.HORIZONTAL) { direction = x < handle.getX() ? -1 : 1; int pixelStopValue = x - scrollUpButton.getWidth() + 1; if (direction == 1) { // If we're scrolling down, account for the width of the // handle in our pixel stop value so that we stop as soon // as the *bottom* of the handle reaches our click point pixelStopValue -= handle.getWidth(); } realStopValue = (int) (pixelStopValue / getValueScale()); } else { direction = y < handle.getY() ? -1 : 1; int pixelStopValue = y - scrollUpButton.getHeight() + 1; if (direction == 1) { // If we're scrolling down, account for the height of the // handle in our pixel stop value so that we stop as soon // as the *bottom* of the handle reaches our click point pixelStopValue -= handle.getHeight(); } realStopValue = (int) (pixelStopValue / getValueScale()); } // Start the automatic scroller automaticScroller.start(direction, Mouse.ScrollType.BLOCK, realStopValue); consumed = true; } return consumed; }