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