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 }