001    /*
002     * Created on Feb 2, 2008
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005     * in compliance with the License. You may obtain a copy of the License at
006     *
007     * http://www.apache.org/licenses/LICENSE-2.0
008     *
009     * Unless required by applicable law or agreed to in writing, software distributed under the License
010     * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011     * or implied. See the License for the specific language governing permissions and limitations under
012     * the License.
013     *
014     * Copyright @2008-2010 the original author or authors.
015     */
016    package org.fest.swing.driver;
017    
018    import static java.awt.Adjustable.HORIZONTAL;
019    import static java.awt.Adjustable.VERTICAL;
020    
021    import java.awt.Point;
022    import java.util.HashMap;
023    import java.util.Map;
024    
025    import javax.swing.JScrollBar;
026    
027    import org.fest.swing.annotation.RunsInCurrentThread;
028    
029    /**
030     * Understands a location in a <code>{@link JScrollBar}</code>.
031     *
032     * @author Yvonne Wang
033     * @author Alex Ruiz
034     */
035    public final class JScrollBarLocation {
036      // TODO Test horizontal scroll bar
037    
038      private static final int BLOCK_OFFSET = 4;
039    
040      private static final Map<Integer, JScrollBarLocationStrategy> LOCATIONS = new HashMap<Integer, JScrollBarLocationStrategy>();
041    
042      static {
043        LOCATIONS.put(HORIZONTAL, new HorizontalJScrollBarLocation());
044        LOCATIONS.put(VERTICAL, new VerticalJScrollBarLocation());
045      }
046    
047      /**
048       * Returns the location where to move the mouse pointer to scroll to the given position.
049       * <p>
050       * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
051       * responsible for calling this method from the EDT.
052       * </p>
053       * @param scrollBar the target <code>JScrollBar</code>.
054       * @param position the position to scroll to.
055       * @return the location where to move the mouse pointer to scroll to the given position.
056       */
057      @RunsInCurrentThread
058      public Point thumbLocation(JScrollBar scrollBar, int position) {
059        double fraction = (double) position / maximumMinusMinimum(scrollBar);
060        return locationStrategyFor(scrollBar).thumbLocation(scrollBar, fraction);
061      }
062    
063      @RunsInCurrentThread
064      private int maximumMinusMinimum(JScrollBar scrollBar) {
065        return scrollBar.getMaximum() - scrollBar.getMinimum();
066      }
067    
068      /**
069       * Returns the location where to move the mouse pointer to scroll one block up (or right.)
070       * <p>
071       * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
072       * responsible for calling this method from the EDT.
073       * </p>
074       * @param scrollBar the target <code>JScrollBar</code>.
075       * @return the location where to move the mouse pointer to scroll one block up (or right.)
076       */
077      @RunsInCurrentThread
078      public Point blockLocationToScrollUp(JScrollBar scrollBar) {
079        Point p = unitLocationToScrollUp(scrollBar);
080        int offset = BLOCK_OFFSET;
081        return blockLocation(scrollBar, p, offset);
082      }
083    
084      /**
085       * Returns the location where to move the mouse pointer to scroll one block down (or left.)
086       * <p>
087       * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
088       * responsible for calling this method from the EDT.
089       * </p>
090       * @param scrollBar the target <code>JScrollBar</code>.
091       * @return the location where to move the mouse pointer to scroll one block down (or left.)
092       */
093      @RunsInCurrentThread
094      public Point blockLocationToScrollDown(JScrollBar scrollBar) {
095        Point p = unitLocationToScrollDown(scrollBar);
096        int offset = -BLOCK_OFFSET;
097        return blockLocation(scrollBar, p, offset);
098      }
099    
100      @RunsInCurrentThread
101      private Point blockLocation(JScrollBar scrollBar, Point unitLocation, int offset) {
102        return locationStrategyFor(scrollBar).blockLocation(scrollBar, unitLocation, offset);
103      }
104    
105      /**
106       * Returns the location where to move the mouse pointer to scroll one unit up (or right.)
107       * <p>
108       * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
109       * responsible for calling this method from the EDT.
110       * </p>
111       * @param scrollBar the target <code>JScrollBar</code>.
112       * @return the location where to move the mouse pointer to scroll one unit up (or right.)
113       */
114      @RunsInCurrentThread
115      public Point unitLocationToScrollUp(JScrollBar scrollBar) {
116        int arrow = locationStrategyFor(scrollBar).arrow(scrollBar);
117        return new Point(arrow / 2, arrow / 2);
118      }
119    
120      /**
121       * Returns the location where to move the mouse pointer to scroll one unit down (or left.)
122       * <p>
123       * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
124       * responsible for calling this method from the EDT.
125       * </p>
126       * @param scrollBar the target <code>JScrollBar</code>.
127       * @return the location where to move the mouse pointer to scroll one unit down (or left.)
128       */
129      @RunsInCurrentThread
130      public Point unitLocationToScrollDown(JScrollBar scrollBar) {
131        return locationStrategyFor(scrollBar).unitLocationToScrollDown(scrollBar);
132      }
133    
134      @RunsInCurrentThread
135      private JScrollBarLocationStrategy locationStrategyFor(JScrollBar scrollBar) {
136        return LOCATIONS.get(scrollBar.getOrientation());
137      }
138    }