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    package edu.wisc.ssec.mcidasv.control;
029    
030    import java.awt.Container;
031    import java.awt.FlowLayout;
032    import java.awt.event.ActionEvent;
033    import java.awt.event.ActionListener;
034    import java.rmi.RemoteException;
035    import java.util.Iterator;
036    
037    import javax.swing.Box;
038    import javax.swing.JButton;
039    import javax.swing.JLabel;
040    import javax.swing.JPanel;
041    import javax.swing.JTextField;
042    
043    import net.miginfocom.swing.MigLayout;
044    
045    import ucar.unidata.data.DataChoice;
046    import ucar.unidata.data.DataSelection;
047    import ucar.unidata.idv.control.DisplayControlImpl;
048    import ucar.unidata.util.ColorTable;
049    import ucar.unidata.util.LogUtil;
050    import ucar.visad.display.DisplayMaster;
051    
052    import visad.BaseColorControl;
053    import visad.CoordinateSystem;
054    import visad.Data;
055    import visad.FieldImpl;
056    import visad.FlatField;
057    import visad.FunctionType;
058    import visad.ScalarMap;
059    import visad.ScalarMapControlEvent;
060    import visad.ScalarMapEvent;
061    import visad.ScalarMapListener;
062    import visad.VisADException;
063    import visad.georef.MapProjection;
064    
065    import edu.wisc.ssec.mcidasv.data.hydra.ImageRGBDisplayable;
066    
067    public class RGBCompositeControl extends DisplayControlImpl {
068    
069       /** Displayable for the data */
070       private ImageRGBDisplayable imageDisplay;
071    
072       private DisplayMaster displayMaster;
073    
074       private ScalarMap redMap = null;
075       private ScalarMap grnMap = null;
076       private ScalarMap bluMap = null;
077    
078       float[][] redTable = null;
079       float[][] grnTable = null;
080       float[][] bluTable = null;
081    
082       final private double[] redRange = new double[] {Double.NaN, Double.NaN};
083       final private double[] grnRange = new double[] {Double.NaN, Double.NaN};
084       final private double[] bluRange = new double[] {Double.NaN, Double.NaN};
085    
086       final double[] initRedRange = new double[] {Double.NaN, Double.NaN};
087       final double[] initGrnRange = new double[] {Double.NaN, Double.NaN};
088       final double[] initBluRange = new double[] {Double.NaN, Double.NaN};
089    
090       private FieldImpl imageField = null;
091       private MapProjection mapProjection = null;
092            
093       private double gamma = 1.0;
094    
095       private double redGamma = 1.0;
096       private double grnGamma = 1.0;
097       private double bluGamma = 1.0;
098    
099       private final JTextField gammaTxtFld =
100            new JTextField(Float.toString(1f), 4);
101       private final JTextField redGammaTxtFld =
102            new JTextField(Float.toString(1f), 4);
103       private final JTextField grnGammaTxtFld =
104            new JTextField(Float.toString(1f), 4);
105       private final JTextField bluGammaTxtFld =
106            new JTextField(Float.toString(1f), 4);
107    
108       private final JTextField redLowTxtFld =
109            new JTextField(Float.toString(1f), 10);
110       private final JTextField redHighTxtFld =
111            new JTextField(Float.toString(1f), 10);
112       private final JTextField grnLowTxtFld =
113            new JTextField(Float.toString(1f), 10);
114       private final JTextField grnHighTxtFld =
115            new JTextField(Float.toString(1f), 10);
116       private final JTextField bluLowTxtFld =
117            new JTextField(Float.toString(1f), 10);
118       private final JTextField bluHighTxtFld =
119            new JTextField(Float.toString(1f), 10);
120    
121       public RGBCompositeControl() {
122         super();
123       }
124    
125       public boolean init(DataChoice dataChoice) throws VisADException, RemoteException {
126         displayMaster = getViewManager().getMaster();
127         DataSelection dataSelection = getDataSelection();
128         imageField = (FieldImpl) dataChoice.getData(dataSelection);
129    
130    
131         imageDisplay = new ImageRGBDisplayable("rgb composite", null, false, imageField);
132    
133         Iterator iter = imageDisplay.getScalarMapSet().iterator();
134         while (iter.hasNext()) {
135             ScalarMap map = (ScalarMap) iter.next();
136             if (map.getScalarName().startsWith("redimage")) {
137                     redMap = map;
138             }
139             if (map.getScalarName().startsWith("greenimage")) {
140                     grnMap = map;
141             }
142             if (map.getScalarName().startsWith("blueimage")) {
143                     bluMap = map;
144             }
145         }
146    
147         if (checkRange()) { //- from unpersistence if true, initialize gui, ScalarMaps
148           double[] redRange = getRedRange();
149           double[] grnRange = getGrnRange();
150           double[] bluRange = getBluRange();
151    
152           initRedRange[0] = redRange[0];
153           initRedRange[1] = redRange[1];
154           initGrnRange[0] = grnRange[0];
155           initGrnRange[1] = grnRange[1];
156           initBluRange[0] = bluRange[0];
157           initBluRange[1] = bluRange[1];
158    
159           redLowTxtFld.setText(Float.toString((float)redRange[0]));
160           redHighTxtFld.setText(Float.toString((float)redRange[1]));
161           grnLowTxtFld.setText(Float.toString((float)grnRange[0]));
162           grnHighTxtFld.setText(Float.toString((float)grnRange[1]));
163           bluLowTxtFld.setText(Float.toString((float)bluRange[0]));
164           bluHighTxtFld.setText(Float.toString((float)bluRange[1]));
165       
166           gammaTxtFld.setText(Float.toString((float)gamma));
167           redGammaTxtFld.setText(Float.toString((float)redGamma));
168           grnGammaTxtFld.setText(Float.toString((float)grnGamma));
169           bluGammaTxtFld.setText(Float.toString((float)bluGamma));
170    
171           redMap.setRange(redRange[0], redRange[1]);
172           grnMap.setRange(grnRange[0], grnRange[1]);
173           bluMap.setRange(bluRange[0], bluRange[1]);
174         } 
175         else {
176           redMap.resetAutoScale();
177           grnMap.resetAutoScale();
178           bluMap.resetAutoScale();
179    
180           redMap.addScalarMapListener(new ColorMapListener(redMap, initRedRange, redRange, redLowTxtFld, redHighTxtFld));
181           grnMap.addScalarMapListener(new ColorMapListener(grnMap, initGrnRange, grnRange, grnLowTxtFld, grnHighTxtFld));
182           bluMap.addScalarMapListener(new ColorMapListener(bluMap, initBluRange, bluRange, bluLowTxtFld, bluHighTxtFld));
183         }
184    
185         setShowInDisplayList(true);
186    
187         addDisplayable(imageDisplay, FLAG_COLORTABLE);
188    
189         return true;
190       }
191    
192       public void initDone() {
193         while (true) {
194             if (null != redMap.getControl()) {
195                redTable = ((BaseColorControl) redMap.getControl()).getTable();
196                break;
197             }
198         }
199         while (true) {
200             if (null != grnMap.getControl()) {
201                 grnTable = ((BaseColorControl) grnMap.getControl()).getTable();
202                 break;
203             }
204         }
205         while (true) {
206             if (null != bluMap.getControl()) {
207                 bluTable = ((BaseColorControl) bluMap.getControl()).getTable();
208                 break;
209             }
210         } 
211    
212         float[][] newRedTbl = getZeroOutArray(redTable);
213         float[][] newGrnTbl = getZeroOutArray(grnTable);
214         float[][] newBluTbl = getZeroOutArray(bluTable);
215    
216         for (int k=0; k<redTable[0].length; k++) {
217           newRedTbl[0][k] = (float) Math.pow(redTable[0][k], redGamma);
218           newGrnTbl[1][k] = (float) Math.pow(grnTable[1][k], grnGamma);
219           newBluTbl[2][k] = (float) Math.pow(bluTable[2][k], bluGamma);
220         }
221    
222         try {
223           displayMaster.setDisplayInactive();
224           ((BaseColorControl)redMap.getControl()).setTable(newRedTbl);
225           ((BaseColorControl)grnMap.getControl()).setTable(newGrnTbl);
226           ((BaseColorControl)bluMap.getControl()).setTable(newBluTbl);
227           imageDisplay.loadData(imageField);
228           displayMaster.setDisplayActive();
229         } catch(Exception ex) {
230           LogUtil.logException("setDisplayInactive", ex);
231         }
232       }
233    
234       public MapProjection getDataProjection() {
235         CoordinateSystem cs = null;
236         try {
237           if (imageField instanceof FlatField) {
238             cs = ((FunctionType)imageField.getType()).getDomain().getCoordinateSystem();
239           } 
240           else if (imageField instanceof FieldImpl) {
241             Data dat = imageField.getSample(0, false);
242             if (dat instanceof FlatField) {
243               FlatField img = (FlatField) dat;
244               cs = ((FunctionType)img.getType()).getDomain().getCoordinateSystem();
245             }
246           }
247         }
248         catch (Exception ex) {
249           LogUtil.logException("problem accessing data", ex);
250         }
251    
252         if (cs instanceof MapProjection) mapProjection = (MapProjection) cs;
253    
254         return mapProjection;
255       }
256    
257       boolean checkRange() {
258         if (Double.isNaN(redRange[0]) || Double.isNaN(grnRange[0]) || Double.isNaN(bluRange[0])) {
259           return false;
260         }
261         else {
262           return true;
263         }
264       }
265    
266       private void updateRedRange(double lo, double hi) {
267         redRange[0] = lo;
268         redRange[1] = hi;
269         try {
270           redMap.setRange(lo, hi);
271         } catch (VisADException ex) {
272           LogUtil.logException("redMap.setRange", ex);
273         } catch (RemoteException ex) {
274           LogUtil.logException("redMap.setRange", ex);
275         }
276       }
277    
278       public void setRedRange(double[] range) {
279         redRange[0] = range[0];
280         redRange[1] = range[1];
281       }
282    
283       public double[] getRedRange() {
284         return new double[] {redRange[0], redRange[1]};
285       }
286    
287       private void updateGrnRange(double lo, double hi) {
288         grnRange[0] = lo;
289         grnRange[1] = hi;
290         try {
291           grnMap.setRange(lo, hi);
292         } catch (VisADException ex) {
293           LogUtil.logException("grnMap.setRange", ex);
294         } catch (RemoteException ex) {
295           LogUtil.logException("grnMap.setRange", ex);
296         }
297       }
298    
299       public void setGrnRange(double[] range) {
300         grnRange[0] = range[0];
301         grnRange[1] = range[1];
302       }
303    
304       public double[] getGrnRange() {
305         return new double[] {grnRange[0], grnRange[1]};
306       }
307    
308       private void updateBluRange(double lo, double hi) {
309         bluRange[0] = lo;
310         bluRange[1] = hi;
311         try {
312           bluMap.setRange(lo, hi);
313         } catch (VisADException ex) {
314           LogUtil.logException("bluMap.setRange", ex);
315         } catch (RemoteException ex) {
316           LogUtil.logException("bluMap.setRange", ex);
317         }
318       }
319    
320       public void setBluRange(double[] range) {
321         bluRange[0] = range[0];
322         bluRange[1] = range[1];
323       }
324    
325       public double[] getBluRange() {
326         return new double[] {bluRange[0], bluRange[1]};
327       }
328    
329       public void setRedGamma(double gamma) {
330         redGamma = gamma;
331       }
332    
333       public double getRedGamma() {
334         return redGamma;
335       }
336    
337       public void setGrnGamma(double gamma) {
338         grnGamma = gamma;
339       }
340    
341       public double getGrnGamma() {
342         return grnGamma;
343       }
344    
345       public void setBluGamma(double gamma) {
346         bluGamma = gamma;
347       }
348    
349       public double getBluGamma() {
350         return bluGamma;
351       }
352    
353       public void setGamma(double gamma) {
354         this.gamma = gamma;
355       }
356    
357       public double getGamma() {
358         return gamma;
359       }
360    
361       private void updateGamma(double gamma) {
362         setGamma(gamma);
363         setRedGamma(gamma);
364         setGrnGamma(gamma);
365         setBluGamma(gamma);
366         redGammaTxtFld.setText(Float.toString((float)gamma));
367         grnGammaTxtFld.setText(Float.toString((float)gamma));
368         bluGammaTxtFld.setText(Float.toString((float)gamma));
369            
370         float[][] newRedTbl = getZeroOutArray(redTable);
371         float[][] newGrnTbl = getZeroOutArray(grnTable);
372         float[][] newBluTbl = getZeroOutArray(bluTable);
373    
374         for (int k=0; k<redTable[0].length; k++) {
375           newRedTbl[0][k] = (float) Math.pow(redTable[0][k], gamma);
376           newGrnTbl[1][k] = (float) Math.pow(grnTable[1][k], gamma);
377           newBluTbl[2][k] = (float) Math.pow(bluTable[2][k], gamma);
378         }
379         try {
380           displayMaster.setDisplayInactive();
381           ((BaseColorControl)redMap.getControl()).setTable(newRedTbl);
382           ((BaseColorControl)grnMap.getControl()).setTable(newGrnTbl);
383           ((BaseColorControl)bluMap.getControl()).setTable(newBluTbl);
384           displayMaster.setDisplayActive();
385         } catch(Exception ex) {
386           LogUtil.logException("setDisplayInactive", ex);
387         }
388       }
389    
390       private void updateRedGamma(double gamma) {
391         setRedGamma(gamma);
392    
393         float[][] newRedTbl = getZeroOutArray(redTable);
394    
395         for (int k=0; k<redTable[0].length; k++) {
396           newRedTbl[0][k] = (float) Math.pow(redTable[0][k], gamma);
397         }
398    
399         try {
400           displayMaster.setDisplayInactive();
401           ((BaseColorControl)redMap.getControl()).setTable(newRedTbl);
402           displayMaster.setDisplayActive();
403         } catch(Exception ex) {
404           LogUtil.logException("setDisplayInactive", ex);
405         }
406       }
407    
408       private void updateGrnGamma(double gamma) {
409         setGrnGamma(gamma);
410    
411         float[][] newGrnTbl = getZeroOutArray(grnTable);
412         for (int k=0; k<grnTable[0].length; k++) {
413           newGrnTbl[1][k] = (float) Math.pow(grnTable[1][k], gamma);
414         }
415    
416         try {
417           displayMaster.setDisplayInactive();
418           ((BaseColorControl)grnMap.getControl()).setTable(newGrnTbl);
419           displayMaster.setDisplayActive();
420         } catch(Exception ex) {
421           LogUtil.logException("setDisplayInactive", ex);
422         }
423       }
424    
425       private void updateBluGamma(double gamma) {
426         setBluGamma(gamma);
427    
428         float[][] newBluTbl = getZeroOutArray(bluTable);
429         for (int k=0; k<bluTable[0].length; k++) {
430           newBluTbl[2][k] = (float) Math.pow(bluTable[2][k], gamma);
431         }
432    
433         try {
434           displayMaster.setDisplayInactive();
435           ((BaseColorControl)bluMap.getControl()).setTable(newBluTbl);
436           displayMaster.setDisplayActive();
437         } catch(Exception ex) {
438           LogUtil.logException("setDisplayInactive", ex);
439         }
440       }
441    
442       public float[][] getZeroOutArray(float[][] array) {
443         float[][] newArray = new float[array.length][array[0].length];
444         for (int i=0; i<newArray.length; i++) {
445           for (int j=0; j<newArray[0].length; j++) {
446             newArray[i][j] = 0f;
447           }
448         }
449         return newArray;
450       }
451    
452       protected ColorTable getInitialColorTable() {
453         return getDisplayConventions().getParamColorTable("image");
454       }
455    
456       public Container doMakeContents() {
457    
458         JButton allGammaButton = new JButton("Apply to All Gamma Fields");
459         allGammaButton.addActionListener(new ActionListener() {
460             public void actionPerformed(ActionEvent e) {
461                 String tmp = gammaTxtFld.getText().trim();
462                 updateGamma(Double.valueOf(tmp));
463             }
464         });
465    
466          gammaTxtFld.addActionListener(new ActionListener() {
467              public void actionPerformed(ActionEvent e) {
468                  String tmp = gammaTxtFld.getText().trim();
469                  updateGamma(Double.valueOf(tmp));
470              }
471          });
472       
473         redLowTxtFld.addActionListener(new ActionListener() {
474             public void actionPerformed(ActionEvent e) {
475                String tmp = redLowTxtFld.getText().trim();
476                updateRedRange(Double.valueOf(tmp), redRange[1]);
477             }
478         });
479         
480         redHighTxtFld.addActionListener(new ActionListener() {
481             public void actionPerformed(ActionEvent e) {
482                String tmp = redHighTxtFld.getText().trim();
483                updateRedRange(redRange[0], Double.valueOf(tmp));
484             }
485         });
486    
487         redGammaTxtFld.addActionListener(new ActionListener() {
488             public void actionPerformed(ActionEvent e) {
489                 String tmp = redGammaTxtFld.getText().trim();
490                 updateRedGamma(Double.valueOf(tmp));
491             }
492         });
493    
494         JButton redReset = new JButton("Reset");
495         redReset.addActionListener(new ActionListener() {
496           public void actionPerformed(ActionEvent e) {
497             updateRedRange(initRedRange[0], initRedRange[1]);
498             redRange[0] = initRedRange[0];
499             redRange[1] = initRedRange[1];
500             redLowTxtFld.setText(Float.toString((float)redRange[0]));
501             redHighTxtFld.setText(Float.toString((float)redRange[1]));
502             updateRedGamma(1.0);
503             redGammaTxtFld.setText("1.0");
504           }
505         });
506       
507         grnLowTxtFld.addActionListener(new ActionListener() {
508             public void actionPerformed(ActionEvent e) {
509                String tmp = grnLowTxtFld.getText().trim();
510                updateGrnRange(Double.valueOf(tmp), grnRange[1]);
511             }
512         });
513    
514         grnHighTxtFld.addActionListener(new ActionListener() {
515             public void actionPerformed(ActionEvent e) {
516                String tmp = grnHighTxtFld.getText().trim();
517                updateGrnRange(grnRange[0], Double.valueOf(tmp));
518             }
519         });
520    
521         grnGammaTxtFld.addActionListener(new ActionListener() {
522             public void actionPerformed(ActionEvent e) {
523                 String tmp = grnGammaTxtFld.getText().trim();
524                 updateGrnGamma(Double.valueOf(tmp));
525             }
526         });
527    
528         JButton grnReset = new JButton("Reset");
529         grnReset.addActionListener(new ActionListener() {
530           public void actionPerformed(ActionEvent e) {
531             updateGrnRange(initGrnRange[0], initGrnRange[1]);
532             grnRange[0] = initGrnRange[0];
533             grnRange[1] = initGrnRange[1];
534             grnLowTxtFld.setText(Float.toString((float)grnRange[0]));
535             grnHighTxtFld.setText(Float.toString((float)grnRange[1]));
536             updateGrnGamma(1.0);
537             grnGammaTxtFld.setText("1.0");
538           }
539         });
540       
541         bluLowTxtFld.addActionListener(new ActionListener() {
542             public void actionPerformed(ActionEvent e) {
543                String tmp = bluLowTxtFld.getText().trim();
544                updateBluRange(Double.valueOf(tmp), bluRange[1]);
545             }
546         });
547    
548         bluHighTxtFld.addActionListener(new ActionListener() {
549             public void actionPerformed(ActionEvent e) {
550                String tmp = bluHighTxtFld.getText().trim();
551                updateBluRange(bluRange[0], Double.valueOf(tmp));
552             }
553         });
554    
555         bluGammaTxtFld.addActionListener(new ActionListener() {
556             public void actionPerformed(ActionEvent e) {
557                 String tmp = bluGammaTxtFld.getText().trim();
558                 updateBluGamma(Double.valueOf(tmp));
559             }
560         });
561    
562         JButton bluReset = new JButton("Reset");
563         bluReset.addActionListener(new ActionListener() {
564           public void actionPerformed(ActionEvent e) {
565             updateBluRange(initBluRange[0], initBluRange[1]);
566             bluRange[0] = initBluRange[0];
567             bluRange[1] = initBluRange[1];
568             bluLowTxtFld.setText(Float.toString((float)bluRange[0]));
569             bluHighTxtFld.setText(Float.toString((float)bluRange[1]));
570             updateBluGamma(1.0);
571             bluGammaTxtFld.setText("1.0");
572           }
573         });
574    
575         JButton applyButton = new JButton("Apply");
576         applyButton.addActionListener(new ActionListener() {
577           public void actionPerformed(ActionEvent e) {
578                String redLow = redLowTxtFld.getText().trim();
579                String redHigh = redHighTxtFld.getText().trim();
580                updateRedRange(Double.valueOf(redLow), Double.valueOf(redHigh));
581                String grnLow = grnLowTxtFld.getText().trim();
582                String grnHigh = grnHighTxtFld.getText().trim();
583                updateGrnRange(Double.valueOf(grnLow), Double.valueOf(grnHigh));
584                String bluLow = bluLowTxtFld.getText().trim();
585                String bluHigh = bluHighTxtFld.getText().trim();
586                updateBluRange(Double.valueOf(bluLow), Double.valueOf(bluHigh));
587    
588                String tmp = redGammaTxtFld.getText().trim();
589                updateRedGamma(Double.valueOf(tmp));
590                tmp = grnGammaTxtFld.getText().trim();
591                updateGrnGamma(Double.valueOf(tmp));
592                tmp = bluGammaTxtFld.getText().trim();
593                updateBluGamma(Double.valueOf(tmp));
594           }
595         });
596         
597         JPanel topPanel = new JPanel(new MigLayout());
598         topPanel.add(new JLabel("Red range: "));
599         topPanel.add(redLowTxtFld);
600         topPanel.add(redHighTxtFld);
601         topPanel.add(new JLabel("Red Gamma: "));
602         topPanel.add(redGammaTxtFld);
603         topPanel.add(redReset, "wrap");
604         
605         topPanel.add(new JLabel("Green range: "));
606         topPanel.add(grnLowTxtFld);
607         topPanel.add(grnHighTxtFld);
608         topPanel.add(new JLabel("Green Gamma: "));
609         topPanel.add(grnGammaTxtFld);
610         topPanel.add(grnReset, "wrap");
611         
612         topPanel.add(new JLabel("Blue range: "));
613         topPanel.add(bluLowTxtFld);
614         topPanel.add(bluHighTxtFld);
615         topPanel.add(new JLabel("Blue Gamma: "));
616         topPanel.add(bluGammaTxtFld);
617         topPanel.add(bluReset, "wrap");
618         
619         topPanel.add(Box.createHorizontalStrut(1), "span 5");
620         topPanel.add(applyButton, "wrap");
621         
622         JPanel bottomPanel = new JPanel(new MigLayout());
623         bottomPanel.add(new JLabel("Common Gamma: "));
624         bottomPanel.add(gammaTxtFld);
625         bottomPanel.add(allGammaButton);
626         
627         JPanel mainPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
628         mainPanel.add(topPanel);
629         mainPanel.add(bottomPanel);
630    
631         return mainPanel;
632       }
633    
634      private class ColorMapListener implements ScalarMapListener
635      {
636        ScalarMap clrMap;
637    
638        double[] range = null;
639        double[] initRange = null;
640    
641        JTextField lowTxtFld;
642        JTextField highTxtFld;
643    
644        ColorMapListener(ScalarMap clrMap, double[] initRange, double[] range, JTextField lowTxtFld, JTextField highTxtFld) {
645          this.clrMap = clrMap;
646          this.lowTxtFld = lowTxtFld;
647          this.highTxtFld = highTxtFld;
648          this.range = range;
649          this.initRange = initRange;
650        }
651    
652    
653        public void controlChanged(ScalarMapControlEvent event) throws RemoteException, VisADException {
654        }
655    
656        public void mapChanged(ScalarMapEvent event) throws RemoteException, VisADException {       
657          if (event.getId() == ScalarMapEvent.AUTO_SCALE) {
658                double[] rng = clrMap.getRange();
659                boolean shouldRemove = false;
660                //Ghansham: decide whether it is first time. The cleaner way
661                if (!Double.isNaN(rng[0]) && !Double.isNaN(rng[1]) && Double.isNaN(initRange[0]) && Double.isNaN(initRange[1])) {
662                    shouldRemove = true;
663                }
664                range[0] = rng[0];
665                range[1] = rng[1];
666                initRange[0] = rng[0];
667                initRange[1] = rng[1];
668                lowTxtFld.setText(Float.toString((float)rng[0]));
669                highTxtFld.setText(Float.toString((float)rng[1]));
670                //Ghansham:If its first time remove the scalarmaplistener and setRange manually to disable autscaling of the scalarmap
671                if(shouldRemove) {
672                    clrMap.removeScalarMapListener(this);
673                //-Lock out auto-scaling
674                    clrMap.disableAutoScale();
675                }
676          }
677          else if (event.getId() == ScalarMapEvent.MANUAL) {
678                double[] rng = clrMap.getRange();
679                range[0] = rng[0];
680                range[1] = rng[1];
681          }
682        }
683      }
684    
685    
686    }