001    /*
002     * Created on Jan 27, 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 javax.swing.SwingConstants.HORIZONTAL;
019    import static javax.swing.SwingConstants.VERTICAL;
020    
021    import java.awt.Insets;
022    import java.awt.Point;
023    import java.util.HashMap;
024    import java.util.Map;
025    
026    import javax.swing.JSlider;
027    
028    import org.fest.swing.annotation.RunsInCurrentThread;
029    
030    /**
031     * Understands a location in a <code>{@link JSlider}</code>.
032     *
033     * @author Alex Ruiz
034     * @author Yvonne Wang
035     */
036    public final class JSliderLocation {
037    
038      private static final Map<Integer, JSliderLocationStrategy> LOCATIONS = new HashMap<Integer, JSliderLocationStrategy>();
039    
040      static {
041        LOCATIONS.put(HORIZONTAL, new JSliderHorizontalLocation());
042        LOCATIONS.put(VERTICAL, new JSliderVerticalLocation());
043      }
044    
045      /**
046       * Returns the coordinates of the given value in the given <code>{@link JSlider}</code>.
047       * <p>
048       * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
049       * responsible for calling this method from the EDT.
050       * </p>
051       * @param slider the given <code>JSlider</code>.
052       * @param value the given value.
053       * @return the coordinates of the given value in the given <code>JSlider</code>.
054       */
055      @RunsInCurrentThread
056      public Point pointAt(JSlider slider, int value) {
057        return LOCATIONS.get(slider.getOrientation()).locationForValue(slider, value);
058      }
059    
060      private static class JSliderHorizontalLocation extends JSliderLocationStrategy {
061        @RunsInCurrentThread
062        int max(JSlider slider, Insets insets) {
063          return slider.getWidth() - insets.left - insets.right - 1;
064        }
065    
066        @RunsInCurrentThread
067        Point update(Point center, int coordinate) {
068          return new Point(coordinate, center.y);
069        }
070      }
071    
072      private static class JSliderVerticalLocation extends JSliderLocationStrategy {
073        @RunsInCurrentThread
074        int max(JSlider slider, Insets insets) {
075          return slider.getHeight() - insets.top - insets.bottom - 1;
076        }
077    
078        @RunsInCurrentThread
079        Point update(Point center, int coordinate) {
080          return new Point(center.x, coordinate);
081        }
082      }
083    
084      private static abstract class JSliderLocationStrategy {
085        @RunsInCurrentThread
086        final Point locationForValue(JSlider slider, int value) {
087          Point center = new Point(slider.getWidth() / 2, slider.getHeight() / 2);
088          int max = max(slider, slider.getInsets());
089          int coordinate = (int)(percent(slider, value) * max);
090          if (!slider.getInverted()) coordinate = max - coordinate;
091          return update(center, coordinate);
092        }
093    
094        @RunsInCurrentThread
095        abstract int max(JSlider slider, Insets insets);
096    
097        @RunsInCurrentThread
098        abstract Point update(Point center, int coordinate);
099    
100        @RunsInCurrentThread
101        private float percent(JSlider slider, int value) {
102          int minimum = slider.getMinimum();
103          int range = slider.getMaximum() - minimum;
104          return (float)(value - minimum) / range;
105        }
106      }
107    }