001: package prefuse.data.query;
002:
003: import javax.swing.DefaultBoundedRangeModel;
004:
005: import prefuse.util.TypeLib;
006: import prefuse.util.ui.ValuedRangeModel;
007:
008: /**
009: * Range model for numerical data. Designed to support range-based dynamic
010: * queries.
011: *
012: * @author <a href="http://jheer.org">jeffrey heer</a>
013: */
014: public class NumberRangeModel extends DefaultBoundedRangeModel
015: implements ValuedRangeModel {
016: protected Class m_type;
017: protected Number m_min, m_max, m_lo, m_hi;
018:
019: // ------------------------------------------------------------------------
020:
021: /**
022: * Create a new NumberRangeModel for the given range.
023: * @param lo the low value of the selected range
024: * @param hi the high value of the selected range
025: * @param min the minimum value allowed for ranges
026: * @param max the maximum value allowed for ranges
027: */
028: public NumberRangeModel(int lo, int hi, int min, int max) {
029: this (new Integer(lo), new Integer(hi), new Integer(min),
030: new Integer(hi));
031: }
032:
033: /**
034: * Create a new NumberRangeModel for the given range.
035: * @param lo the low value of the selected range
036: * @param hi the high value of the selected range
037: * @param min the minimum value allowed for ranges
038: * @param max the maximum value allowed for ranges
039: */
040: public NumberRangeModel(long lo, long hi, long min, long max) {
041: this (new Long(lo), new Long(hi), new Long(min), new Long(max));
042: }
043:
044: /**
045: * Create a new NumberRangeModel for the given range.
046: * @param lo the low value of the selected range
047: * @param hi the high value of the selected range
048: * @param min the minimum value allowed for ranges
049: * @param max the maximum value allowed for ranges
050: */
051: public NumberRangeModel(float lo, float hi, float min, float max) {
052: this (new Float(lo), new Float(hi), new Float(min), new Float(
053: max));
054: }
055:
056: /**
057: * Create a new NumberRangeModel for the given range.
058: * @param lo the low value of the selected range
059: * @param hi the high value of the selected range
060: * @param min the minimum value allowed for ranges
061: * @param max the maximum value allowed for ranges
062: */
063: public NumberRangeModel(double lo, double hi, double min, double max) {
064: this (new Double(lo), new Double(hi), new Double(min),
065: new Double(max));
066: }
067:
068: /**
069: * Create a new NumberRangeModel for the given range.
070: * @param lo the low value of the selected range
071: * @param hi the high value of the selected range
072: * @param min the minimum value allowed for ranges
073: * @param max the maximum value allowed for ranges
074: */
075: public NumberRangeModel(Number lo, Number hi, Number min, Number max) {
076: m_type = TypeLib.getPrimitiveType(min.getClass());
077: setValueRange(lo, hi, min, max);
078: }
079:
080: // ------------------------------------------------------------------------
081:
082: /**
083: * Update the range settings based on current values.
084: */
085: protected void updateRange() {
086: if (m_type == int.class) {
087: setRange(m_lo.intValue(),
088: m_hi.intValue() - m_lo.intValue(),
089: m_min.intValue(), m_max.intValue());
090: } else if (m_type == long.class) {
091: long range = m_max.longValue() - m_min.longValue();
092: if (range == 0) {
093: setRange(0, 0, 0, 0);
094: } else {
095: long lo = m_lo.longValue() - m_min.longValue();
096: long hi = m_hi.longValue() - m_min.longValue();
097:
098: int v = 10000 * (int) (lo / range);
099: int e = 10000 * (int) (hi / range) - v;
100: setRange(v, e, 0, 10000);
101: }
102: } else {
103: double range = m_max.doubleValue() - m_min.doubleValue();
104: if (range == 0) {
105: setRange(0, 0, 0, 0);
106: } else {
107: double lo = m_lo.doubleValue() - m_min.doubleValue();
108: double hi = m_hi.doubleValue() - m_min.doubleValue();
109:
110: int v = 10000 * (int) (lo / range);
111: int e = 10000 * (int) (hi / range) - v;
112: setRange(v, e, 0, 10000);
113: }
114: }
115: }
116:
117: /**
118: * Set the range settings in the pixel-space coordinates.
119: */
120: protected void setRange(int val, int ext, int min, int max) {
121: super .setRangeProperties(val, ext, min, max, false);
122: }
123:
124: /**
125: * @see javax.swing.BoundedRangeModel#setRangeProperties(int, int, int, int, boolean)
126: */
127: public void setRangeProperties(int val, int extent, int min,
128: int max, boolean adj) {
129: if (min != getMinimum() || max != getMaximum()) {
130: throw new IllegalArgumentException(
131: "Can not change min or max.");
132: }
133: m_lo = null;
134: m_hi = null;
135: super .setRangeProperties(val, extent, min, max, adj);
136: }
137:
138: /**
139: * Set the range model's backing values.
140: * @param lo the low value of the selected range
141: * @param hi the high value of the selected range
142: * @param min the minimum value allowed for ranges
143: * @param max the maximum value allowed for ranges
144: */
145: public void setValueRange(Number lo, Number hi, Number min,
146: Number max) {
147: m_lo = lo;
148: m_hi = hi;
149: m_min = min;
150: m_max = max;
151: updateRange();
152: }
153:
154: /**
155: * Set the range model's backing values.
156: * @param lo the low value of the selected range
157: * @param hi the high value of the selected range
158: * @param min the minimum value allowed for ranges
159: * @param max the maximum value allowed for ranges
160: */
161: public void setValueRange(double lo, double hi, double min,
162: double max) {
163: m_lo = new Double(lo);
164: m_hi = new Double(hi);
165: m_min = new Double(min);
166: m_max = new Double(max);
167: updateRange();
168: }
169:
170: /**
171: * Set the range model's backing values.
172: * @param lo the low value of the selected range
173: * @param hi the high value of the selected range
174: * @param min the minimum value allowed for ranges
175: * @param max the maximum value allowed for ranges
176: */
177: public void setValueRange(int lo, int hi, int min, int max) {
178: m_lo = new Integer(lo);
179: m_hi = new Integer(hi);
180: m_min = new Integer(min);
181: m_max = new Integer(max);
182: updateRange();
183: }
184:
185: /**
186: * Set the range model's backing values.
187: * @param lo the low value of the selected range
188: * @param hi the high value of the selected range
189: * @param min the minimum value allowed for ranges
190: * @param max the maximum value allowed for ranges
191: */
192: public void setValueRange(long lo, long hi, long min, long max) {
193: m_lo = new Long(lo);
194: m_hi = new Long(hi);
195: m_min = new Long(min);
196: m_max = new Long(max);
197: updateRange();
198: }
199:
200: /**
201: * @see prefuse.util.ui.ValuedRangeModel#getMinValue()
202: */
203: public Object getMinValue() {
204: return m_min;
205: }
206:
207: /**
208: * Set the minimum range value.
209: * @param n the minimum range value.
210: */
211: public void setMinValue(Number n) {
212: setValueRange((Number) getLowValue(), (Number) getHighValue(),
213: n, m_max);
214: }
215:
216: /**
217: * @see prefuse.util.ui.ValuedRangeModel#getMaxValue()
218: */
219: public Object getMaxValue() {
220: return m_max;
221: }
222:
223: /**
224: * Set the maximum range value.
225: * @param n the maximum range value.
226: */
227: public void setMaxValue(Number n) {
228: setValueRange((Number) getLowValue(), (Number) getHighValue(),
229: m_min, n);
230: }
231:
232: /**
233: * @see prefuse.util.ui.ValuedRangeModel#getLowValue()
234: */
235: public Object getLowValue() {
236: if (m_lo == null)
237: m_lo = (Number) value(getValue());
238: return m_lo;
239: }
240:
241: /**
242: * Set the lowest selected range value.
243: * @param n the low value of the selected range.
244: */
245: public void setLowValue(Number n) {
246: setValueRange(n, (Number) getHighValue(), m_min, m_max);
247: }
248:
249: /**
250: * @see prefuse.util.ui.ValuedRangeModel#getHighValue()
251: */
252: public Object getHighValue() {
253: if (m_hi == null)
254: m_hi = (Number) value(getValue() + getExtent());
255: return m_hi;
256: }
257:
258: /**
259: * Set the highest selected range value.
260: * @param n the high value of the selected range.
261: */
262: public void setHighValue(Number n) {
263: setValueRange((Number) getLowValue(), n, m_min, m_max);
264: }
265:
266: protected Object value(int val) {
267: int min = getMinimum();
268: int max = getMaximum();
269: if (m_type == double.class || m_type == float.class) {
270: double f = (val - min) / (double) (max - min);
271: double m = m_min.doubleValue();
272: double v = m + f * (m_max.doubleValue() - m);
273: return (m_type == float.class ? (Number) new Float(
274: (float) v) : new Double(v));
275: } else if (m_type == long.class) {
276: long m = m_min.longValue();
277: long v = m + (val - min) * (m_max.longValue() - m)
278: / (max - min);
279: return new Long(v);
280: } else {
281: return new Integer(val);
282: }
283: }
284:
285: /**
286: * Not supported, throws an exception.
287: * @throws UnsupportedOperationException
288: * @see javax.swing.BoundedRangeModel#setMinimum(int)
289: */
290: public void setMinimum(int min) {
291: throw new UnsupportedOperationException();
292: }
293:
294: /**
295: * Not supported, throws an exception.
296: * @throws UnsupportedOperationException
297: * @see javax.swing.BoundedRangeModel#setMaximum(int)
298: */
299: public void setMaximum(int max) {
300: throw new UnsupportedOperationException();
301: }
302:
303: /**
304: * @see javax.swing.BoundedRangeModel#setValue(int)
305: */
306: public void setValue(int val) {
307: m_lo = null;
308: super .setValue(val);
309: }
310:
311: /**
312: * @see javax.swing.BoundedRangeModel#setExtent(int)
313: */
314: public void setExtent(int extent) {
315: m_hi = null;
316: super .setExtent(extent);
317: }
318:
319: } // end of class NumberRangeModel
|