1 | /* |
---|
2 | * $Id: Pane.java,v 1.23 2003/09/19 23:14:24 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.Debug; |
---|
16 | |
---|
17 | import java.awt.Rectangle; |
---|
18 | import java.awt.Dimension; |
---|
19 | import java.awt.Point; |
---|
20 | import java.awt.Component; |
---|
21 | import java.awt.Container; |
---|
22 | import java.awt.Graphics; |
---|
23 | import java.awt.AWTEvent; |
---|
24 | |
---|
25 | import java.awt.event.MouseEvent; |
---|
26 | import java.beans.PropertyChangeListener; |
---|
27 | |
---|
28 | /** |
---|
29 | * The <code>Pane</code> class is extended from <code>java.awt.Container</code> |
---|
30 | * and is the basis for the <code>gov.noaa.pmel.sgt</code> package. |
---|
31 | * <p> |
---|
32 | * The Java scientific graphics toolkit is designed to allow a |
---|
33 | * graphics client developer a great deal of flexibility and freedom. |
---|
34 | * <code>sgt</code> is a package that greatly aids a developer in |
---|
35 | * creating graphics applets. <code>sgt</code> is not a general |
---|
36 | * purpose graphics package, but provides the tools to enable |
---|
37 | * scientific graphics to be easily incorporated into <code>Applets</code>. |
---|
38 | * <p> |
---|
39 | * <code>sgt</code> has three main components, the "pane", on which |
---|
40 | * all graphics are drawn. The <code>Pane</code> is a fairly simple |
---|
41 | * class and all drawing is done in "device" coordinates (pixels). |
---|
42 | * By default, the <code>Pane</code> will draw on the screen, but it is |
---|
43 | * designed to allow drawing in an offscreen buffer that can be |
---|
44 | * printed (for applications). |
---|
45 | * <p> |
---|
46 | * The next component is the <code>Layer</code>. Several |
---|
47 | * <code>Layers</code> can be associated with a single |
---|
48 | * <code>Pane</code>. The <code>Layer</code> class insulates |
---|
49 | * the developer from the details of device coordinates by |
---|
50 | * using "physical" coordinates. Physical coordinates are |
---|
51 | * a right-hand coordinate systems with an origin of (0.0, 0.0) in the |
---|
52 | * lower-left-hand corner and have the same scale in both the vertical |
---|
53 | * and horizontal directions. Thus, a <code>Layer</code> that is |
---|
54 | * 5.0 units wide and 3.0 units high can be made larger and smaller |
---|
55 | * on the screen by resizing the <code>Pane</code>, but will not be |
---|
56 | * distorted. The <code>Layer</code> class is responsible for |
---|
57 | * displaying labels, keys (color, vector, and line), and rulers. |
---|
58 | * A <code>Layer</code> can contain a single <code>Graph</code>. |
---|
59 | * <p> |
---|
60 | * Finally, the <code>Graph</code> component transforms from |
---|
61 | * user coordinates (e.g. cm/sec, time, degC, or meters) to |
---|
62 | * physical coordinates. The <code>Graph</code> |
---|
63 | * classes handle the display of axes and data. Children of |
---|
64 | * the <code>Graph</code> class are capable of creating Cartesian, |
---|
65 | * polar, and map graphics. For Cartesian graphs, several different |
---|
66 | * axes (log, plain and time), transforms (linear, log, and |
---|
67 | * tablelookup), and <code>CartesianGraph</code> (pixel, |
---|
68 | * line, vector, and contour) classes are available. These classes can be |
---|
69 | * combined in almost any combination. |
---|
70 | * <p> |
---|
71 | * While only one dataset may be plotted per <code>Layer</code>, |
---|
72 | * co-plotting is supported by allowing layers to use the same |
---|
73 | * transform objects. The order that the layers are plotted can |
---|
74 | * be changed, allowing the developer (or user) to control what |
---|
75 | * may be obscured. |
---|
76 | * <p> |
---|
77 | * Member functions, in package <code>gov.noaa.pmel.sgt</code>, |
---|
78 | * follow the following naming convention. Member functions that |
---|
79 | * have a <B>P</B>, <B>U</B>, or <I>nothing</I> at the end of the |
---|
80 | * function name are of type double in <B>P</B>hysical |
---|
81 | * units, type double in <B>U</B>ser units, and type int in Device |
---|
82 | * units, respectively. |
---|
83 | * Variables that start with p, u, t, or d are coordinates of type physical, |
---|
84 | * user, time, or device, respectively. |
---|
85 | * <p> |
---|
86 | * All graphics are rendered when the <code>draw()</code> method is invoked. |
---|
87 | * <p> |
---|
88 | * <B>Mouse Events</B> |
---|
89 | * <p> |
---|
90 | * Mouse events are processed by the <code>JPane</code> object to support |
---|
91 | * object selection and zooming. Object selection is accomplished by |
---|
92 | * left clicking the mouse on the desired object. <code>JPane</code> |
---|
93 | * then fires a <code>PropertyChangeEvent</code> of type |
---|
94 | * "objectSelected" that can be listened for by the users application. |
---|
95 | * The user application then invokes the |
---|
96 | * <code>getSelectedObject()</code> method. Zooming is accomplished in |
---|
97 | * several steps. |
---|
98 | * <p> |
---|
99 | * |
---|
100 | * <pre> |
---|
101 | * 1) Begin a zoom operation by pressing the left button. |
---|
102 | * 2) Describe a zoom rectangle by dragging the mouse with the left |
---|
103 | * button down. |
---|
104 | * 3) Finish the zoom operation by releasing the left mouse button. |
---|
105 | * </pre> |
---|
106 | * |
---|
107 | * <p> |
---|
108 | * When the mouse button has been release <code>JPane</code> fires a |
---|
109 | * <code>PropertyChangeEvent</code> of type "zoomRectangle" that can |
---|
110 | * be listened for by the users application. The user application can |
---|
111 | * then obtain the zoom rectangle by invoking the |
---|
112 | * <code>getZoomBounds()</code> method. |
---|
113 | * |
---|
114 | * <p> An example of object selection and zooming can be found in the |
---|
115 | * {@link JPane} documentation. |
---|
116 | * |
---|
117 | * @author Donald Denbo |
---|
118 | * @version $Revision: 1.23 $, $Date: 2003/09/19 23:14:24 $ |
---|
119 | * @since 1.0 |
---|
120 | * @deprecated As of sgt 3.0, use {@link gov.noaa.pmel.sgt.JPane JPane}. |
---|
121 | * @see Layer |
---|
122 | * @see Graph |
---|
123 | * @see java.awt.Graphics |
---|
124 | **/ |
---|
125 | public class Pane extends Container implements AbstractPane { |
---|
126 | // |
---|
127 | private PaneProxy proxy_; |
---|
128 | // |
---|
129 | /**@shapeType AggregationLink |
---|
130 | * @supplierCardinality 1..**/ |
---|
131 | /*# Layer lnkUnnamed*/ |
---|
132 | /** |
---|
133 | * Constructs a <code>Pane</code>. |
---|
134 | * |
---|
135 | * @param id the <code>Pane</code> identifier |
---|
136 | * @param size the size of the <code>Pane</code> in pixels |
---|
137 | **/ |
---|
138 | public Pane(String id, Dimension size) { |
---|
139 | proxy_ = new PaneProxy(this, id, size); |
---|
140 | setSize(size); |
---|
141 | // |
---|
142 | // setup for Low-Level Events |
---|
143 | // |
---|
144 | this.enableEvents(AWTEvent.MOUSE_EVENT_MASK | |
---|
145 | AWTEvent.MOUSE_MOTION_EVENT_MASK); |
---|
146 | } |
---|
147 | /** |
---|
148 | * Default constructor. The identifier is set to an empty string and |
---|
149 | * the size is set to a width and height of 50 pixels. A default constructor |
---|
150 | * is required to work as a component with Visual Cafe. |
---|
151 | * |
---|
152 | * <pre> |
---|
153 | * import gov.noaa.pmel.sgt.Pane; |
---|
154 | * ... |
---|
155 | * Pane pane; |
---|
156 | * ... |
---|
157 | * pane = new Pane("main graph", new Dimension(400, 500)); |
---|
158 | * pane.setLayout(new StackedLayout()); |
---|
159 | * ... |
---|
160 | * </pre> |
---|
161 | * |
---|
162 | * @see StackedLayout |
---|
163 | * |
---|
164 | **/ |
---|
165 | public Pane() { |
---|
166 | this(new String(""), new Dimension(50,50)); |
---|
167 | } |
---|
168 | /** |
---|
169 | * Return the version of SGT. |
---|
170 | * @since 3.0 |
---|
171 | */ |
---|
172 | public static String getVersion() { |
---|
173 | return PaneProxy.getVersion(); |
---|
174 | } |
---|
175 | public void draw() { |
---|
176 | proxy_.draw(); |
---|
177 | } |
---|
178 | /** |
---|
179 | * No initialization required by Pane. |
---|
180 | */ |
---|
181 | public void init() { |
---|
182 | } |
---|
183 | public void draw(Graphics g) { |
---|
184 | proxy_.draw(g); |
---|
185 | } |
---|
186 | public void draw(Graphics g, int width, int height) { |
---|
187 | proxy_.draw(g, width, height); |
---|
188 | } |
---|
189 | public boolean isPrinter() { |
---|
190 | return proxy_.isPrinter(); |
---|
191 | } |
---|
192 | /** |
---|
193 | * Internal access to jdk1.1 or Java2D line drawing. |
---|
194 | */ |
---|
195 | public static StrokeDrawer getStrokeDrawer() { |
---|
196 | return PaneProxy.strokeDrawer; |
---|
197 | } |
---|
198 | public Dimension getPageSize() { |
---|
199 | return proxy_.getPageSize(); |
---|
200 | } |
---|
201 | /** |
---|
202 | * Updates the <code>Pane</code> |
---|
203 | */ |
---|
204 | public void update(Graphics g) { |
---|
205 | if(Debug.DEBUG) System.out.println("Pane: " + proxy_.getId() + ": update(g)"); |
---|
206 | super.update(g); |
---|
207 | paint(g); |
---|
208 | } |
---|
209 | /** |
---|
210 | * Override of the parent <code>paint</code> method. This method should not be |
---|
211 | * called by a user. |
---|
212 | **/ |
---|
213 | public void paint(Graphics g) { |
---|
214 | proxy_.paint(g); |
---|
215 | } |
---|
216 | /** |
---|
217 | * Adds the specified component to the end of the <code>Pane</code>. |
---|
218 | * |
---|
219 | * @param comp the component to be added |
---|
220 | * @return component argument |
---|
221 | */ |
---|
222 | public Component add(Component comp) { |
---|
223 | if(comp instanceof Layer) { |
---|
224 | ((Layer)comp).setPane(this); |
---|
225 | } else if(comp instanceof LayerContainer) { |
---|
226 | ((LayerContainer)comp).setPane(this); |
---|
227 | } |
---|
228 | return super.add(comp); |
---|
229 | } |
---|
230 | /** |
---|
231 | * Adds the specified component to the <code>Pane</code> at the |
---|
232 | * given position. |
---|
233 | * |
---|
234 | * @param comp the component to be added |
---|
235 | * @param index the position at which to insert the component, or -1 |
---|
236 | to insert the component at the end. |
---|
237 | * @return component argument |
---|
238 | */ |
---|
239 | public Component add(Component comp, int index) { |
---|
240 | if(comp instanceof Layer) { |
---|
241 | ((Layer)comp).setPane(this); |
---|
242 | } else if(comp instanceof LayerContainer) { |
---|
243 | ((LayerContainer)comp).setPane(this); |
---|
244 | } |
---|
245 | return super.add(comp, index); |
---|
246 | } |
---|
247 | /** |
---|
248 | * Adds the specified component to the end of this <code>Pane</code>. |
---|
249 | * Also notifies the layout manager to add the component to this |
---|
250 | * <code>Pane</code>'s layout using the specified constraints object. |
---|
251 | * |
---|
252 | * @param comp the component to be added |
---|
253 | * @param constraints an object expressing layout constraints for |
---|
254 | this component |
---|
255 | */ |
---|
256 | public void add(Component comp, Object constraints) { |
---|
257 | super.add(comp, constraints); |
---|
258 | if(comp instanceof Layer) { |
---|
259 | ((Layer)comp).setPane(this); |
---|
260 | } else if(comp instanceof LayerContainer) { |
---|
261 | ((LayerContainer)comp).setPane(this); |
---|
262 | } |
---|
263 | } |
---|
264 | /** |
---|
265 | * Adds the specified component to the end of this <code>Pane</code> |
---|
266 | * at the specified index. |
---|
267 | * Also notifies the layout manager to add the component to this |
---|
268 | * <code>Pane</code>'s layout using the specified constraints object. |
---|
269 | * |
---|
270 | * @param comp the component to be added |
---|
271 | * @param constraints an object expressing layout constraints for |
---|
272 | this component |
---|
273 | * @param index the position in the <code>Pane</code>'s list at which to |
---|
274 | insert the component -1 means insert at the end. |
---|
275 | */ |
---|
276 | public void add(Component comp, Object constraints, int index) { |
---|
277 | super.add(comp, constraints, index); |
---|
278 | if(comp instanceof Layer) { |
---|
279 | ((Layer)comp).setPane(this); |
---|
280 | } else if(comp instanceof LayerContainer) { |
---|
281 | ((LayerContainer)comp).setPane(this); |
---|
282 | } |
---|
283 | } |
---|
284 | /** |
---|
285 | * Adds the specified component to this <code>Pane</code>. It |
---|
286 | * is strongly advised to use add(Component, Object), in place |
---|
287 | * of this method. |
---|
288 | */ |
---|
289 | public Component add(String name, Component comp) { |
---|
290 | if(comp instanceof Layer) { |
---|
291 | ((Layer)comp).setPane(this); |
---|
292 | } else if(comp instanceof LayerContainer) { |
---|
293 | ((LayerContainer)comp).setPane(this); |
---|
294 | } |
---|
295 | return super.add(name, comp); |
---|
296 | } |
---|
297 | |
---|
298 | public String getId() { |
---|
299 | return proxy_.getId(); |
---|
300 | } |
---|
301 | public void setId(String id) { |
---|
302 | proxy_.setId(id); |
---|
303 | } |
---|
304 | public void setPageAlign(int vert,int horz) { |
---|
305 | proxy_.setPageAlign(vert, horz); |
---|
306 | } |
---|
307 | public void setPageVAlign(int vert) { |
---|
308 | proxy_.setPageVAlign(vert); |
---|
309 | } |
---|
310 | public void setPageHAlign(int horz) { |
---|
311 | proxy_.setPageHAlign(horz); |
---|
312 | } |
---|
313 | public int getPageVAlign() { |
---|
314 | return proxy_.getPageVAlign(); |
---|
315 | } |
---|
316 | public int getPageHAlign() { |
---|
317 | return proxy_.getPageHAlign(); |
---|
318 | } |
---|
319 | public void setPageOrigin(Point p) { |
---|
320 | proxy_.setPageOrigin(p); |
---|
321 | } |
---|
322 | public Point getPageOrigin() { |
---|
323 | return proxy_.getPageOrigin(); |
---|
324 | } |
---|
325 | /** |
---|
326 | * Set the size. |
---|
327 | */ |
---|
328 | public void setSize(Dimension d) { |
---|
329 | super.setSize(d); |
---|
330 | proxy_.setSize(d); |
---|
331 | } |
---|
332 | public Layer getFirstLayer() { |
---|
333 | return proxy_.getFirstLayer(); |
---|
334 | } |
---|
335 | public Layer getLayer(String id) throws LayerNotFoundException { |
---|
336 | return proxy_.getLayer(id); |
---|
337 | } |
---|
338 | public Layer getLayerFromDataId(String id) throws LayerNotFoundException { |
---|
339 | return proxy_.getLayerFromDataId(id); |
---|
340 | } |
---|
341 | /** |
---|
342 | * Move the <code>Layer</code> up in the stack. |
---|
343 | * The order of the layers determine when they |
---|
344 | * are drawn. Moving the <code>Layer</code> up causes the |
---|
345 | * <code>Layer</code> to be drawn later and over earlier |
---|
346 | * layers. |
---|
347 | * |
---|
348 | * @param lyr <code>Layer</code> object. |
---|
349 | * @exception LayerNotFoundException The specified <code>Layer</code> was not found in the list. |
---|
350 | * @see Layer |
---|
351 | **/ |
---|
352 | public void moveLayerUp(Layer lyr) throws LayerNotFoundException { |
---|
353 | throw new MethodNotImplementedError(); |
---|
354 | } |
---|
355 | /** |
---|
356 | * Move the <code>Layer</code> up in the stack. |
---|
357 | * The order of the layers determine when they |
---|
358 | * are drawn. Moving the <code>Layer</code> up causes the |
---|
359 | * <code>Layer</code> to be drawn later and over earlier |
---|
360 | * layers. |
---|
361 | * |
---|
362 | * @param id identifier. |
---|
363 | * @exception LayerNotFoundException The specified <code>Layer</code> was not found in the list. |
---|
364 | * @see Layer |
---|
365 | **/ |
---|
366 | public void moveLayerUp(String id) throws LayerNotFoundException { |
---|
367 | throw new MethodNotImplementedError(); |
---|
368 | } |
---|
369 | /** |
---|
370 | * Move the <code>Layer</code> down in the stack. |
---|
371 | * The order of the layers determine when they |
---|
372 | * are drawn. Moving the <code>Layer</code> down causes the |
---|
373 | * <code>Layer</code> to be drawn earlier. |
---|
374 | * |
---|
375 | * @param lyr <code>Layer</code> object. |
---|
376 | * @exception LayerNotFoundException The specified <code>Layer</code> was not found in the list. |
---|
377 | * @see Layer |
---|
378 | **/ |
---|
379 | public void moveLayerDown(Layer lyr) throws LayerNotFoundException { |
---|
380 | throw new MethodNotImplementedError(); |
---|
381 | } |
---|
382 | /** |
---|
383 | * Move the <code>Layer</code> down in the stack. |
---|
384 | * The order of the layers determine when they |
---|
385 | * are drawn. Moving the <code>Layer</code> down causes the |
---|
386 | * <code>Layer</code> to be drawn earlier. |
---|
387 | * |
---|
388 | * @param id identifier |
---|
389 | * @exception LayerNotFoundException The specified <code>Layer</code> was not found in the list. |
---|
390 | * @see Layer |
---|
391 | **/ |
---|
392 | public void moveLayerDown(String id) throws LayerNotFoundException { |
---|
393 | throw new MethodNotImplementedError(); |
---|
394 | } |
---|
395 | public Object getSelectedObject() { |
---|
396 | return proxy_.getSelectedObject(); |
---|
397 | } |
---|
398 | public void setSelectedObject(Object obj) { |
---|
399 | proxy_.setSelectedObject(obj); |
---|
400 | } |
---|
401 | /** |
---|
402 | * Overrides the default event methods. |
---|
403 | **/ |
---|
404 | public void processMouseEvent(MouseEvent event) { |
---|
405 | if(!proxy_.processMouseEvent(event)) |
---|
406 | super.processMouseEvent(event); |
---|
407 | } |
---|
408 | |
---|
409 | public void processMouseMotionEvent(MouseEvent event) { |
---|
410 | if(!proxy_.processMouseMotionEvent(event)) |
---|
411 | super.processMouseMotionEvent(event); |
---|
412 | } |
---|
413 | public Rectangle getZoomBounds() { |
---|
414 | return proxy_.getZoomBounds(); |
---|
415 | } |
---|
416 | /** |
---|
417 | * @since 3.0 |
---|
418 | */ |
---|
419 | public Point getZoomStart() { |
---|
420 | return proxy_.getZoomStart(); |
---|
421 | } |
---|
422 | public Object getObjectAt(int x, int y) { |
---|
423 | return proxy_.getObjectAt(x, y); |
---|
424 | } |
---|
425 | /** |
---|
426 | * @since 3.0 |
---|
427 | */ |
---|
428 | public Object[] getObjectsAt(int x, int y) { |
---|
429 | return proxy_.getObjectsAt(x, y); |
---|
430 | } |
---|
431 | /** |
---|
432 | * @since 3.0 |
---|
433 | */ |
---|
434 | public Object[] getObjectsAt(Point pt) { |
---|
435 | return proxy_.getObjectsAt(pt.x, pt.y); |
---|
436 | } |
---|
437 | public Component getComponent() { |
---|
438 | return (Component)this; |
---|
439 | } |
---|
440 | public Dimension getMaximumSize() { |
---|
441 | return proxy_.getMaximumSize(); |
---|
442 | } |
---|
443 | public Dimension getMinimumSize() { |
---|
444 | return proxy_.getMinimumSize(); |
---|
445 | } |
---|
446 | public Dimension getPreferredSize() { |
---|
447 | return proxy_.getPreferredSize(); |
---|
448 | } |
---|
449 | /** |
---|
450 | * Get a <code>String</code> representatinof the |
---|
451 | * <code>Pane</code>. |
---|
452 | * |
---|
453 | * @return <code>String</code> representation |
---|
454 | */ |
---|
455 | public String toString() { |
---|
456 | return proxy_.toString(); |
---|
457 | } |
---|
458 | public void setBatch(boolean batch, String msg) { |
---|
459 | proxy_.setBatch(batch, msg); |
---|
460 | } |
---|
461 | public void setBatch(boolean batch) { |
---|
462 | proxy_.setBatch(batch, ""); |
---|
463 | } |
---|
464 | public boolean isBatch() { |
---|
465 | return proxy_.isBatch(); |
---|
466 | } |
---|
467 | public void setModified(boolean mod, String mess) { |
---|
468 | proxy_.setModified(mod, mess); |
---|
469 | } |
---|
470 | public boolean isModified() { |
---|
471 | return proxy_.isModified(); |
---|
472 | } |
---|
473 | /** |
---|
474 | * @since 3.0 |
---|
475 | */ |
---|
476 | public void setMouseEventsEnabled(boolean enable) { |
---|
477 | proxy_.setMouseEventsEnabled(enable); |
---|
478 | } |
---|
479 | /** |
---|
480 | * @since 3.0 |
---|
481 | */ |
---|
482 | public boolean isMouseEventsEnabled() { |
---|
483 | return proxy_.isMouseEventsEnabled(); |
---|
484 | } |
---|
485 | public void setPageScaleMode(int mode) { |
---|
486 | proxy_.setPageScaleMode(mode); |
---|
487 | } |
---|
488 | public int getPageScaleMode() { |
---|
489 | return proxy_.getPageScaleMode(); |
---|
490 | } |
---|
491 | /* |
---|
492 | * Pane PropertyChange methods |
---|
493 | */ |
---|
494 | public void addPropertyChangeListener(PropertyChangeListener l) { |
---|
495 | proxy_.addPropertyChangeListener(l); |
---|
496 | } |
---|
497 | public void removePropertyChangeListener(PropertyChangeListener l) { |
---|
498 | proxy_.removePropertyChangeListener(l); |
---|
499 | } |
---|
500 | } |
---|