source: ether_megapoli/trunk/service/implementation/gov2/noaa/pmel/sgt/ColorKey.java @ 192

Last change on this file since 192 was 192, checked in by vmipsl, 13 years ago

Servlet _ Contour en cours _ package gov2

File size: 19.2 KB
Line 
1/*
2 * $Id: ColorKey.java,v 1.20 2003/08/22 23:02:31 dwd Exp $
3 *
4 * This software is provided by NOAA for full, free and open release.  It is
5 * understood by the recipient/user that NOAA assumes no liability for any
6 * errors contained in the code.  Although this software is released without
7 * conditions or restrictions in its use, it is expected that appropriate
8 * credit be given to its author and to the National Oceanic and Atmospheric
9 * Administration should the software be included by the recipient as an
10 * element in other product development.
11 */
12
13package  gov.noaa.pmel.sgt;
14
15import gov.noaa.pmel.util.Rectangle2D;
16import gov.noaa.pmel.util.Dimension2D;
17import gov.noaa.pmel.util.Range2D;
18import gov.noaa.pmel.util.Point2D;
19import gov.noaa.pmel.util.Debug;
20
21import java.awt.Graphics;
22import java.awt.Rectangle;
23import java.awt.Color;
24import java.awt.Font;
25import java.awt.Insets;
26import java.beans.PropertyChangeEvent;
27import java.beans.PropertyChangeListener;
28import java.beans.PropertyChangeSupport;
29import java.awt.Point;
30
31// jdk1.2
32//import java.awt.geom.Rectangle2D;
33//import java.awt.geom.Point2D;
34
35/**
36 * The <code>ColorKey</code> class provides a graphical depiction
37 * of the relationship between a <code>ColorMap</code>
38 * and user values. A single <code>ColorKey</code> can be
39 * attached to a <code>Layer</code>. A <code>ColorMap</code>
40 * is associated with the Key and therefor with a specific transformation
41 * and optionally a <code>SGTData</code> object.
42 *
43 * @author Donald Denbo
44 * @version $Revision: 1.20 $, $Date: 2003/08/22 23:02:31 $
45 * @since 1.0
46 * @see Ruler
47 * @see ColorMap
48 * @see Layer
49**/
50public class ColorKey implements Cloneable, DataKey,
51                                 PropertyChangeListener {
52  // Scale members
53  /**@label title
54   * @link aggregationByValue
55   * @undirected
56   */
57  private SGLabel title_ = null;
58  //
59  private String ident_;
60  /** @directed */
61  private Layer layer_;
62  /**@label scale
63   * @link aggregationByValue */
64  private Ruler scale_ = new Ruler(); // mod Tom Ewing
65  private int valign_;
66  private int halign_;
67  private int orient_;
68  private int style_;
69  private boolean selected_;
70  private boolean selectable_;
71  private boolean visible_;
72  /**
73   * maximum bounds of key in p-space
74   */
75//  private Rectangle2D.Double pbounds_;
76  private Point2D.Double porigin_;
77  private Dimension2D psize_;
78  /**
79   * top, left, bottom, right in p-space
80   */
81  private double[] insets_ = {0.05, 0.15, 0.05, 0.15};
82  private double barWidth_ = 0.2;
83
84  /**
85   * @label cm
86   */
87  private ColorMap cm_ = null;
88  /**
89   * Use plain line border.
90   */
91  public static final int PLAIN_LINE = 0;
92  /**
93   * Use raised border.
94   */
95  public static final int RAISED = 1;
96  /**
97   * Do not draw a border.
98   */
99  public static final int NO_BORDER = 2;
100  /**
101   * Align to top of key.
102   */
103  public static final int TOP = 0;
104  /**
105   * Align to middle of key.
106   */
107  public static final int MIDDLE = 1;
108  /**
109   * Align to bottom of key.
110   */
111  public static final int BOTTOM = 2;
112  /**
113   * Align to left of key.
114   */
115  public static final int LEFT = 0;
116  /**
117   * Align to center of key.
118   */
119  public static final int CENTER = 1;
120  /**
121   * Align to right of key.
122   */
123  public static final int RIGHT = 2;
124  /**
125   * Orient key horizontally.
126   */
127  public static final int HORIZONTAL = 1;
128  /**
129   * Orient key vertically.
130   */
131  public static final int VERTICAL = 2;
132
133//  private boolean moveable_ = false;
134//  private PropertyChangeSupport changes_ = new PropertyChangeSupport(this);
135  /**
136   * Default <code>ColorKey</code> constructor. The location and size
137   * must be specified before the <code>ColorKey</code> is
138   * attached to a layer!
139   **/
140  public ColorKey() {
141    this(new Rectangle2D.Double(), BOTTOM, LEFT);
142  }
143  /**
144   * <code>ColorKey</code> constructor that include location, size,
145   * and alignment information. Default orientation is
146   * <code>HORIZONTAL</code>.
147   *
148   * @param pr a Rectangle2D object that includes location and size
149   * @param valign vertical alignment
150   * @param halign horizontal alignment
151   **/
152  public ColorKey(Rectangle2D.Double pr,int valign,int halign) {
153    this(new Point2D.Double(pr.x, pr.y),
154         new Dimension2D(pr.width, pr.height),
155         valign, halign);
156  }
157  /**
158   * @since 3.0
159   */
160  public ColorKey(Point2D.Double pt, Dimension2D size, int valign, int halign) {
161    porigin_ = pt;
162    psize_ = size;
163//    pbounds_ = new Rectangle2D.Double(pt.x, pt.y, size.width, size.height);
164    valign_ = valign;
165    halign_ = halign;
166    //
167    // set defaults
168    //
169    orient_ = HORIZONTAL;
170    selected_ = false;
171    selectable_ = true;
172    visible_ = true;
173    style_ = PLAIN_LINE;
174//    moveable_ = false;
175
176  }
177  /**
178   * Create a copy of <code>ColorKey</code>.
179   *
180   * @return a copy of the key
181   */
182  public LayerChild copy() {
183    ColorKey newKey;
184    try {
185      newKey = (ColorKey)clone();
186    } catch (CloneNotSupportedException e) {
187      newKey = new ColorKey();
188    }
189    return (LayerChild)newKey;
190  }
191  /**
192   * Sets the <code>selected</code> property.
193   * @since 2.0
194   *
195   * @param sel true if selected, false if not.
196   */
197  public void setSelected(boolean sel) {
198    selected_ = sel;
199  }
200  /**
201   * Returns true if the <code>selected</code> property is set.
202   *
203   * @return true is selected, false if not.
204   */
205  public boolean isSelected() {
206    return selected_;
207  }
208  /**
209   * Sets the selectable property.
210   * @since 2.0
211   */
212  public void setSelectable(boolean select) {
213    selectable_ = select;
214  }
215  /**
216   * Tests the selectable property.
217   * @since 2.0
218   */
219  public boolean isSelectable() {
220    return selectable_;
221  }
222  /**
223   * Set ColorKey identifier.
224   *
225   * @param id key identifier
226   */
227  public void setId(String id) {
228    ident_ = id;
229  }
230  /**
231   * Get <code>ColorKey</code> identifier
232   *
233   * @return identifier
234   */
235  public String getId() {
236    return ident_;
237  }
238  /**
239   * Set parent <code>Layer</code>. Method should not be called
240   * directly, called when the <code>Layer.addChild</code>
241   * method is called.
242   *
243   * @param l parent layer
244   */
245  public void setLayer(Layer l) {
246    layer_ = l;
247  }
248  /**
249   * Returns the layer the ColorKey is attached.
250   *
251   * @return The parent layer.
252   * @see Layer
253   **/
254  public Layer getLayer() {
255    return layer_;
256  }
257  /**
258   * Get the parent pane.
259   * @since 2.0
260   */
261  public AbstractPane getPane() {
262    return layer_.getPane();
263  }
264  /**
265   * For internal sgt use.
266   * @since 2.0
267   */
268  public void modified(String mess) {
269    //    if(Debug.EVENT) System.out.println("ColorKey: modified()");
270    if(layer_ != null)
271      layer_.modified(mess);
272  }
273  /**
274   * Set color map.
275   *
276   * @param cm color map
277   */
278  public void setColorMap(ColorMap cm) {
279    if(cm_ == null || !cm_.equals(cm)) {
280      if(cm_ != null) cm_.removePropertyChangeListener(this);
281      cm_ = cm;
282      cm_.addPropertyChangeListener(this);
283      modified("ColorKey: setColorMap()");
284    }
285  }
286  /**
287   * Add a GridCartesianRenderer and label to the ColorKey.
288   *
289   * @param rend GridCartesianRenderer object
290   * @param label descriptive label
291   * @since 3.0
292   */
293  public void addGraph(CartesianRenderer rend, SGLabel label)
294      throws IllegalArgumentException {
295    if(!(rend instanceof GridCartesianRenderer))
296      throw new IllegalArgumentException("Renderer is not a GridCartesianRenderer");
297    GridAttribute ga = (GridAttribute)((GridCartesianRenderer)rend).getAttribute();
298    ColorMap cm = ga.getColorMap();
299    setColorMap(cm);
300    setTitle(label);
301 //   addVectorGraph((VectorCartesianRenderer)rend, label);
302  }
303  /**
304   * Get color map.
305   *
306   * @return color map
307   */
308  public ColorMap getColorMap() {
309    return cm_;
310  }
311  /**
312   * Set border style.
313   *
314   * @param style border style
315   * @see #PLAIN_LINE
316   * @see #RAISED
317   * @see #NO_BORDER
318   */
319  public void setBorderStyle(int style) {
320    if(style_ != style) {
321      style_ = style;
322      modified("LineKey: setBorderStyle()");
323    }
324  }
325  /**
326   * Get border style.
327   *
328   * @return border style
329   */
330  public int getBorderStyle() {
331    return style_;
332  }
333  /**
334   * Set color key alignment.
335   *
336   * @param vert vertical alignment
337   * @param horz horizontal alignment
338   */
339  public void setAlign(int vert,int horz) {
340    if(valign_ != vert || halign_ != horz) {
341      valign_ = vert;
342      halign_ = horz;
343      modified("ColorKey: setAlign()");
344    }
345  }
346  /**
347   * Set orientation.
348   *
349   * @param orient key orientation
350   */
351  public void setOrientation(int orient) {
352    if(orient_ != orient) {
353      orient_ = orient;
354      modified("ColorKey: setOrientation()");
355    }
356  }
357  /**
358   * Set vertical alignment
359   *
360   * @param vert vertical alignment
361   */
362  public void setVAlign(int vert) {
363    if(valign_ != vert) {
364      valign_ = vert;
365      modified("ColorKey: setVAlign()");
366    }
367  }
368  /**
369   * Set horizontal alignment
370   *
371   * @param horz horizontal alignment
372   */
373  public void setHAlign(int horz) {
374    if(halign_ != horz) {
375      halign_ = horz;
376      modified("ColorKey: setHAlign()");
377    }
378  }
379  /**
380   * Get vertical alignment
381   *
382   * @return vertical alignment
383   */
384  public int getVAlign() {
385    return valign_;
386  }
387  /**
388   * Get horizontal alignment
389   *
390   * @return horizontal alignment
391   */
392  public int getHAlign() {
393    return halign_;
394  }
395  /**
396   * Set location of key in physical coordinates.
397   *
398   * @param loc key location
399   */
400  public void setLocationP(Point2D.Double loc) {
401    if(porigin_.x != loc.x || porigin_.y != loc.y) {
402//      Point2D.Double temp = new Point2D.Double(pbounds_.x, pbounds_.y);
403      porigin_.x = loc.x;
404      porigin_.y = loc.y;
405      modified("ColorKey: setLocationP()");
406//      changes_.firePropertyChange("location", temp, loc);
407    }
408  }
409  /**
410   * Set the size of the key in physical coordinates.
411   *
412   * @param d size of key
413   */
414  public void setSizeP(Dimension2D d) {
415    if(psize_.width != d.width || psize_.height != d.height) {
416      psize_.width = d.width;
417      psize_.height = d.height;
418      modified("ColorKey: setSizeP()");
419    }
420  }
421  /**
422   * Set the bounds of the key in physical coordinates.
423   *
424   * @param r bounding rectangle
425   */
426  public void setBoundsP(Rectangle2D.Double r) {
427    if(Debug.EVENT) System.out.println("ColorKey: porigin = " +
428                                       porigin_ + ", r = " + r);
429    setLocationP(new Point2D.Double(r.x, r.y));
430    setSizeP(new Dimension2D(r.width, r.height));
431//    if(pbounds_ == null || !pbounds_.equals(r)) {
432//      pbounds_ = r;
433//      modified("ColorKey: setBoundsP()");
434//    }
435  }
436  /**
437   * Get the bounding rectangle for the key in physical
438   * coordinates.
439   *
440   * @return bounding rectangle
441   */
442  public Rectangle2D.Double getBoundsP() {
443    return new Rectangle2D.Double(porigin_.x, porigin_.y,
444                                  psize_.width, psize_.height);
445  }
446  /**
447   * Gets the bounding rectangle in device
448   * coordinates.
449   *
450   * @return bounding rectangle
451   */
452  public Rectangle getBounds() {
453    int x, y, height, width;
454    x = layer_.getXPtoD(porigin_.x);
455    y = layer_.getYPtoD(porigin_.y);
456    width = layer_.getXPtoD(porigin_.x + psize_.width) - x;
457    height = layer_.getYPtoD(porigin_.y - psize_.height) - y;
458    switch(halign_) {
459    case RIGHT:
460      x = x - width;
461      break;
462    case CENTER:
463      x = x - width/2;
464    }
465    switch(valign_) {
466    case BOTTOM:
467      y = y - height;
468      break;
469    case MIDDLE:
470      y = y - height/2;
471    }
472    if(false) {
473      StringBuffer sbuf = new StringBuffer("\nColorKey.getBounds(): ");
474      switch(halign_) {
475        case RIGHT:
476          sbuf.append("RIGHT");
477          break;
478        case LEFT:
479          sbuf.append("LEFT");
480          break;
481        case CENTER:
482          sbuf.append("CENTER");
483          break;
484      }
485      sbuf.append(", ");
486      switch(valign_) {
487        case TOP:
488          sbuf.append("TOP");
489          break;
490        case BOTTOM:
491          sbuf.append("BOTTOM");
492          break;
493        case MIDDLE:
494          sbuf.append("MIDDLE");
495          break;
496      }
497      System.out.println(sbuf);
498      System.out.println("    orig = " + porigin_ + ", " + "size = " + psize_);
499      System.out.println("    x,y,width,height = " + x + ", " + y + ", " +
500                         width + ", " + height);
501      System.out.println("   layer.getBounds() = " + layer_.getBounds());
502      System.out.println("   layer.getBoundsP() = " + layer_.getBoundsP());
503    }
504    return new Rectangle(x, y, width, height);
505  }
506  /**
507   * Change the selected objects bounding rectangle in
508   * device coordinates. The object will move to the new bounding
509   * rectangle.
510   *
511   * @param r new bounding rectangle
512   */
513  public void setBounds(Rectangle r) {
514    setBounds(r.x, r.y, r.width, r.height);
515  }
516  /**
517   * Change the selected objects bounding rectangle in
518   * device coordinates. The object will move to the new bounding
519   * rectangle.
520   *
521   * @param x horizontal location, positive right
522   * @param y vertical location, positive down
523   * @param width horizontal size
524   * @param height vertical size
525   */
526  public void setBounds(int x, int y, int width, int height) {
527    switch(halign_) {
528    case RIGHT:
529      x = x + width;
530      break;
531    case CENTER:
532      x = x + width/2;
533    }
534    switch(valign_) {
535    case BOTTOM:
536      y = y + height;
537      break;
538    case MIDDLE:
539      y = y + height/2;
540    }
541//    Point orig = new Point(layer_.getXPtoD(pbounds_.x),
542//                           layer_.getYPtoD(pbounds_.y));
543    double xp = layer_.getXDtoP(x);
544    double yp = layer_.getYDtoP(y);
545    if(porigin_.x != xp || porigin_.y != yp) {
546      porigin_.x = xp;
547      porigin_.y = yp;
548      modified("ColorKey: setBounds()");
549//      changes_.firePropertyChange("location",
550//                                  orig, new Point(x,y));
551    }
552  }
553  /**
554   * Set the title of the key.
555   *
556   * @param title key title
557   */
558  public void setTitle(SGLabel title) {
559    if(title_ == null || !title_.equals(title)) {
560      title_ = title;
561      modified("ColorKey: setTitle()");
562    }
563  }
564  /**
565   * Get the key's title.
566   *
567   * @return the title
568   */
569  public SGLabel getTitle() {
570    return title_;
571  }
572  /**
573   * Get the <code>Ruler</code> associated
574   * with the key.
575   *
576   * @return the ruler
577   */
578  public Ruler getRuler() {
579    return scale_;
580  }
581  /**
582   * Draw the ColorKey. This method should not be directly called.
583   *
584   * @see Pane#draw
585   */
586  public void draw(Graphics g) {
587    Rectangle bounds;
588    double xp, yp;  // lower-left coordinates in p-space
589    double ptop, pbottom, pleft, pright; // insets in p-space
590    double delta;
591    if(!visible_) return;
592    ptop = insets_[0];
593    pbottom =insets_[2];
594    pleft = insets_[1];
595    pright = insets_[3];
596    xp = porigin_.x;
597    yp = porigin_.y;
598    switch(halign_) {
599    case RIGHT:
600      xp = xp - psize_.width;
601      break;
602    case CENTER:
603      xp = xp - psize_.width/2;
604    }
605    switch(valign_) {
606    case TOP:
607      yp = yp - psize_.height;
608      break;
609    case MIDDLE:
610      yp = yp - psize_.height/2;
611    }
612    bounds = getBounds();
613    g.setColor(Color.black);
614    switch(style_) {
615    case PLAIN_LINE:
616      g.drawRect(bounds.x, bounds.y, bounds.width-1, bounds.height-1);
617      break;
618    case RAISED:
619      break;
620    default:
621    case NO_BORDER:
622    }
623
624    if(cm_ == null) return;
625    Range2D uRange = cm_.getRange();
626    //
627    if(Double.isNaN(uRange.delta)) {
628      Range2D rnge = Graph.computeRange(uRange.start, uRange.end, 10);
629      delta = rnge.delta;
630    } else {
631      delta = uRange.delta;
632    }
633    if(orient_ == HORIZONTAL) {
634      drawBar(g, xp + pleft, yp + psize_.height - ptop,
635              psize_.width - pleft - pright,
636              psize_.height - ptop - pbottom);
637      //scale_ = new Ruler(); // mod Tom Ewing
638      scale_.setOrientation(Ruler.HORIZONTAL);
639      scale_.setLayer(layer_);
640      scale_.setTitle(title_);
641      scale_.setTicPosition(Ruler.NEGATIVE_SIDE);
642      scale_.setLabelPosition(Ruler.NEGATIVE_SIDE);
643      scale_.setBoundsP(new Rectangle2D.Double(xp + pleft,
644                                               yp + psize_.height - ptop - barWidth_,
645                                               psize_.width - pleft - pright,
646                                               psize_.height - ptop - pbottom));
647      scale_.setRangeU(new Range2D(uRange.start, uRange.end, delta));
648      scale_.draw(g);
649    } else {
650      drawBar(g, xp + pleft, yp + pbottom,
651              psize_.width - pleft - pright,
652              psize_.height - ptop - pbottom);
653      //scale_ = new Ruler(); // mod dwd
654      scale_.setOrientation(Ruler.VERTICAL);
655      scale_.setLayer(layer_);
656      scale_.setTitle(title_);
657      scale_.setTicPosition(Ruler.POSITIVE_SIDE);
658      scale_.setLabelPosition(Ruler.POSITIVE_SIDE);
659      scale_.setBoundsP(new Rectangle2D.Double(xp + pleft + barWidth_,
660                                               yp + pbottom,
661                                               psize_.width - pleft - pright,
662                                               psize_.height - ptop - pbottom));
663      scale_.setRangeU(new Range2D(uRange.start, uRange.end, delta));
664      scale_.draw(g);
665    }
666  }
667  //
668  void drawBar(Graphics g,
669               double plocx, double plocy,
670               double pwidth, double pheight) {
671    int yloc, xloc, xend, yend;
672    int dBarHeight, dBarWidth;
673    Range2D uRange = cm_.getRange();
674    AxisTransform sTrans;
675    if(orient_ == HORIZONTAL) {
676      dBarHeight = layer_.getYPtoD(plocy - barWidth_) -
677        layer_.getYPtoD(plocy);
678      sTrans = new LinearTransform(plocx, plocx + pwidth,
679                                   uRange.start, uRange.end);
680      yloc = layer_.getYPtoD(plocy);
681      xloc = layer_.getXPtoD(sTrans.getTransP(uRange.start));
682      xend = layer_.getXPtoD(sTrans.getTransP(uRange.end));
683      for(int i=xloc; i <= xend; i++) {
684        g.setColor(cm_.getColor(sTrans.getTransU(layer_.getXDtoP(i))));
685        g.fillRect(i, yloc, 1, dBarHeight);
686      }
687    } else {
688      dBarWidth = layer_.getXPtoD(plocx + barWidth_) - layer_.getXPtoD(plocx);
689      sTrans = new LinearTransform(plocy, plocy + pheight,
690                                   uRange.start, uRange.end);
691      xloc = layer_.getXPtoD(plocx);
692      yloc = layer_.getYPtoD(sTrans.getTransP(uRange.start));
693      yend = layer_.getYPtoD(sTrans.getTransP(uRange.end));
694      for(int i=yend; i <= yloc; i++) {
695        g.setColor(cm_.getColor(sTrans.getTransU(layer_.getXDtoP(i))));
696        g.fillRect(xloc, i, dBarWidth, 1);
697      }
698    }
699  }
700  /**
701   * Get a string representation of the key.
702   *
703   * @return string representation
704   */
705  public String toString() {
706    String name = getClass().getName();
707    return name.substring(name.lastIndexOf(".")+1) + ": " + ident_;
708  }
709  /**
710   * Check if ColorKey is visible.
711   * @since 2.0
712   */
713  public boolean isVisible() {
714    return visible_;
715  }
716  /**
717   * Set visibility state for ColorKey.
718   * @since 2.0
719   */
720  public void setVisible(boolean visible) {
721    if(visible_ != visible) {
722      visible_ = visible;
723      modified("ColorKey: setVisible()");
724    }
725  }
726  public void propertyChange(PropertyChangeEvent evt) {
727    modified("ColorKey: propertyChange(" +
728             evt.getSource().toString() + "[" +
729             evt.getPropertyName() + "]" + ")");
730  }
731
732  /**
733   * Set columns. Unimplmented.
734   * @param col
735   * @since 3.0
736   */
737  public void setColumns(int col) {}
738  /**
739   * Set line lenght. Unimplemented.
740   * @since 3.0
741   */
742  public void setLineLengthP(double len) {}
743
744}
Note: See TracBrowser for help on using the repository browser.