001 /*
002 * $Id: HydraRGBDisplayable.java,v 1.13 2012/02/19 17:35:42 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2012
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 *
012 * All Rights Reserved
013 *
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.
016 *
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 *
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
025 * GNU Lesser Public License for more details.
026 *
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program. If not, see http://www.gnu.org/licenses.
029 */
030
031 package edu.wisc.ssec.mcidasv.data.hydra;
032
033 import java.rmi.RemoteException;
034
035 import java.util.Iterator;
036
037 import java.awt.Color;
038
039 import ucar.unidata.beans.*;
040
041 import visad.*;
042
043 import ucar.visad.display.DisplayMaster;
044 import ucar.visad.display.Displayable;
045 import ucar.visad.display.DisplayableData;
046 import ucar.visad.display.ScalarMapSet;
047 import ucar.unidata.util.Range;
048
049 import visad.RealType;
050 import visad.ScalarMap;
051 import visad.BadMappingException;
052 import visad.LocalDisplay;
053 import visad.DataReference;
054 import visad.VisADException;
055 import visad.UnimplementedException;
056 import visad.bom.ImageRendererJ3D;
057 import visad.java3d.DefaultRendererJ3D;
058 import java.rmi.RemoteException;
059
060 import java.util.ArrayList;
061 import java.util.Hashtable;
062 import java.util.List;
063 import java.util.Iterator;
064
065 import edu.wisc.ssec.mcidasv.control.HydraControl;
066 import edu.wisc.ssec.mcidasv.control.MultiSpectralControl;
067
068
069 public class HydraRGBDisplayable extends DisplayableData {
070
071 /**
072 * The name of the "color palette" property.
073 */
074 public static final String COLOR_PALETTE = "colorPalette";
075
076 /**
077 * The name of the "RGB real-type" property.
078 */
079 public static final String RGB_REAL_TYPE = "rgbRealType";
080
081 /**
082 * The polygon fill style
083 */
084 public static final int POLYGON_FILL = 0;
085
086 /**
087 * The polygon line style
088 */
089 public static final int POLYGON_LINE = 1;
090
091 /**
092 * The polygon point style
093 */
094 public static final int POLYGON_POINT = 2;
095
096 /**
097 * Color Palette
098 */
099 private float[][] colorPalette = null;
100
101 /** color ScalarMap */
102 private volatile ScalarMap colorMap;
103
104 /** field index to Animation ScalarMap */
105 private volatile ScalarMap animMap;
106
107 /** control for ScalarMap */
108 private volatile BaseColorControl colorControl;
109
110 /** RealType for the ScalarMap */
111 private volatile RealType rgbRealType;
112
113 /** RealType for the SelectRange ScalarMap */
114 private ScalarMap selectMap = null;
115
116 /** RealType for the Animation ScalarMap */
117 private RealType indexRealType;
118
119 /** Control for select range */
120 private RangeControl selectControl;
121
122 /** RealType for the SelectRange ScalarMap */
123 private RealType selectRealType = null;
124
125 /** flag for whether alpha is used or not */
126 private boolean alphaflag;
127
128 /** local point size */
129 private float myPointSize;
130
131 /** low range for colors */
132 //private double lowRange = 315; // low range for scalarmap
133 private double lowRange = Double.NaN; // low range for scalarmap
134
135 /** high range for colors */
136 //private double highRange = 230; // high range for scalarmap
137 private double highRange = Double.NaN; // high range for scalarmap
138
139 /** default polygonMode */
140 private int polygonMode = POLYGON_FILL;
141
142 /** default curvedSize */
143 private int curvedSize = 10;
144
145 /** low range for select */
146 private double lowSelectedRange = Double.NaN; // low range for scalarmap
147
148 /** high range for select */
149 private double highSelectedRange = Double.NaN; // high range for scalarmap
150
151 /** low range for select map */
152 private double minSelect = Double.NaN; // low range for scalarmap
153
154 /** high range for select map */
155 private double maxSelect = Double.NaN; // high range for scalarmap
156
157 private HydraControl multiSpecCntrl;
158
159 private boolean useDefaultRenderer = false;
160
161 /**
162 * Constructs from a name for the Displayable and the type of the
163 * RGB parameter.
164 *
165 * @param name The name for the displayable.
166 * @param rgbRealType The type of the RGB parameter. May be
167 * <code>null</code>.
168 * @param alphaflag boolean - will use Display.RBGA if true
169 * otherwise only Display.RGB
170 * @throws VisADException VisAD failure.
171 * @throws RemoteException Java RMI failure.
172 */
173 public HydraRGBDisplayable(String name, RealType rgbRealType, RealType indexRealType, boolean alphaflag,
174 HydraControl multiSpecCntrl)
175 throws VisADException, RemoteException {
176 this(name, rgbRealType, indexRealType, null, alphaflag, multiSpecCntrl);
177 }
178
179 /**
180 * Constructs from a name for the Displayable and the type of the
181 * RGB parameter.
182 *
183 * @param name The name for the displayable.
184 * @param rgbRealType The type of the RGB parameter. May be
185 * <code>null</code>.
186 * @param colorPalette The initial colorPalette to use. May be
187 * <code>null</code> (Vis5D palette used
188 * as default).
189 * @param alphaflag boolean - use Display.RBGA if true
190 * @throws VisADException VisAD failure.
191 * @throws RemoteException Java RMI failure.
192 */
193 public HydraRGBDisplayable(String name, RealType rgbRealType, RealType indexRealType, float[][] colorPalette, boolean alphaflag,
194 HydraControl multiSpecCntrl)
195 throws VisADException, RemoteException {
196
197 super(name);
198
199 this.rgbRealType = rgbRealType;
200 this.selectRealType = rgbRealType;
201 this.indexRealType = indexRealType;
202 this.colorPalette = colorPalette;
203 this.alphaflag = alphaflag;
204 this.multiSpecCntrl = multiSpecCntrl;
205
206 if (rgbRealType != null) {
207 setColorMaps();
208 if (useDisplayUnitForColor()) {
209 setDisplayUnit(rgbRealType.getDefaultUnit());
210 } else {
211 setColorUnit(rgbRealType.getDefaultUnit());
212 }
213 }
214
215 if (indexRealType != null) {
216 //-setAnimationMap();
217 setSelectMap();
218 }
219
220 if (selectRealType != null) {
221 //setSelectMaps();
222 }
223 }
224
225 /**
226 * Does this object use the displayUnit (or the colorUnit) for its
227 * display unit. The default is true. This allows derived classes
228 * to have this class use the colorUnit.
229 * @return true if the display unit is the same as the color unit
230 */
231 protected boolean useDisplayUnitForColor() {
232 return true;
233 }
234
235
236 /**
237 * Constructs from another instance. The following attributes are set from
238 * the other instance: color palette, the color RealType.
239 * @param that The other instance.
240 * @throws VisADException VisAD failure.
241 * @throws RemoteException Java RMI failure.
242 */
243 protected HydraRGBDisplayable(HydraRGBDisplayable that)
244 throws VisADException, RemoteException {
245
246 super(that);
247 colorPalette = that.colorPalette;
248 rgbRealType = that.rgbRealType; // immutable object
249 alphaflag = that.alphaflag;
250
251 if (rgbRealType != null) {
252 setColorMaps();
253 }
254 }
255
256 /**
257 * Sets the RealType of the RGB parameter.
258 * @param realType The RealType of the RGB parameter. May
259 * not be <code>null</code>.
260 * @throws VisADException VisAD failure.
261 * @throws RemoteException Java RMI failure.
262 */
263 public void setRGBRealType(RealType realType)
264 throws RemoteException, VisADException {
265
266 if ( !realType.equals(rgbRealType)) {
267 RealType oldValue = rgbRealType;
268 rgbRealType = realType;
269 setColorMaps();
270 if (useDisplayUnitForColor()) {
271 if ( !isUnitCompatible(rgbRealType, getDisplayUnit())) {
272 setDisplayUnit(null);
273 }
274 } else {
275 if ( !isUnitCompatible(rgbRealType, getColorUnit())) {
276 setColorUnit(null);
277 }
278 }
279 firePropertyChange(RGB_REAL_TYPE, oldValue, rgbRealType);
280 }
281 }
282
283 public ScalarMap getColorMap() {
284 return colorMap;
285 }
286
287 public ScalarMap getAnimationMap() {
288 return animMap;
289 }
290
291
292 /**
293 * Returns the RealType of the RGB parameter.
294 * @return The RealType of the color parameter. May
295 * be <code>null</code>.
296 */
297 public RealType getRGBRealType() {
298 return rgbRealType;
299 }
300
301 /**
302 * Returns the RealType of the SelectRange parameter.
303 * @return The RealType of the select range parameter. May
304 * be <code>null</code>.
305 */
306 public RealType getSelectRealType() {
307 return selectRealType;
308 }
309
310 protected DataRenderer getDataRenderer() throws VisADException {
311 if (useDefaultRenderer) {
312 return new DefaultRendererJ3D();
313 }
314 else {
315 return new ImageRendererJ3D();
316 }
317 }
318
319 public void setDefaultRenderer() {
320 useDefaultRenderer = true;
321 }
322
323 public void setImageRenderer() {
324 useDefaultRenderer = false;
325 }
326
327 /**
328 * Sets the set of ScalarMap-s of this instance. The ScalarMap-s of
329 * this instance will be added to the set before the SCALAR_MAP_SET
330 * property is set. This method fires a PropertyChangeEvent for
331 * SCALAR_MAP_SET with <code>null</code> for the old value and the new
332 * set of ScalarMap-s for the new Value. Intermediate subclasses that
333 * have their own ScalarMap-s should override this method and invoke
334 * <code>super.setScalarMaps(ScalarMapSet)</code>.
335 * @param maps The set of ScalarMap-s to be added.
336 * @throws BadMappingException The RealType of the color parameter
337 * has not been set or its ScalarMap is alread in
338 * the set.
339 */
340 protected void setScalarMaps(ScalarMapSet maps)
341 throws BadMappingException {
342
343 if (colorMap == null) {
344 throw new BadMappingException(getClass().getName()
345 + ".setScalarMaps(ScalarMapSet): "
346 + "Color not yet set");
347 }
348
349 maps.add(colorMap);
350
351 if (selectMap != null) {
352
353 maps.add(selectMap);
354 }
355
356 super.setScalarMapSet(maps);
357 }
358
359 /**
360 * This method sets the color palette
361 * according to the color table in argument;
362 * pair this method with setRange(lo,high) to get
363 * a fixed association of color table and range of values.
364 *
365 * @param colorPalette the color table or color-alpha table desired
366 * @throws VisADException if a core VisAD failure occurs.
367 * @throws RemoteException if a Java RMI failure occurs.
368 */
369 public void setColorPalette(float[][] colorPalette)
370 throws RemoteException, VisADException {
371 if (colorControl != null) {
372 colorControl.setTable(colorPalette);
373 }
374
375 this.colorPalette = colorPalette;
376 }
377
378 /**
379 * Return the current color palette in this Displayable
380 *
381 * @return a color table float[3][len] or color-alpha table float[4][len]
382 */
383 public float[][] getColorPalette() {
384 return colorPalette;
385 }
386
387 /**
388 * Make a color palette representing this color and set it as the
389 * color pallete.
390 *
391 * @param color color to use
392 * @throws VisADException VisAD failure.
393 * @throws RemoteException Java RMI failure.
394 */
395 public void setColor(Color color) throws RemoteException, VisADException {
396 int len = 5;
397 float[][] table = new float[(alphaflag == true)
398 ? 4
399 : 3][len];
400 for (int m = 0; m < len; m++) {
401 table[0][m] = color.getRed() / 255.f; // Red amount
402 table[1][m] = color.getGreen() / 255.f; // Green
403 table[2][m] = color.getBlue() / 255.f; // Blue
404 }
405 setColorPalette(table);
406 }
407
408 /**
409 * This method sets the color palette to shades of grey.
410 *
411 * @throws VisADException if a core VisAD failure occurs.
412 * @throws RemoteException if a Java RMI failure occurs.
413 */
414 public final void setGreyPalette()
415 throws RemoteException, VisADException {
416
417 if (colorControl != null) {
418 colorControl.initGreyWedge();
419 setColorPalette(colorControl.getTable());
420 }
421 }
422
423 /**
424 * This method with no argument sets the default Vis5D color spectrum.
425 *
426 * @throws VisADException if a core VisAD failure occurs.
427 * @throws RemoteException if a Java RMI failure occurs.
428 */
429 public final void setVisADPalette()
430 throws RemoteException, VisADException {
431
432 if (colorControl != null) {
433 colorControl.initVis5D();
434 setColorPalette(colorControl.getTable());
435 }
436 }
437
438 /**
439 * Set the upper and lower limit of the range values associated
440 * with a color table.
441 *
442 * @param low the minimun value
443 * @param hi the maximum value
444 * @deprecated use setRangeForColor
445 *
446 * @throws RemoteException Java RMI error
447 * @throws VisADException problem creating VisAD object
448 */
449 public void setRange(double low, double hi)
450 throws VisADException, RemoteException {
451
452 setRangeForColor(low, hi);
453 }
454
455 /**
456 * Set the upper and lower limit of the range values associated
457 * with a color table.
458 *
459 * Matches method name in Contour2DDisplayable
460 *
461 * @param low The minimum value of the parameter matched to
462 * the low end of the color table.
463 * @param hi The maximum value of the parameter matched to
464 * the high end of the color table.
465 *
466 * @exception VisADException VisAD failure.
467 * @exception RemoteException Java RMI failure.
468 */
469 public void setRangeForColor(double low, double hi)
470 throws VisADException, RemoteException {
471 lowRange = low;
472 highRange = hi;
473 if ((colorMap != null) && hasRange()) {
474 colorMap.setRange(low, hi);
475 }
476 }
477
478 /**
479 * Get the color range
480 *
481 * @return an array of the low and high values for the range
482 * @deprecated use #getRangeForColor()
483 */
484 public double[] getRangeforColor() {
485 return getRangeForColor();
486 }
487
488 /**
489 * Get the color range
490 *
491 * @return an array of the low and high values for the range
492 */
493 public double[] getRangeForColor() {
494 return new double[]{ lowRange, highRange };
495 }
496
497 /**
498 * Apply the correct unit (either the displayUnit or the colorUnit)
499 * to the scalar map
500 *
501 * @param colorMap ScalarMap to apply to
502 * @param rgbRealType RealType for default Unit
503 *
504 * @throws RemoteException Java RMI error
505 * @throws VisADException problem creating VisAD object
506 */
507 private void applyUnit(ScalarMap colorMap, RealType rgbRealType)
508 throws VisADException, RemoteException {
509 if (useDisplayUnitForColor()) {
510 applyDisplayUnit(colorMap, rgbRealType);
511 } else {
512 applyColorUnit(colorMap, rgbRealType);
513 }
514 }
515
516
517 /**
518 * Set the units for the displayed range
519 *
520 * @param unit Unit for display
521 *
522 * @throws RemoteException Java RMI error
523 * @throws VisADException problem creating VisAD object
524 */
525 public void setDisplayUnit(Unit unit)
526 throws VisADException, RemoteException {
527 if (useDisplayUnitForColor()) {
528 //Make sure this unit is ok
529 checkUnit(rgbRealType, unit);
530 }
531 super.setDisplayUnit(unit);
532 if (useDisplayUnitForColor()) {
533 applyUnit(colorMap, rgbRealType);
534 }
535 }
536
537
538 /**
539 * Set the units for the displayed range
540 *
541 * @param unit Unit for display
542 *
543 * @throws RemoteException Java RMI error
544 * @throws VisADException problem creating VisAD object
545 */
546 public void setColorUnit(Unit unit)
547 throws VisADException, RemoteException {
548 if ( !useDisplayUnitForColor()) {
549 //Make sure this unit is ok
550 checkUnit(rgbRealType, unit);
551 }
552 super.setColorUnit(unit);
553 if ( !useDisplayUnitForColor()) {
554 applyUnit(colorMap, rgbRealType);
555 }
556 }
557
558
559 /**
560 * Returns whether this Displayable has a valid range (i.e., lowRange and
561 * highRange are both not NaN's
562 *
563 * @return true if range has been set
564 */
565 public boolean hasRange() {
566 return ( !Double.isNaN(lowRange) && !Double.isNaN(highRange));
567 }
568
569
570 /**
571 * Sets the size of points in this Displayable.
572 *
573 * @param pointSize Size of points (2 = normal)
574 *
575 * @throws VisADException VisAD failure.
576 * @throws RemoteException Java RMI failure.
577 */
578 public void setPointSize(float pointSize)
579 throws VisADException, RemoteException {
580
581 float oldValue;
582
583 synchronized (this) {
584 oldValue = myPointSize;
585
586 addConstantMap(new ConstantMap(pointSize, Display.PointSize));
587
588 myPointSize = pointSize;
589 }
590
591 }
592
593 /**
594 * Gets the point size associated with this LineDrawing
595 *
596 * @return point size
597 */
598 public float getPointSize() {
599 return myPointSize;
600 }
601
602 /**
603 * Set the type of polygon display that should be used
604 *
605 * @param polygonMode polygon mode
606 *
607 * @throws RemoteException Java RMI error
608 * @throws VisADException problem creating VisAD object
609 */
610 public void setPolygonMode(int polygonMode)
611 throws VisADException, RemoteException {
612 this.polygonMode = polygonMode;
613 addConstantMap(new ConstantMap(convertToVisADPolygonMode(polygonMode),
614 Display.PolygonMode));
615 }
616
617 /**
618 * Converts an RGBDisplayable Polygon mode to the appropriate
619 * (or default) VisAD mode
620 *
621 * @param myMode polygon mode
622 * @return Java3D mode
623 */
624 private int convertToVisADPolygonMode(int myMode) {
625 if (visad.util.Util.canDoJava3D()) {
626 switch (myMode) {
627
628 case POLYGON_FILL :
629 return visad.java3d.DisplayImplJ3D.POLYGON_FILL;
630
631 case POLYGON_LINE :
632 return visad.java3d.DisplayImplJ3D.POLYGON_LINE;
633
634 case POLYGON_POINT :
635 return visad.java3d.DisplayImplJ3D.POLYGON_POINT;
636
637 default :
638 return visad.java3d.DisplayImplJ3D.POLYGON_FILL;
639 }
640 } else {
641 return 0;
642 }
643 }
644
645 /**
646 * Return the type of polygon mode being used
647 *
648 * @return polygon mode
649 */
650 public int getPolygonMode() {
651 return polygonMode;
652 }
653
654 /**
655 * Set the curved size for textured displays
656 *
657 * @param curvedSize size to use (> 0)
658 *
659 * @throws RemoteException Java RMI error
660 * @throws VisADException problem creating VisAD object
661 */
662 public void setCurvedSize(int curvedSize)
663 throws VisADException, RemoteException {
664 this.curvedSize = curvedSize;
665 addConstantMap(makeCurvedSizeMap(curvedSize));
666 }
667
668 /**
669 * Create the ConstantMap for the texture curve size
670 *
671 * @param curvedSize size for texture curve
672 * @return ConstantMap
673 *
674 * @throws RemoteException Java RMI error
675 * @throws VisADException problem creating VisAD object
676 */
677 protected ConstantMap makeCurvedSizeMap(int curvedSize)
678 throws VisADException, RemoteException {
679 return new ConstantMap(curvedSize, Display.CurvedSize);
680 }
681
682 /**
683 * Return the size of a curved texture
684 * @return curved size
685 */
686 public int getCurvedSize() {
687 return curvedSize;
688 }
689
690 /**
691 * creates the ScalarMap for color and ColorControl for this Displayable.
692 *
693 * @throws VisADException VisAD failure.
694 * @throws RemoteException Java RMI failure.
695 */
696 private void setColorMaps() throws RemoteException, VisADException {
697
698 // ScalarMap is either mapping to Display.RGB (color only)
699 // or to Display.RGBA color plus transparency.
700 if ( !alphaflag) {
701 colorMap = new ScalarMap(rgbRealType, Display.RGB);
702 } else {
703 colorMap = new ScalarMap(rgbRealType, Display.RGBA);
704 }
705
706 applyUnit(colorMap, rgbRealType);
707
708 if (hasRange()) {
709 colorMap.setRange(lowRange, highRange);
710 }
711
712 colorMap.addScalarMapListener(new ScalarMapListener() {
713
714 public void controlChanged(ScalarMapControlEvent event)
715 throws RemoteException, VisADException {
716
717 int id = event.getId();
718
719 if ((id == event.CONTROL_ADDED)
720 || (id == event.CONTROL_REPLACED)) {
721 colorControl = (BaseColorControl) colorMap.getControl();
722
723 if (colorControl != null) {
724 if (colorPalette != null) {
725 colorControl.setTable(colorPalette);
726 } else {
727 colorPalette = colorControl.getTable();
728 }
729 }
730 }
731 }
732
733 public void mapChanged(ScalarMapEvent event)
734 throws RemoteException, VisADException {
735 if ((event.getId() == event.AUTO_SCALE) && hasRange()) {
736 double[] rng = colorMap.getRange();
737 if (multiSpecCntrl != null) {
738 multiSpecCntrl.updateRange(new Range(rng));
739 }
740 }
741 }
742 });
743 ScalarMapSet maps = getScalarMapSet(); //new ScalarMapSet();
744 maps.add(colorMap);
745 setScalarMapSet(maps);
746 }
747
748 private void setAnimationMap() throws RemoteException, VisADException {
749 animMap = new ScalarMap(indexRealType, Display.Animation);
750 ScalarMapSet maps = getScalarMapSet();
751 maps.add(animMap);
752 setScalarMapSet(maps);
753 }
754
755 private void setSelectMap() throws RemoteException, VisADException {
756 animMap = new ScalarMap(indexRealType, Display.SelectValue);
757 ScalarMapSet maps = getScalarMapSet();
758 maps.add(animMap);
759 setScalarMapSet(maps);
760 }
761
762 /**
763 * Sets the RealType of the select parameter.
764 * @param realType The RealType of the RGB parameter. May
765 * not be <code>null</code>.
766 * @throws VisADException VisAD failure.
767 * @throws RemoteException Java RMI failure.
768 */
769 protected void setSelectRealType(RealType realType)
770 throws RemoteException, VisADException {
771
772 if ( !realType.equals(selectRealType)) {
773 RealType oldValue = selectRealType;
774 selectRealType = realType;
775 setSelectMaps();
776 if (useDisplayUnitForColor()) {
777 if ( !isUnitCompatible(selectRealType, getDisplayUnit())) {
778 setDisplayUnit(null);
779 }
780 } else {
781 if ( !isUnitCompatible(selectRealType, getColorUnit())) {
782 setColorUnit(null);
783 }
784 }
785 }
786 }
787
788 /**
789 * Returns whether this Displayable has a valid range
790 * (i.e., lowSelectedRange and highSelectedRange are both not NaN's
791 *
792 * @return true if range has been set
793 */
794 public boolean hasSelectedRange() {
795 return ( !Double.isNaN(lowSelectedRange)
796 && !Double.isNaN(highSelectedRange));
797 }
798
799 /**
800 * Set selected range with the range for select
801 *
802 * @param low low select value
803 * @param hi hi select value
804 *
805 * @throws RemoteException Java RMI error
806 * @throws VisADException problem creating VisAD object
807 */
808 public void setSelectedRange(double low, double hi)
809 throws VisADException, RemoteException {
810
811 lowSelectedRange = low;
812 highSelectedRange = hi;
813 if ((selectControl != null) && hasSelectedRange()) {
814 selectControl.setRange(new double[]{ low, hi });
815 }
816
817 }
818
819 /**
820 * Set the upper and lower limit of the range values associated
821 * with a color table.
822 *
823 * @param low the minimun value
824 * @param hi the maximum value
825 *
826 * @throws RemoteException Java RMI error
827 * @throws VisADException problem creating VisAD object
828 */
829 public void setRangeForSelect(double low, double hi)
830 throws VisADException, RemoteException {
831
832 minSelect = low;
833 maxSelect = hi;
834 if ((selectMap != null) && hasSelectMinMax()) {
835 selectMap.setRange(low, hi);
836 }
837 }
838
839 /**
840 * Check to see if the range has been set for the select
841 *
842 * @return true if it has
843 */
844 private boolean hasSelectMinMax() {
845 return ( !Double.isNaN(minSelect) && !Double.isNaN(maxSelect));
846 }
847
848 /**
849 * creates the ScalarMap for SelectRange and control for this Displayable.
850 *
851 * @throws VisADException VisAD failure.
852 * @throws RemoteException Java RMI failure.
853 */
854 private void setSelectMaps() throws RemoteException, VisADException {
855
856 selectMap = new ScalarMap(selectRealType, Display.SelectRange);
857
858 if (selectRealType.equals(rgbRealType)) {
859 applyUnit(selectMap, selectRealType);
860 }
861
862 if (hasSelectMinMax()) {
863 selectMap.setRange(minSelect, maxSelect);
864 }
865
866 selectMap.addScalarMapListener(new ScalarMapListener() {
867
868 public void controlChanged(ScalarMapControlEvent event)
869 throws RemoteException, VisADException {
870
871 int id = event.getId();
872
873 if ((id == event.CONTROL_ADDED)
874 || (id == event.CONTROL_REPLACED)) {
875 selectControl = (RangeControl) selectMap.getControl();
876 if (hasSelectedRange()) {
877 selectControl.setRange(new double[]{ lowSelectedRange,
878 highSelectedRange });
879 }
880 }
881 }
882
883 public void mapChanged(ScalarMapEvent event)
884 throws RemoteException, VisADException {
885 if ((event.getId() == event.AUTO_SCALE)
886 && hasSelectMinMax()) {
887 selectMap.setRange(minSelect, maxSelect);
888 }
889 }
890 });
891 ScalarMapSet maps = getScalarMapSet(); //new ScalarMapSet();
892 maps.add(selectMap);
893 setScalarMapSet(maps);
894 }
895
896 }