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 | |
---|
13 | package gov.noaa.pmel.sgt; |
---|
14 | |
---|
15 | import gov.noaa.pmel.util.Point2D; |
---|
16 | import gov.noaa.pmel.util.Rectangle2D; |
---|
17 | |
---|
18 | import java.awt.*; |
---|
19 | import java.beans.PropertyChangeEvent; |
---|
20 | import java.beans.PropertyChangeListener; |
---|
21 | import java.beans.PropertyChangeSupport; |
---|
22 | import java.util.Enumeration; |
---|
23 | import 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 | */ |
---|
37 | public 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 | } |
---|