1
2 package hep.wired.util;
3
4 import javax.swing.*;
5 import javax.swing.event.*;
6
7
8 /***
9 * Like DefaultBoundedRangeModel but for double values.
10 *
11 * @author Mark Donszelmann
12 * @version $Id: DefaultBoundedDoubleRangeModel.java 1988 2005-06-30 00:05:07Z duns $
13 */
14 public class DefaultBoundedDoubleRangeModel extends DefaultBoundedRangeModel implements BoundedDoubleRangeModel {
15
16 private static final int bins = 10000;
17
18 private double minimum;
19 private double maximum;
20 private double def;
21 private boolean log;
22
23 private double factor;
24 private double logFactor;
25
26 public DefaultBoundedDoubleRangeModel(double value, double extent, double min, double max, boolean log) {
27 super(0, 0, 0, bins);
28
29 if ((max >= min) &&
30 (value >= min) &&
31 ((value + extent) >= value) &&
32 ((value + extent) <= max)) {
33
34 setRangeProperties(value, extent, min, max, false, log);
35 }
36 else {
37 throw new IllegalArgumentException("invalid range properties");
38 }
39
40 def = value;
41 }
42
43 public boolean isLogarithmic() {
44 return log;
45 }
46
47 public boolean canBeLogarithmic() {
48 return getMinimumDouble()*getMaximumDouble() > 0;
49 }
50
51 public void setLogarithmic(boolean log) {
52 setRangeProperties(getValue(), getExtentDouble(), minimum, maximum, getValueIsAdjusting(), log);
53 }
54
55 public double getMinimumDouble() {
56 return minimum;
57 }
58
59 public void setMinimum(double min) {
60 double newMax = Math.max(min, maximum);
61 double newValue = Math.max(min, getValueDouble());
62 double newExtent = Math.min(newMax - newValue, getExtentDouble());
63 setRangeProperties(newValue, newExtent, min, newMax, getValueIsAdjusting(), log);
64 }
65
66 public double getMaximumDouble() {
67 return maximum;
68 }
69
70 public void setMaximum(double max) {
71 double newMin = Math.min(max, minimum);
72 double newExtent = Math.min(max - newMin, getExtentDouble());
73 double newValue = Math.min(max - newExtent, getValueDouble());
74 setRangeProperties(newValue, newExtent, newMin, max, getValueIsAdjusting(), log);
75 }
76
77 public double getValueDouble() {
78 return getValueAt(super.getValue());
79 }
80
81 public double getValueAt(int bin) {
82 return log ? pow10(bin * logFactor + log10(minimum)) : (bin * factor) + minimum;
83 }
84
85 public void setValue(double value) {
86 double newValue = Math.max(value, minimum);
87 if (newValue + getExtentDouble() > maximum) {
88 newValue = maximum - getExtentDouble();
89 }
90 setRangeProperties(newValue, getExtentDouble(), minimum, maximum, getValueIsAdjusting(), log);
91 }
92
93 public double getExtentDouble() {
94 return super.getExtent() * getFactor();
95 }
96
97 public void setExtent(double extent) {
98 double newExtent = Math.max(0, extent);
99 if (getValueDouble() + newExtent > maximum) {
100 newExtent = maximum - getValueDouble();
101 }
102 setRangeProperties(getValueDouble(), newExtent, minimum, maximum, getValueIsAdjusting(), log);
103 }
104
105 public double getDefaultValueDouble() {
106 return def;
107 }
108
109 public void setDefaultValue(double def) {
110 this.def = def;
111 }
112
113 public void setRangeProperties(double newValue, double newExtent, double newMin, double newMax, boolean newAdjusting, boolean newLog) {
114 System.err.println("Range: "+newValue+" "+newExtent+" "+newMin+" "+newMax+" "+newAdjusting+" "+newLog);
115
116 if (newMin > newMax) {
117 newMin = newMax;
118 }
119 if (newValue > newMax) {
120 newMax = newValue;
121 }
122 if (newValue < newMin) {
123 newMin = newValue;
124 }
125 if ((newExtent + newValue) > newMax) {
126 newExtent = newMax - newValue;
127 }
128 if (newExtent < 0) {
129 newExtent = 0;
130 }
131
132 boolean fire = (newMin != minimum) ||
133 (newMax != maximum) ||
134 (newLog != log);
135 if (fire) {
136 minimum = newMin;
137 maximum = newMax;
138
139 if (log && !canBeLogarithmic()) {
140 throw new IllegalArgumentException("min and max need to be on the same side of zero for a log slider and cannot be zero ("+getMinimumDouble()+", "+getMaximumDouble()+")");
141 }
142 log = newLog;
143
144 double range = maximum - minimum;
145 factor = range / bins;
146 logFactor = (log10(maximum) - log10(minimum)) / bins;
147 System.err.println("Factor: "+factor+" "+logFactor);
148 }
149
150 boolean isChange = (newValue != getValueDouble()) ||
151 (newExtent != getExtentDouble()) ||
152 (newAdjusting != getValueIsAdjusting());
153 if (isChange) {
154 System.err.println(newValue+" "+minimum);
155 int intValue = log ? (int)(((log10(newValue) - log10(minimum)) / logFactor)) : (int)((newValue - minimum) / factor);
156 int intExtent = (int)(newExtent / getFactor());
157 System.err.println(intValue+" "+intExtent);
158 super.setRangeProperties(intValue, intExtent, getMinimum(), getMaximum(), newAdjusting);
159 } else {
160 if (fire) fireStateChanged();
161 }
162 }
163
164 public double getFactor() {
165 return log ? logFactor : factor;
166 }
167
168
169 static double log10(double x) {
170 return Math.log(x)/Math.log(10);
171 }
172
173 static double pow10(double x) {
174 return Math.pow(10, x);
175 }
176 }