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