alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (AquaScrollBarUI.java)

This example Java source code file (AquaScrollBarUI.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

actionevent, aquascrollbarui, awt, bean, dimension, event, gui, hit, initialdelay, jcomponent, modellistener, mouseevent, plaf, point, propertychangelistener, rectangle, scrollbarpart, scrolllistener, swing, tracklistener

The AquaScrollBarUI.java Java example source code

/*
 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * 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.apple.laf;

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.util.*;

import javax.swing.*;
import javax.swing.Timer;
import javax.swing.event.*;
import javax.swing.plaf.*;

import apple.laf.*;
import apple.laf.JRSUIConstants.*;
import apple.laf.JRSUIState.ScrollBarState;

import com.apple.laf.AquaUtils.RecyclableSingleton;

public class AquaScrollBarUI extends ScrollBarUI {
    private static final int kInitialDelay = 300;
    private static final int kNormalDelay = 100;

    // when we make small and mini scrollbars, this will no longer be a constant
    static final int MIN_ARROW_COLLAPSE_SIZE = 64;

    // tracking state
    protected boolean fIsDragging;
    protected Timer fScrollTimer;
    protected ScrollListener fScrollListener;
    protected TrackListener fTrackListener;
    protected Hit fTrackHighlight = Hit.NONE;
    protected Hit fMousePart = Hit.NONE; // Which arrow (if any) we moused pressed down in (used by arrow drag tracking)

    protected JScrollBar fScrollBar;
    protected ModelListener fModelListener;
    protected PropertyChangeListener fPropertyChangeListener;

    protected final AquaPainter<ScrollBarState> painter = AquaPainter.create(JRSUIStateFactory.getScrollBar());

    // Create PLAF
    public static ComponentUI createUI(final JComponent c) {
        return new AquaScrollBarUI();
    }

    public AquaScrollBarUI() { }

    public void installUI(final JComponent c) {
        fScrollBar = (JScrollBar)c;
        installListeners();
        configureScrollBarColors();
    }

    public void uninstallUI(final JComponent c) {
        uninstallListeners();
        fScrollBar = null;
    }

    protected void configureScrollBarColors() {
        LookAndFeel.installColors(fScrollBar, "ScrollBar.background", "ScrollBar.foreground");
    }

    protected TrackListener createTrackListener() {
        return new TrackListener();
    }

    protected ScrollListener createScrollListener() {
        return new ScrollListener();
    }

    protected void installListeners() {
        fTrackListener = createTrackListener();
        fModelListener = createModelListener();
        fPropertyChangeListener = createPropertyChangeListener();
        fScrollBar.addMouseListener(fTrackListener);
        fScrollBar.addMouseMotionListener(fTrackListener);
        fScrollBar.getModel().addChangeListener(fModelListener);
        fScrollBar.addPropertyChangeListener(fPropertyChangeListener);
        fScrollListener = createScrollListener();
        fScrollTimer = new Timer(kNormalDelay, fScrollListener);
        fScrollTimer.setInitialDelay(kInitialDelay); // default InitialDelay?
    }

    protected void uninstallListeners() {
        fScrollTimer.stop();
        fScrollTimer = null;
        fScrollBar.getModel().removeChangeListener(fModelListener);
        fScrollBar.removeMouseListener(fTrackListener);
        fScrollBar.removeMouseMotionListener(fTrackListener);
        fScrollBar.removePropertyChangeListener(fPropertyChangeListener);
    }

    protected PropertyChangeListener createPropertyChangeListener() {
        return new PropertyChangeHandler();
    }

    protected ModelListener createModelListener() {
        return new ModelListener();
    }

    protected void syncState(final JComponent c) {
        final ScrollBarState scrollBarState = painter.state;
        scrollBarState.set(isHorizontal() ? Orientation.HORIZONTAL : Orientation.VERTICAL);

        final float trackExtent = fScrollBar.getMaximum() - fScrollBar.getMinimum() - fScrollBar.getModel().getExtent();
        if (trackExtent <= 0.0f) {
            scrollBarState.set(NothingToScroll.YES);
            return;
        }

        final ScrollBarPart pressedPart = getPressedPart();
        scrollBarState.set(pressedPart);
        scrollBarState.set(getState(c, pressedPart));
        scrollBarState.set(NothingToScroll.NO);
        scrollBarState.setValue((fScrollBar.getValue() - fScrollBar.getMinimum()) / trackExtent);
        scrollBarState.setThumbStart(getThumbStart());
        scrollBarState.setThumbPercent(getThumbPercent());
        scrollBarState.set(shouldShowArrows() ? ShowArrows.YES : ShowArrows.NO);
    }

    public void paint(final Graphics g, final JComponent c) {
        syncState(c);
        painter.paint(g, c, 0, 0, fScrollBar.getWidth(), fScrollBar.getHeight());
    }

    protected State getState(final JComponent c, final ScrollBarPart pressedPart) {
        if (!AquaFocusHandler.isActive(c)) return State.INACTIVE;
        if (!c.isEnabled()) return State.INACTIVE;
        if (pressedPart != ScrollBarPart.NONE) return State.PRESSED;
        return State.ACTIVE;
    }

    static final RecyclableSingleton<Map hitToPressedPartMap = new RecyclableSingleton>(){
        @Override
        protected Map<Hit, ScrollBarPart> getInstance() {
            final Map<Hit, ScrollBarPart> map = new HashMap(7);
            map.put(ScrollBarHit.ARROW_MAX, ScrollBarPart.ARROW_MAX);
            map.put(ScrollBarHit.ARROW_MIN, ScrollBarPart.ARROW_MIN);
            map.put(ScrollBarHit.ARROW_MAX_INSIDE, ScrollBarPart.ARROW_MAX_INSIDE);
            map.put(ScrollBarHit.ARROW_MIN_INSIDE, ScrollBarPart.ARROW_MIN_INSIDE);
            map.put(ScrollBarHit.TRACK_MAX, ScrollBarPart.TRACK_MAX);
            map.put(ScrollBarHit.TRACK_MIN, ScrollBarPart.TRACK_MIN);
            map.put(ScrollBarHit.THUMB, ScrollBarPart.THUMB);
            return map;
        }
    };
    protected ScrollBarPart getPressedPart() {
        if (!fTrackListener.fInArrows || !fTrackListener.fStillInArrow) return ScrollBarPart.NONE;
        final ScrollBarPart pressedPart = hitToPressedPartMap.get().get(fMousePart);
        if (pressedPart == null) return ScrollBarPart.NONE;
        return pressedPart;
    }

    protected boolean shouldShowArrows() {
        return MIN_ARROW_COLLAPSE_SIZE < (isHorizontal() ? fScrollBar.getWidth() : fScrollBar.getHeight());
    }

    // Layout Methods
    // Layout is controlled by the user in the Appearance Control Panel
    // Theme will redraw correctly for the current layout
    public void layoutContainer(final Container fScrollBarContainer) {
        fScrollBar.repaint();
        fScrollBar.revalidate();
    }

    protected Rectangle getTrackBounds() {
        return new Rectangle(0, 0, fScrollBar.getWidth(), fScrollBar.getHeight());
    }

    protected Rectangle getDragBounds() {
        return new Rectangle(0, 0, fScrollBar.getWidth(), fScrollBar.getHeight());
    }

    protected void startTimer(final boolean initial) {
        fScrollTimer.setInitialDelay(initial ? kInitialDelay : kNormalDelay); // default InitialDelay?
        fScrollTimer.start();
    }

    protected void scrollByBlock(final int direction) {
        synchronized(fScrollBar) {
            final int oldValue = fScrollBar.getValue();
            final int blockIncrement = fScrollBar.getBlockIncrement(direction);
            final int delta = blockIncrement * ((direction > 0) ? +1 : -1);

            fScrollBar.setValue(oldValue + delta);
            fTrackHighlight = direction > 0 ? ScrollBarHit.TRACK_MAX : ScrollBarHit.TRACK_MIN;
            fScrollBar.repaint();
            fScrollListener.setDirection(direction);
            fScrollListener.setScrollByBlock(true);
        }
    }

    protected void scrollByUnit(final int direction) {
        synchronized(fScrollBar) {
            int delta = fScrollBar.getUnitIncrement(direction);
            if (direction <= 0) delta = -delta;

            fScrollBar.setValue(delta + fScrollBar.getValue());
            fScrollBar.repaint();
            fScrollListener.setDirection(direction);
            fScrollListener.setScrollByBlock(false);
        }
    }

    protected Hit getPartHit(final int x, final int y) {
        syncState(fScrollBar);
        return JRSUIUtils.HitDetection.getHitForPoint(painter.getControl(), 0, 0, fScrollBar.getWidth(), fScrollBar.getHeight(), x, y);
    }

    protected class PropertyChangeHandler implements PropertyChangeListener {
        public void propertyChange(final PropertyChangeEvent e) {
            final String propertyName = e.getPropertyName();

            if ("model".equals(propertyName)) {
                final BoundedRangeModel oldModel = (BoundedRangeModel)e.getOldValue();
                final BoundedRangeModel newModel = (BoundedRangeModel)e.getNewValue();
                oldModel.removeChangeListener(fModelListener);
                newModel.addChangeListener(fModelListener);
                fScrollBar.repaint();
                fScrollBar.revalidate();
            } else if (AquaFocusHandler.FRAME_ACTIVE_PROPERTY.equals(propertyName)) {
                fScrollBar.repaint();
            }
        }
    }

    protected class ModelListener implements ChangeListener {
        public void stateChanged(final ChangeEvent e) {
            layoutContainer(fScrollBar);
        }
    }

    // Track mouse drags.
    protected class TrackListener extends MouseAdapter implements MouseMotionListener {
        protected transient int fCurrentMouseX, fCurrentMouseY;
        protected transient boolean fInArrows; // are we currently tracking arrows?
        protected transient boolean fStillInArrow = false; // Whether mouse is in an arrow during arrow tracking
        protected transient boolean fStillInTrack = false; // Whether mouse is in the track during pageup/down tracking
        protected transient int fFirstMouseX, fFirstMouseY, fFirstValue; // Values for getValueFromOffset

        public void mouseReleased(final MouseEvent e) {
            if (!fScrollBar.isEnabled()) return;
            if (fInArrows) {
                mouseReleasedInArrows(e);
            } else {
                mouseReleasedInTrack(e);
            }

            fInArrows = false;
            fStillInArrow = false;
            fStillInTrack = false;

            fScrollBar.repaint();
            fScrollBar.revalidate();
        }

        public void mousePressed(final MouseEvent e) {
            if (!fScrollBar.isEnabled()) return;

            final Hit part = getPartHit(e.getX(), e.getY());
            fInArrows = HitUtil.isArrow(part);
            if (fInArrows) {
                mousePressedInArrows(e, part);
            } else {
                if (part == Hit.NONE) {
                    fTrackHighlight = Hit.NONE;
                } else {
                    mousePressedInTrack(e, part);
                }
            }
        }

        public void mouseDragged(final MouseEvent e) {
            if (!fScrollBar.isEnabled()) return;

            if (fInArrows) {
                mouseDraggedInArrows(e);
            } else if (fIsDragging) {
                mouseDraggedInTrack(e);
            } else {
                // In pageup/down zones

                // check that thumb has not been scrolled under the mouse cursor
                final Hit previousPart = getPartHit(fCurrentMouseX, fCurrentMouseY);
                if (!HitUtil.isTrack(previousPart)) {
                    fStillInTrack = false;
                }

                fCurrentMouseX = e.getX();
                fCurrentMouseY = e.getY();

                final Hit part = getPartHit(e.getX(), e.getY());
                final boolean temp = HitUtil.isTrack(part);
                if (temp == fStillInTrack) return;

                fStillInTrack = temp;
                if (!fStillInTrack) {
                    fScrollTimer.stop();
                } else {
                    fScrollListener.actionPerformed(new ActionEvent(fScrollTimer, 0, ""));
                    startTimer(false);
                }
            }
        }

        int getValueFromOffset(final int xOffset, final int yOffset, final int firstValue) {
            final boolean isHoriz = isHorizontal();

            // find the amount of pixels we've moved x & y (we only care about one)
            final int offsetWeCareAbout = isHoriz ? xOffset : yOffset;

            // now based on that floating point percentage compute the real scroller value.
            final int visibleAmt = fScrollBar.getVisibleAmount();
            final int max = fScrollBar.getMaximum();
            final int min = fScrollBar.getMinimum();
            final int extent = max - min;

            // ask native to tell us what the new float that is a ratio of how much scrollable area
            // we have moved (not the thumb area, just the scrollable). If the
            // scroller goes 0-100 with a visible area of 20 we are getting a ratio of the
            // remaining 80.
            syncState(fScrollBar);
            final double offsetChange = JRSUIUtils.ScrollBar.getNativeOffsetChange(painter.getControl(), 0, 0, fScrollBar.getWidth(), fScrollBar.getHeight(), offsetWeCareAbout, visibleAmt, extent);

            // the scrollable area is the extent - visible amount;
            final int scrollableArea = extent - visibleAmt;

            final int changeByValue = (int)(offsetChange * scrollableArea);
            int newValue = firstValue + changeByValue;
            newValue = Math.max(min, newValue);
            newValue = Math.min((max - visibleAmt), newValue);
            return newValue;
        }

        /**
         * Arrow Listeners
         */
        // Because we are handling both mousePressed and Actions
        // we need to make sure we don't fire under both conditions.
        // (keyfocus on scrollbars causes action without mousePress
        void mousePressedInArrows(final MouseEvent e, final Hit part) {
            final int direction = HitUtil.isIncrement(part) ? 1 : -1;

            fStillInArrow = true;
            scrollByUnit(direction);
            fScrollTimer.stop();
            fScrollListener.setDirection(direction);
            fScrollListener.setScrollByBlock(false);

            fMousePart = part;
            startTimer(true);
        }

        void mouseReleasedInArrows(final MouseEvent e) {
            fScrollTimer.stop();
            fMousePart = Hit.NONE;
            fScrollBar.setValueIsAdjusting(false);
        }

        void mouseDraggedInArrows(final MouseEvent e) {
            final Hit whichPart = getPartHit(e.getX(), e.getY());

            if ((fMousePart == whichPart) && fStillInArrow) return; // Nothing has changed, so return

            if (fMousePart != whichPart && !HitUtil.isArrow(whichPart)) {
                // The mouse is not over the arrow we mouse pressed in, so stop the timer and mark as
                // not being in the arrow
                fScrollTimer.stop();
                fStillInArrow = false;
                fScrollBar.repaint();
            } else {
                // We are in the arrow we mouse pressed down in originally, but the timer was stopped so we need
                // to start it up again.
                fMousePart = whichPart;
                fScrollListener.setDirection(HitUtil.isIncrement(whichPart) ? 1 : -1);
                fStillInArrow = true;
                fScrollListener.actionPerformed(new ActionEvent(fScrollTimer, 0, ""));
                startTimer(false);
            }

            fScrollBar.repaint();
        }

        void mouseReleasedInTrack(final MouseEvent e) {
            if (fTrackHighlight != Hit.NONE) {
                fScrollBar.repaint();
            }

            fTrackHighlight = Hit.NONE;
            fIsDragging = false;
            fScrollTimer.stop();
            fScrollBar.setValueIsAdjusting(false);
        }

        /**
         * Adjust the fScrollBars value based on the result of hitTestTrack
         */
        void mousePressedInTrack(final MouseEvent e, final Hit part) {
            fScrollBar.setValueIsAdjusting(true);

            // If option-click, toggle scroll-to-here
            boolean shouldScrollToHere = (part != ScrollBarHit.THUMB) && JRSUIUtils.ScrollBar.useScrollToClick();
            if (e.isAltDown()) shouldScrollToHere = !shouldScrollToHere;

            // pretend the mouse was dragged from a point in the current thumb to the current mouse point in one big jump
            if (shouldScrollToHere) {
                final Point p = getScrollToHereStartPoint(e.getX(), e.getY());
                fFirstMouseX = p.x;
                fFirstMouseY = p.y;
                fFirstValue = fScrollBar.getValue();
                moveToMouse(e);

                // OK, now we're in the thumb - any subsequent dragging should move it
                fTrackHighlight = ScrollBarHit.THUMB;
                fIsDragging = true;
                return;
            }

            fCurrentMouseX = e.getX();
            fCurrentMouseY = e.getY();

            int direction = 0;
            if (part == ScrollBarHit.TRACK_MIN) {
                fTrackHighlight = ScrollBarHit.TRACK_MIN;
                direction = -1;
            } else if (part == ScrollBarHit.TRACK_MAX) {
                fTrackHighlight = ScrollBarHit.TRACK_MAX;
                direction = 1;
            } else {
                fFirstValue = fScrollBar.getValue();
                fFirstMouseX = fCurrentMouseX;
                fFirstMouseY = fCurrentMouseY;
                fTrackHighlight = ScrollBarHit.THUMB;
                fIsDragging = true;
                return;
            }

            fIsDragging = false;
            fStillInTrack = true;

            scrollByBlock(direction);
            // Check the new location of the thumb
            // stop scrolling if the thumb is under the mouse??

            final Hit newPart = getPartHit(fCurrentMouseX, fCurrentMouseY);
            if (newPart == ScrollBarHit.TRACK_MIN || newPart == ScrollBarHit.TRACK_MAX) {
                fScrollTimer.stop();
                fScrollListener.setDirection(((newPart == ScrollBarHit.TRACK_MAX) ? 1 : -1));
                fScrollListener.setScrollByBlock(true);
                startTimer(true);
            }
        }

        /**
         * Set the models value to the position of the top/left
         * of the thumb relative to the origin of the track.
         */
        void mouseDraggedInTrack(final MouseEvent e) {
            moveToMouse(e);
        }

        // For normal mouse dragging or click-to-here
        // fCurrentMouseX, fCurrentMouseY, and fFirstValue must be set
        void moveToMouse(final MouseEvent e) {
            fCurrentMouseX = e.getX();
            fCurrentMouseY = e.getY();

            final int oldValue = fScrollBar.getValue();
            final int newValue = getValueFromOffset(fCurrentMouseX - fFirstMouseX, fCurrentMouseY - fFirstMouseY, fFirstValue);
            if (newValue == oldValue) return;

            fScrollBar.setValue(newValue);
            final Rectangle dirtyRect = getTrackBounds();
            fScrollBar.repaint(dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height);
        }
    }

    /**
     * Listener for scrolling events initiated in the ScrollPane.
     */
    protected class ScrollListener implements ActionListener {
        boolean fUseBlockIncrement;
        int fDirection = 1;

        void setDirection(final int direction) {
            this.fDirection = direction;
        }

        void setScrollByBlock(final boolean block) {
            this.fUseBlockIncrement = block;
        }

        public void actionPerformed(final ActionEvent e) {
            if (fUseBlockIncrement) {
                Hit newPart = getPartHit(fTrackListener.fCurrentMouseX, fTrackListener.fCurrentMouseY);

                if (newPart == ScrollBarHit.TRACK_MIN || newPart == ScrollBarHit.TRACK_MAX) {
                    final int newDirection = (newPart == ScrollBarHit.TRACK_MAX ? 1 : -1);
                    if (fDirection != newDirection) {
                        fDirection = newDirection;
                    }
                }

                scrollByBlock(fDirection);
                newPart = getPartHit(fTrackListener.fCurrentMouseX, fTrackListener.fCurrentMouseY);

                if (newPart == ScrollBarHit.THUMB) {
                    ((Timer)e.getSource()).stop();
                }
            } else {
                scrollByUnit(fDirection);
            }

            if (fDirection > 0 && fScrollBar.getValue() + fScrollBar.getVisibleAmount() >= fScrollBar.getMaximum()) {
                ((Timer)e.getSource()).stop();
            } else if (fDirection < 0 && fScrollBar.getValue() <= fScrollBar.getMinimum()) {
                ((Timer)e.getSource()).stop();
            }
        }
    }

    float getThumbStart() {
        final int max = fScrollBar.getMaximum();
        final int min = fScrollBar.getMinimum();
        final int extent = max - min;
        if (extent <= 0) return 0f;

        return (float)(fScrollBar.getValue() - fScrollBar.getMinimum()) / (float)extent;
    }

    float getThumbPercent() {
        final int visible = fScrollBar.getVisibleAmount();
        final int max = fScrollBar.getMaximum();
        final int min = fScrollBar.getMinimum();
        final int extent = max - min;
        if (extent <= 0) return 0f;

        return (float)visible / (float)extent;
    }

    /**
     * A scrollbar's preferred width is 16 by a reasonable size to hold
     * the arrows
     *
     * @param c The JScrollBar that's delegating this method to us.
     * @return The preferred size of a Basic JScrollBar.
     * @see #getMaximumSize
     * @see #getMinimumSize
     */
    public Dimension getPreferredSize(final JComponent c) {
        return isHorizontal() ? new Dimension(96, 15) : new Dimension(15, 96);
    }

    public Dimension getMinimumSize(final JComponent c) {
        return isHorizontal() ? new Dimension(54, 15) : new Dimension(15, 54);
    }

    public Dimension getMaximumSize(final JComponent c) {
        return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
    }

    boolean isHorizontal() {
        return fScrollBar.getOrientation() == Adjustable.HORIZONTAL;
    }

    // only do scroll-to-here for page up and page down regions, when the option key is pressed
    // This gets the point where the mouse would have been clicked in the current thumb
    // so we can pretend the mouse was dragged to the current mouse point in one big jump
    Point getScrollToHereStartPoint(final int clickPosX, final int clickPosY) {
        // prepare the track rectangle and limit rectangle so we can do our calculations
        final Rectangle limitRect = getDragBounds(); // GetThemeTrackDragRect

        // determine the bounding rectangle for our thumb region
        syncState(fScrollBar);
        double[] rect = new double[4];
        JRSUIUtils.ScrollBar.getPartBounds(rect, painter.getControl(), 0, 0, fScrollBar.getWidth(), fScrollBar.getHeight(), ScrollBarPart.THUMB);
        final Rectangle r = new Rectangle((int)rect[0], (int)rect[1], (int)rect[2], (int)rect[3]);

        // figure out the scroll-to-here start location based on our orientation, the
        // click position, and where it must be in the thumb to travel to the endpoints
        // properly.
        final Point startPoint = new Point(clickPosX, clickPosY);

        if (isHorizontal()) {
            final int halfWidth = r.width / 2;
            final int limitRectRight = limitRect.x + limitRect.width;

            if (clickPosX + halfWidth > limitRectRight) {
                // Up against right edge
                startPoint.x = r.x + r.width - limitRectRight - clickPosX - 1;
            } else if (clickPosX - halfWidth < limitRect.x) {
                // Up against left edge
                startPoint.x = r.x + clickPosX - limitRect.x;
            } else {
                // Center the thumb
                startPoint.x = r.x + halfWidth;
            }

            // Pretend clicked in middle of indicator vertically
            startPoint.y = (r.y + r.height) / 2;
            return startPoint;
        }

        final int halfHeight = r.height / 2;
        final int limitRectBottom = limitRect.y + limitRect.height;

        if (clickPosY + halfHeight > limitRectBottom) {
            // Up against bottom edge
            startPoint.y = r.y + r.height - limitRectBottom - clickPosY - 1;
        } else if (clickPosY - halfHeight < limitRect.y) {
            // Up against top edge
            startPoint.y = r.y + clickPosY - limitRect.y;
        } else {
            // Center the thumb
            startPoint.y = r.y + halfHeight;
        }

        // Pretend clicked in middle of indicator horizontally
        startPoint.x = (r.x + r.width) / 2;

        return startPoint;
    }

    static class HitUtil {
        static boolean isIncrement(final Hit hit) {
            return (hit == ScrollBarHit.ARROW_MAX) || (hit == ScrollBarHit.ARROW_MAX_INSIDE);
        }

        static boolean isDecrement(final Hit hit) {
            return (hit == ScrollBarHit.ARROW_MIN) || (hit == ScrollBarHit.ARROW_MIN_INSIDE);
        }

        static boolean isArrow(final Hit hit) {
            return isIncrement(hit) || isDecrement(hit);
        }

        static boolean isTrack(final Hit hit) {
            return (hit == ScrollBarHit.TRACK_MAX) || (hit == ScrollBarHit.TRACK_MIN);
        }
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java AquaScrollBarUI.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.