source: ether_megapoli/trunk/service/implementation/gov2/noaa/pmel/sgt/LineKey.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: 22.2 KB
Line 
1/*
2 * $Id: LineKey.java,v 1.16 2003/08/22 23:02:32 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.Point2D;
16import gov.noaa.pmel.util.Rectangle2D;
17
18import java.awt.*;
19import java.beans.PropertyChangeEvent;
20import java.beans.PropertyChangeListener;
21import java.beans.PropertyChangeSupport;
22import java.util.Enumeration;
23import java.util.Vector;
24
25// jdk1.2
26//import java.awt.geom.Point2D;
27
28/**
29 * <code>LineKey</code> is used to create a key for the
30 * <code>LineCartesianRenderer</code>. Multiple
31 * lines can be included in the key.
32 *
33 * @author Donald Denbo
34 * @version $Revision: 1.16 $, $Date: 2003/08/22 23:02:32 $
35 * @since 1.0
36 */
37public class LineKey
38        implements Cloneable,
39        DataKey, Moveable, PropertyChangeListener
40{
41    private String ident_;
42    /**
43     * @directed
44     */
45    private Layer layer_;
46    /**
47     * @link aggregation
48     * @supplierCardinality *
49     * @label line
50     */
51    /*#LineCartesianRenderer lnkLineCartesianRenderer;*/
52    private Vector line_;
53    /**
54     * @link aggregation
55     * @supplierCardinality *
56     * @label label
57     */
58    /*#SGLabel lnkSGLabel;*/
59    private Vector label_;
60    private int columns_;
61    private int style_;
62    private int valign_;
63    private int halign_;
64    private Point2D.Double porigin_;
65    private double lineLengthP_;
66    private int maxLabelLength_;
67    private int maxLabelHeight_;
68    private StrokeDrawer stroke_ = null;
69    private boolean selected_;
70    private boolean selectable_;
71    private boolean visible_;
72    private boolean moveable_;
73    private PropertyChangeSupport changes_ = new PropertyChangeSupport( this );
74    private static final int VERTICAL_BORDER_ = 3;
75    private static final int HORIZONTAL_BORDER_ = 15;
76    // VMIPSL
77    private static final int COLUMN_SPACE_ = 0;
78    private static final int ROW_SPACE_ = 15;
79    private static final int LABEL_SPACE_ = 10;
80    /**
81     * Use plain line border.
82     */
83    public static final int PLAIN_LINE = 0;
84    /**
85     * Use raised border.
86     */
87    public static final int RAISED = 1;
88    /**
89     * Do not draw a border.
90     */
91    public static final int NO_BORDER = 2;
92    /**
93     * Align to top of key.
94     */
95    public static final int TOP = 0;
96    /**
97     * Align to middle of key.
98     */
99    public static final int MIDDLE = 1;
100    /**
101     * Align to bottom of key.
102     */
103    public static final int BOTTOM = 2;
104    /**
105     * Align to left of key.
106     */
107    public static final int LEFT = 0;
108    /**
109     * Align to center of key.
110     */
111    public static final int CENTER = 1;
112    /**
113     * Align to right of key.
114     */
115    public static final int RIGHT = 2;
116
117
118    /**
119     * Default constructor.
120     */
121    public LineKey()
122    {
123        this( new Point2D.Double( 0.0, 0.0 ), BOTTOM, LEFT );
124    }
125
126    /**
127     *
128     */
129    public LineKey( Point2D.Double loc, int valign, int halign )
130    {
131        porigin_ = loc;
132        valign_ = valign;
133        halign_ = halign;
134        line_ = new Vector( 2, 2 );
135        label_ = new Vector( 2, 2 );
136        //
137        // set defaults
138        //
139        style_ = PLAIN_LINE;
140        columns_ = 1;
141        ident_ = "";
142        lineLengthP_ = 0.3f;
143        selected_ = false;
144        selectable_ = true;
145        visible_ = true;
146        moveable_ = true;
147        stroke_ = PaneProxy.strokeDrawer;
148    }
149
150    /**
151     * Create of copy of LineKey.
152     */
153    public LayerChild copy()
154    {
155        LineKey newKey;
156        try
157        {
158            newKey = (LineKey) clone();
159        }
160        catch( CloneNotSupportedException e )
161        {
162            newKey = new LineKey();
163        }
164        newKey.line_ = new Vector( 2, 2 );
165        newKey.label_ = new Vector( 2, 2 );
166        return newKey;
167    }
168
169    public void setSelected( boolean sel )
170    {
171        selected_ = sel;
172    }
173
174    public boolean isSelected()
175    {
176        return selected_;
177    }
178
179    public void setSelectable( boolean select )
180    {
181        selectable_ = select;
182    }
183
184    public boolean isSelectable()
185    {
186        return selectable_;
187    }
188
189    public boolean isMoveable()
190    {
191        return moveable_;
192    }
193
194    public void setMoveable( boolean moveable )
195    {
196        moveable_ = moveable;
197    }
198
199    /**
200     * Set parent layer.
201     *
202     * @param l parent layer
203     */
204    public void setLayer( Layer l )
205    {
206        layer_ = l;
207    }
208
209    /**
210     * Get layer.
211     *
212     * @return layer
213     */
214    public Layer getLayer()
215    {
216        return layer_;
217    }
218
219    public AbstractPane getPane()
220    {
221        return layer_.getPane();
222    }
223
224    public void modified( String mess )
225    {
226        if( layer_ != null )
227            layer_.modified( mess );
228    }
229
230    /**
231     * Set LineKey identifier.
232     *
233     * @param id key identifier
234     */
235    public void setId( String id )
236    {
237        ident_ = id;
238    }
239
240    /**
241     * Get LineKey identifier
242     *
243     * @return identifier
244     */
245    public String getId()
246    {
247        return ident_;
248    }
249
250    /**
251     * Set line length.
252     *
253     * @param len line length
254     */
255    public void setLineLengthP( double len )
256    {
257        if( lineLengthP_ != len )
258        {
259            lineLengthP_ = len;
260            modified( "LineKey: setLineLengthP()" );
261        }
262    }
263
264    /**
265     * Get line length
266     *
267     * @return line length
268     */
269    public double getLineLengthP()
270    {
271        return lineLengthP_;
272    }
273
274    /**
275     * Set the number of columns.
276     *
277     * @param col number of columns
278     */
279    public void setColumns( int col )
280    {
281        if( columns_ != col )
282        {
283            columns_ = col;
284            modified( "LineKey: setColumms()" );
285        }
286    }
287
288    /**
289     * Get the number of columns.
290     *
291     * @return number of columns
292     */
293    public int getColumns()
294    {
295        return columns_;
296    }
297
298    /**
299     * Set border style.
300     *
301     * @param style border style
302     * @see #PLAIN_LINE
303     * @see #RAISED
304     * @see #NO_BORDER
305     */
306    public void setBorderStyle( int style )
307    {
308        if( style_ != style )
309        {
310            style_ = style;
311            modified( "LineKey: setBorderStyle()" );
312        }
313    }
314
315    /**
316     * Get border style.
317     *
318     * @return border style
319     */
320    public int getBorderStyle()
321    {
322        return style_;
323    }
324
325    /**
326     * Set alignment.
327     *
328     * @param vert vertical alignment
329     * @param horz horizontal alignment
330     */
331    public void setAlign( int vert, int horz )
332    {
333        if( valign_ != vert || halign_ != horz )
334        {
335            valign_ = vert;
336            halign_ = horz;
337            modified( "LineKey: setAlign()" );
338        }
339    }
340
341    /**
342     * Set vertical alignment
343     *
344     * @param vert vertical alignment
345     */
346    public void setVAlign( int vert )
347    {
348        if( valign_ != vert )
349        {
350            valign_ = vert;
351            modified( "LineKey: setVAlign()" );
352        }
353    }
354
355    /**
356     * Set horizontal alignment
357     *
358     * @param horz horizontal alignment
359     */
360    public void setHAlign( int horz )
361    {
362        if( halign_ != horz )
363        {
364            halign_ = horz;
365            modified( "LineKey: setHAlign()" );
366        }
367    }
368
369    /**
370     * Get vertical alignment
371     *
372     * @return vertical alignment
373     */
374    public int getVAlign()
375    {
376        return valign_;
377    }
378
379    /**
380     * Get horizontal alignment
381     *
382     * @return horizontal alignment
383     */
384    public int getHAlign()
385    {
386        return halign_;
387    }
388
389    /**
390     * Set location of key
391     * <BR><B>Property Change:</B> <code>location</code>.
392     *
393     * @param loc key location
394     */
395    public void setLocationP( Point2D.Double loc )
396    {
397        if( porigin_ == null || !porigin_.equals( loc ) )
398        {
399            Point2D.Double temp = porigin_;
400            porigin_ = loc;
401            changes_.firePropertyChange( "location",
402                    temp,
403                    porigin_ );
404            modified( "LineKey: setLocationP()" );
405        }
406    }
407
408    /**
409     * Set the bounds of the <code>LineKey</code> in physical units.
410     */
411    public void setBoundsP( Rectangle2D.Double r )
412    {
413        setLocationP( new Point2D.Double( r.x, r.y ) );
414    }
415
416    /**
417     * Get key bounds in physical coordinates.
418     * Not presently implemented.
419     */
420    public Rectangle2D.Double getBoundsP()
421    {
422        throw new MethodNotImplementedError();
423    }
424
425    /**
426     * Get location of key.
427     *
428     * @return Key location
429     */
430    public Point2D.Double getLocationP()
431    {
432        return porigin_;
433    }
434
435
436    /**
437     * Add a LineCartesianRenderer and label to the LineKey.
438     *
439     * @param line  LineCartesianGraph object
440     * @param label descriptive label
441     */
442    public void addLineGraph( LineCartesianRenderer line, SGLabel label )
443    {
444        line_.addElement( line );
445        label.setLayer( layer_ );
446        label.setMoveable( false );
447        label.setSelectable( false );
448        label_.addElement( label );
449        ( (LineAttribute) line.getAttribute() ).addPropertyChangeListener( this );
450        modified( "LineKey: addLineGraph()" );
451    }
452
453    /**
454     * Add a LineCartesianRenderer and label to the LineKey.
455     *
456     * @param rend  LineCartesianRenderer object
457     * @param label descriptive label
458     * @since 3.0
459     */
460    public void addGraph( CartesianRenderer rend, SGLabel label )
461            throws IllegalArgumentException
462    {
463        if( !( rend instanceof LineCartesianRenderer ) )
464            throw new IllegalArgumentException( "Renderer is not a LineCartesianRenderer" );
465        addLineGraph( (LineCartesianRenderer) rend, label );
466    }
467
468    /**
469     * Remove a line from the LineKey.
470     */
471    public void removeLineGraph( SGLabel label )
472    {
473    }
474
475    /**
476     * Remove a line from the LineKey.
477     */
478    public void removeLineRenderer( LineCartesianRenderer line )
479    {
480    }
481
482    /**
483     * Remove a line from the LineKey.
484     */
485    public void removeLineGraph( String ident )
486    {
487    }
488
489    /**
490     * Remove all lines from the LineKey.
491     */
492    public void clearAll()
493    {
494        LineAttribute attr;
495        for( Enumeration e = line_.elements(); e.hasMoreElements(); )
496        {
497            attr = (LineAttribute) ( (LineCartesianRenderer) e.nextElement() ).getAttribute();
498            attr.removePropertyChangeListener( this );
499        }
500        line_.removeAllElements();
501        label_.removeAllElements();
502        modified( "LineKey: clearAll()" );
503    }
504
505    /**
506     * Remove line associated with data id from LineKey.
507     *
508     * @since 2.0
509     */
510    public void clear( String data_id )
511    {
512        LineCartesianRenderer lcr;
513        int indx = -1;
514        for( Enumeration it = line_.elements(); it.hasMoreElements(); )
515        {
516            indx++;
517            lcr = (LineCartesianRenderer) it.nextElement();
518            if( lcr.getLine().getId().equals( data_id ) )
519            {
520                lcr.getAttribute().removePropertyChangeListener( this );
521                line_.removeElement( lcr );
522                label_.removeElementAt( indx );
523                modified( "LineKey: clear()" );
524                break;
525            }
526        }
527    }
528
529    /**
530     * Return rowheight of key in pixels.
531     *
532     * @since 2.0
533     */
534    public int getRowHeight()
535    {
536        Rectangle bounds;
537        bounds = getBounds();
538        return ROW_SPACE_ + maxLabelHeight_;
539    }
540
541    /**
542     * Draw the Key.
543     */
544    public void draw( Graphics g )
545    {
546        double maxLabelLength, maxLabelHeight;
547        int numLines, numRows, i, lineLength;
548        int col, row, ytemp;
549        double xloc, labelSpace;
550        double[] xp, yp;
551        int[] xd, yd;
552        int[] xout, yout;
553        Rectangle bounds;
554        LineCartesianRenderer render = null;
555        SGLabel label;
556        LineAttribute attr = null;
557        //
558        numLines = line_.size();
559        if( ( numLines <= 0 ) || !visible_ ) return;
560
561        numRows = numLines / columns_;
562        if( numLines % columns_ != 0 ) numRows++;
563
564        xp = new double[columns_];
565        xd = new int[columns_];
566        yp = new double[numRows];
567        yd = new int[numRows];
568        xout = new int[2];
569        yout = new int[2];
570
571        g.setColor( layer_.getPane().getComponent().getForeground() );
572        bounds = getBounds();
573        //
574        // compute location of rows and columns in device and physical coordinates
575        //
576        lineLength = layer_.getXPtoD( lineLengthP_ ) - layer_.getXPtoD( 0.0f );
577        labelSpace = layer_.getXDtoP( LABEL_SPACE_ ) - layer_.getXDtoP( 0 );
578        //
579        yd[0] = bounds.y + VERTICAL_BORDER_ + maxLabelHeight_;
580        yp[0] = layer_.getYDtoP( yd[0] );
581        for( i = 1; i < numRows; i++ )
582        {
583            yd[i] = yd[i - 1] + ROW_SPACE_ + maxLabelHeight_;
584            yp[i] = layer_.getYDtoP( yd[i] );
585        }
586        xd[0] = bounds.x + HORIZONTAL_BORDER_;
587        xp[0] = layer_.getXDtoP( xd[0] );
588        for( i = 1; i < columns_; i++ )
589        {
590            xd[i] = xd[i - 1] + COLUMN_SPACE_ + lineLength + LABEL_SPACE_ + maxLabelLength_;
591            xp[i] = layer_.getXDtoP( xd[i] );
592        }
593        //
594        row = 0;
595        col = 0;
596        Object obj;
597        Enumeration labelIt = label_.elements();
598        for( Enumeration lineIt = line_.elements(); lineIt.hasMoreElements(); )
599        {
600            obj = lineIt.nextElement();
601            render = (LineCartesianRenderer) obj;
602            attr = (LineAttribute) render.getAttribute();
603            label = (SGLabel) labelIt.nextElement();
604            //
605            // draw line
606            //
607            g.setColor( attr.getColor() );
608            xout[0] = xd[col];
609            xout[1] = xout[0] + lineLength;
610
611            // VMIPSL
612            if( 0 != maxLabelHeight_ )
613                yout[0] = yd[row] - maxLabelHeight_ / 2;
614            else
615                yout[0] = yd[row] - 4;
616            yout[1] = yout[0];
617            switch( attr.getStyle() )
618            {
619                case LineAttribute.MARK:
620                    // VMIPSL
621                    xout[0] = xout[1];
622                    render.drawMark( g, xout, yout, 1, attr );
623                    break;
624                case LineAttribute.HIGHLIGHT:
625                    stroke_.drawHighlight( g, xout, yout, 2, attr );
626                    break;
627                case LineAttribute.HEAVY:
628                    stroke_.drawHeavy( g, xout, yout, 2, attr );
629                    break;
630                case LineAttribute.DASHED:
631                    stroke_.drawDashed( g, xout, yout, 2, attr );
632                    break;
633                case LineAttribute.STROKE:
634                    stroke_.drawStroke( g, xout, yout, 2, attr );
635                    break;
636                case LineAttribute.MARK_LINE:
637                    render.drawMark( g, xout, yout, 2, attr );
638                default:
639                case LineAttribute.SOLID:
640                    g.drawLine( xout[0], yout[0], xout[1], yout[1] );
641            }
642            //
643            xloc = xp[col] + lineLengthP_ + labelSpace;
644            label.setLocationP( new Point2D.Double( xloc, yp[row] ) );
645            try
646            {
647                label.draw( g );
648            }
649            catch( SGException e )
650            {
651            }
652            //
653            col++;
654            if( col >= columns_ )
655            {
656                col = 0;
657                row++;
658            }
659        }
660        switch( style_ )
661        {
662            case PLAIN_LINE:
663                g.drawRect( bounds.x, bounds.y, bounds.width - 1, bounds.height - 1 );
664                break;
665            case RAISED:
666                break;
667            default:
668            case NO_BORDER:
669        }
670    }
671
672    /**
673     * Get the bounding rectangle.
674     *
675     * @return bounding rectangle
676     */
677    public Rectangle getBounds()
678    {
679        int lineLength;
680        int numLines, rows;
681        int x, y, height, width;
682
683        numLines = line_.size();
684        if( numLines <= 0 ) return new Rectangle( 0, 0, 0, 0 );
685        //
686        // find longest label
687        //
688        maxLabelLength_ = 0;
689        maxLabelHeight_ = 0;
690        SGLabel label;
691        for( Enumeration it = label_.elements(); it.hasMoreElements(); )
692        {
693            label = (SGLabel) it.nextElement();
694            Rectangle sz = label.getBounds();
695            maxLabelLength_ = Math.max( maxLabelLength_, sz.width );
696            maxLabelHeight_ = Math.max( maxLabelHeight_, sz.height );
697        }
698        //
699        rows = numLines / columns_;
700        if( numLines % columns_ != 0 ) rows++;
701        lineLength = layer_.getXPtoD( lineLengthP_ ) - layer_.getXPtoD( 0.0f );
702        width = 2 * HORIZONTAL_BORDER_ + columns_ * ( lineLength + LABEL_SPACE_ + maxLabelLength_ )
703                + ( columns_ - 1 ) * COLUMN_SPACE_;
704        height = 2 * VERTICAL_BORDER_ + rows * maxLabelHeight_ + ( rows - 1 ) * ROW_SPACE_;
705        //
706        x = layer_.getXPtoD( porigin_.x );
707        y = layer_.getYPtoD( porigin_.y );
708        switch( halign_ )
709        {
710            case RIGHT:
711                x = x - width;
712                break;
713            case CENTER:
714                x = x - width / 2;
715        }
716        switch( valign_ )
717        {
718            case BOTTOM:
719                y = y - height;
720                break;
721            case MIDDLE:
722                y = y - height / 2;
723        }
724        return new Rectangle( x, y, width, height );
725    }
726
727    public Point getLocation()
728    {
729        Rectangle bnds = getBounds();
730        return new Point( bnds.x, bnds.y );
731    }
732
733    public void setLocation( Point loc )
734    {
735        Rectangle bnds = getBounds();
736        setBounds( loc.x, loc.y, bnds.width, bnds.height );
737    }
738
739    /**
740     * Set the bounds of the <code>LineKey</code>.
741     */
742    public void setBounds( Rectangle r )
743    {
744        setBounds( r.x, r.y, r.width, r.height );
745    }
746
747    /**
748     * Set the bounds of the <code>LineKey</code>.
749     * <BR><B>Property Change:</B> <code>location</code>.
750     */
751    public void setBounds( int x, int y, int width, int height )
752    {
753        switch( halign_ )
754        {
755            case RIGHT:
756                x = x + width;
757                break;
758            case CENTER:
759                x = x + width / 2;
760        }
761        switch( valign_ )
762        {
763            case BOTTOM:
764                y = y + height;
765                break;
766            case MIDDLE:
767                y = y + height / 2;
768        }
769        double xp = layer_.getXDtoP( x );
770        double yp = layer_.getYDtoP( y );
771        if( porigin_.x != xp || porigin_.y != yp )
772        {
773            Point2D.Double temp = porigin_;
774            porigin_.x = xp;
775            porigin_.y = yp;
776            changes_.firePropertyChange( "location",
777                    temp,
778                    new Point2D.Double( xp, yp ) );
779            modified( "LineKey: setBounds()" );
780        }
781    }
782
783    Object getObjectAt( Point pt )
784    {
785        Rectangle lbnds;
786        Rectangle bounds;
787        LineCartesianRenderer line;
788        int[] xout, yout;
789        int[] xd, yd;
790        int numLines, numRows;
791        int lineLength;
792        double labelSpace;
793        int i;
794
795        numLines = line_.size();
796        if( numLines <= 0 ) return null;
797
798        numRows = numLines / columns_;
799        if( numLines % columns_ != 0 ) numRows++;
800
801        xd = new int[columns_];
802        yd = new int[numRows];
803        xout = new int[2];
804        yout = new int[2];
805        bounds = getBounds();
806        //
807        // compute location of rows and columns in device and physical coordinates
808        //
809        lineLength = layer_.getXPtoD( lineLengthP_ ) - layer_.getXPtoD( 0.0 );
810        labelSpace = layer_.getXDtoP( LABEL_SPACE_ ) - layer_.getXDtoP( 0 );
811        //
812        yd[0] = bounds.y + VERTICAL_BORDER_ + maxLabelHeight_;
813        for( i = 1; i < numRows; i++ )
814        {
815            yd[i] = yd[i - 1] + ROW_SPACE_ + maxLabelHeight_;
816        }
817        xd[0] = bounds.x + HORIZONTAL_BORDER_;
818        for( i = 1; i < columns_; i++ )
819        {
820            xd[i] = xd[i - 1] + COLUMN_SPACE_ + lineLength + LABEL_SPACE_ + maxLabelLength_;
821        }
822        // loop over all the lines
823        int row = 0;
824        int col = 0;
825        for( Enumeration lineIt = line_.elements(); lineIt.hasMoreElements(); )
826        {
827            line = (LineCartesianRenderer) lineIt.nextElement();
828            xout[0] = xd[col];
829            xout[1] = xout[0] + lineLength + LABEL_SPACE_ + maxLabelLength_;
830//        xout[1] = xout[0] + lineLength + LABEL_SPACE_;
831            yout[0] = yd[row] - maxLabelHeight_;
832            yout[1] = yd[row];
833            lbnds = new Rectangle( xout[0], yout[0],
834                    xout[1] - xout[0],
835                    yout[1] - yout[0] );
836            if( lbnds.contains( pt ) )
837            {
838                return line;
839            }
840            //
841            col++;
842            if( col >= columns_ )
843            {
844                col = 0;
845                row++;
846            }
847        }
848        if( bounds.contains( pt ) )
849        {
850            return this;
851        }
852        return null;
853    }
854
855    public String toString()
856    {
857        String name = getClass().getName();
858        return name.substring( name.lastIndexOf( "." ) + 1 ) + ": " + ident_;
859    }
860
861    public boolean isVisible()
862    {
863        return visible_;
864    }
865
866    public void setVisible( boolean visible )
867    {
868        if( visible_ != visible )
869        {
870            visible_ = visible;
871            modified( "LineKey: setVisible()" );
872        }
873    }
874
875    public void propertyChange( PropertyChangeEvent evt )
876    {
877//      if(Debug.EVENT) {
878//        System.out.println("LineKey: " + evt);
879//        System.out.println("         " + evt.getPropertyName());
880//      }
881        modified( "LineKey: propertyChange(" +
882                evt.getSource().toString() + "[" +
883                evt.getPropertyName() + "]" + ")" );
884    }
885
886    public void addPropertyChangeListener( PropertyChangeListener l )
887    {
888        changes_.addPropertyChangeListener( l );
889    }
890
891    public void removePropertyChangeListener( PropertyChangeListener l )
892    {
893        changes_.removePropertyChangeListener( l );
894    }
895}
Note: See TracBrowser for help on using the repository browser.