Merge branch 'JAL-3878_ws-overhaul-3' into with_ws_overhaul-3
[jalview.git] / src / jalview / gui / Slider.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.gui;
22
23 import javax.swing.JSlider;
24
25 /**
26  * A modified {@code javax.swing.JSlider} that
27  * <ul>
28  * <li>supports float valued numbers (by scaling up integer values)</li>
29  * <li>rescales 'true' value range to avoid negative values, as these are not
30  * rendered correctly by some look and feel libraries</li>
31  * </ul>
32  * 
33  * @author gmcarstairs
34  */
35 @SuppressWarnings("serial")
36 public class Slider extends JSlider
37 {
38   /*
39    * the number of nominal positions the slider represents
40    * (higher number = more fine-grained positioning)
41    */
42   private static final int SCALE_TICKS = 1000;
43
44   /*
45    * 'true' value corresponding to zero on the slider
46    */
47   private float trueMin;
48
49   /*
50    * 'true' value corresponding to slider maximum
51    */
52   private float trueMax;
53
54   /*
55    * scaleFactor applied to true value range to give a
56    * slider range of 0 - 100
57    */
58   private float sliderScaleFactor;
59
60   /**
61    * Constructor that rescales min - max to 0 - 100 for the slider
62    * 
63    * @param min
64    * @param max
65    * @param value
66    */
67   public Slider(float min, float max, float value)
68   {
69     super();
70     setSliderModel(min, max, value);
71   }
72
73   /**
74    * Sets the min-max range and current value of the slider, with rescaling from
75    * true values to slider range as required
76    * 
77    * @param min
78    * @param max
79    * @param value
80    */
81   public void setSliderModel(float min, float max, float value)
82   {
83     trueMin = min;
84     trueMax = max;
85     setMinimum(0);
86     sliderScaleFactor = SCALE_TICKS / (max - min);
87     int sliderMax = (int) ((max - min) * sliderScaleFactor);
88     setMaximum(sliderMax);
89     setSliderValue(value);
90   }
91
92   /**
93    * Answers the value of the slider position (descaled to 'true' value)
94    * 
95    * @return
96    */
97   public float getSliderValue()
98   {
99     /*
100      * convert slider max to 'true max' in case of rounding errors
101      */
102     int value = getValue();
103     return value == getMaximum() ? trueMax
104             : value / sliderScaleFactor + trueMin;
105   }
106
107   /**
108    * Sets the slider value (scaled from the true value to the slider range)
109    * 
110    * @param value
111    */
112   public void setSliderValue(float value)
113   {
114     setValue(Math.round((value - trueMin) * sliderScaleFactor));
115   }
116
117   /**
118    * Answers the value of the slider position as a percentage between minimum
119    * and maximum of its range
120    * 
121    * @return
122    */
123   public float getSliderPercentageValue()
124   {
125     return (getValue() - getMinimum()) * 100f
126             / (getMaximum() - getMinimum());
127   }
128
129   /**
130    * Sets the slider position for a given percentage value of its min-max range
131    * 
132    * @param pct
133    */
134   public void setSliderPercentageValue(float pct)
135   {
136     float pc = pct / 100f * getMaximum();
137     setValue((int) pc);
138   }
139 }