KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > SystemEventQueueUtilities


1 /*
2  * @(#)SystemEventQueueUtilities.java 1.39 04/02/18
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package javax.swing;
8
9 import java.awt.*;
10 import java.awt.event.*;
11 import java.awt.image.*;
12
13 import java.util.*;
14
15 import java.lang.reflect.InvocationTargetException JavaDoc;
16
17 import sun.awt.AppContext;
18
19 /**
20  * Swing internal utilities for dealing with the AWT system event
21  * queue. Four methods are exported, see the individual method javadoc
22  * for more information: addRunnableCanvas(), removeRunnableCanvas(),
23  * postRunnable(), queueComponentWorkRequest().
24  *
25  * Note: most of the code in this class is no longer needed since
26  * we're no longer supporting Swing in 1.1.x VM's and in 1.2 we're
27  * guaranteed access to the AWT event queue. However all of the entry
28  * points, save postRunnable(), are still used.
29  *
30  * @see RepaintManager
31  * @see JRootPane
32  */

33 class SystemEventQueueUtilities
34 {
35     private static final Object JavaDoc classLock = new Object JavaDoc();
36
37
38     private static final Object JavaDoc rootTableKey =
39                 new StringBuffer JavaDoc("SystemEventQueueUtilties.rootTableKey");
40
41     private static Map getRootTable() {
42     Map rt = (Map)AppContext.getAppContext().get(rootTableKey);
43     if (rt == null) {
44         synchronized (rootTableKey) {
45         rt = (Map)AppContext.getAppContext().get(rootTableKey);
46         if (rt == null) {
47             rt = Collections.synchronizedMap(new WeakHashMap(4));
48             AppContext.getAppContext().put(rootTableKey, rt);
49         }
50         }
51     }
52     return rt;
53     }
54
55
56     /**
57      * SystemEventQueue class. This private class just exists to
58      * encapsulate the details of getting at the System Event queue
59      * in the Java 2 platform. The rest of the SystemEventQueueUtilities
60      * class just uses SystemEventQueue.get() to access the event queue.
61      */

62
63     private static class SystemEventQueue
64     {
65     // If the AWT system event queue is accessible then return it.
66
// otherwise return null.
67

68     static EventQueue get() {
69         EventQueue retValue;
70         try {
71             retValue = Toolkit.getDefaultToolkit().getSystemEventQueue();
72             }
73         catch (SecurityException JavaDoc se) {
74             // Should never happen.
75
retValue = null;
76             }
77             return retValue;
78     }
79
80     // If the AWT system event queue is accessible then return it.
81
// otherwise return null.
82
static EventQueue get(JRootPane JavaDoc rootPane) {
83         return get();
84     }
85     }
86
87     /**
88      * A Runnable with a component. If we need to post this
89      * runnable to the AWT system event queue, we'll find it's
90      * JRootPane ancestor and use that as the key to the table
91      * of RunnableCanvas's.
92      *
93      * @see RunnableCanvas
94      */

95     private static class ComponentWorkRequest implements Runnable JavaDoc
96     {
97     boolean isPending;
98     Component component;
99   
100     ComponentWorkRequest(Component c) {
101         /* As of 1.2, the component field is no longer used. It was
102          * used by the RunnableCanvas class to find the JRootPane
103          * associated with a ComponentWorkRequest for JDK1.1.x.
104          */

105         // component = c;
106
}
107     public void run() {
108         RepaintManager JavaDoc rm;
109         synchronized (this) {
110         rm = RepaintManager.currentManager(component /*null*/);
111         isPending = false;
112         }
113         rm.validateInvalidComponents();
114         rm.paintDirtyRegions();
115     }
116     }
117
118
119     /**
120      * This method is used by RepaintManager to queue a ComponentWorkRequest
121      * with invokeLater(). It assumes that the root argument is either
122      * and Applet or a Window, the root passed in obtained in a
123      * slightly different manner than see SwingUtilities.getRoot(). If this
124      * called with the root obtained in a different way than RepaintManager
125      * currently uses, be sure to also tweak removeRunnableCanvas.
126      */

127     static void queueComponentWorkRequest(Component root)
128     {
129     ComponentWorkRequest req = (ComponentWorkRequest)(getRootTable().get(root));
130     boolean newWorkRequest = (req == null);
131     if (newWorkRequest) {
132         req = new ComponentWorkRequest(root);
133     }
134
135     /* At this point the ComponentWorkRequest may be accessible from
136      * an event dispatching thread so before updating it further
137      * we synchronize access to it.
138      */

139     synchronized(req) {
140         if (newWorkRequest) {
141         getRootTable().put(root, req);
142         }
143         if (!req.isPending) {
144         SwingUtilities.invokeLater(req);
145         req.isPending = true;
146         }
147     }
148     }
149
150
151     /**
152      * Associate a RunnableCanvas and a JRootPane to enable queuing
153      * events for the root pane's parent window's event dispatching thread.
154      * Adds a 1x1 RunnableCanvas to the root pane's layered pane.
155      * <p>
156      * Called by JRootPane.addNotify() to set up the RunnableCanvas.
157      *
158      * @see RunnableCanvas
159      * @see JRootPane#addNotify
160      */

161     static void addRunnableCanvas(JRootPane JavaDoc rootPane)
162     {
163     synchronized (classLock) {
164         /* If we have access to the system event queue, we don't bother
165          * with a RunnableCanvas
166          */

167         if (SystemEventQueue.get(rootPane) != null) {
168         return;
169         }
170
171         JLayeredPane JavaDoc layeredPane = rootPane.getLayeredPane();
172         if (layeredPane != null) {
173         RunnableCanvas rc = new RunnableCanvas(rootPane);
174         layeredPane.add(rc);
175         }
176     }
177     }
178
179
180     /**
181      * Remove the RunnableCanvas from the JRootPane and clear the
182      * internal bookeeping associated with it.
183      * <p>
184      * Called by JRootPane.removeNotify()
185      *
186      * @see RunnableCanvas
187      */

188     static void removeRunnableCanvas(JRootPane JavaDoc rootPane) {
189     synchronized (classLock) {
190         // We don't use SwingUtilities.getRoot, as it has different
191
// behavior then the RepaintManager call to add the initial root.
192
Component root = null;
193         for (Component c = rootPane; c != null; c = c.getParent()) {
194         if ((c instanceof Window) ||
195             (c instanceof java.applet.Applet JavaDoc)) {
196             root = c;
197             break;
198         }
199         }
200         if (root != null) {
201         getRootTable().remove(root);
202         }
203         RunnableCanvas.remove(rootPane);
204     }
205     }
206
207
208     /**
209      * Post an event to the AWT System event queue that, when dispatched,
210      * will invoke the specified Runnable. If lock is non-null this call
211      * blocks (by waiting on the lock) until the doRun() method returns,
212      * otherwise we return as soon as the event has been enqueued. An
213      * exception is only returned if lock is non-null, i.e. if we're
214      * being called from invokeAndWait().
215      * <p>
216      * This method is only intended to support SwingUtilities.invokeLater()
217      * and SwingUtilities.invokeAndWait().
218      */

219     static Exception JavaDoc postRunnable(Runnable JavaDoc doRun, Object JavaDoc lock)
220     {
221     EventQueue systemEventQueue = SystemEventQueue.get();
222
223     RunnableEvent event = new RunnableEvent(doRun, lock);
224     if (systemEventQueue != null) {
225         systemEventQueue.postEvent(event);
226     }
227     else {
228         postRunnableCanvasEvent(event);
229     }
230     return event.exception;
231     }
232
233
234     /**
235      * Adds a RunnableEvent to all the remaining RunnableCanvases to restart
236      * the TimerQueues thread.
237      *
238      * @see RunnableCanvas#postRunnableEventToAll
239      */

240     static void restartTimerQueueThread() {
241     synchronized (classLock) {
242         if (SystemEventQueue.get() == null) {
243         Runnable JavaDoc restarter = new TimerQueueRestart();
244         RunnableEvent event = new RunnableEvent(restarter, null);
245         RunnableCanvas.postRunnableEventToAll(event);
246         }
247     }
248     }
249
250
251     /**
252      * Runnable that will message the shared instance of the Timer Queue
253      * to restart.
254      *
255      * @see #restartTimerQueueThread
256      */

257     private static class TimerQueueRestart implements Runnable JavaDoc {
258     boolean attemptedStart;
259
260     public synchronized void run() {
261         // Only try and restart the q once.
262
if(!attemptedStart) {
263         TimerQueue JavaDoc q = TimerQueue.sharedInstance();
264
265         synchronized(q) {
266             if(!q.running)
267             q.start();
268         }
269         attemptedStart = true;
270         }
271     }
272     }
273
274     /**
275      * Event type used for dispatching runnable objects for
276      * SwingUtilities.invokeLater() and SwingUtilities.invokeAndWait().
277      *
278      * @see #postRunnable
279      */

280     private static class RunnableEvent extends AWTEvent {
281         static final int EVENT_ID = AWTEvent.RESERVED_ID_MAX + 1000;
282     static final Component target = new RunnableTarget();
283     final Runnable JavaDoc doRun;
284     final Object JavaDoc lock;
285     Exception JavaDoc exception;
286
287         RunnableEvent(Runnable JavaDoc doRun, Object JavaDoc lock) {
288             super(target, EVENT_ID);
289         this.doRun = doRun;
290         this.lock = lock;
291         }
292     }
293
294
295     /**
296      * Calls RunnableEvent.doRun.run(). If RunnableEvent.lock is non
297      * null then we synchronize the run() call and save the exception
298      * (if any) in the RunnableEvent.exception field.
299      */

300     private static void processRunnableEvent(RunnableEvent runnableEvent)
301     {
302     Object JavaDoc lock = runnableEvent.lock;
303     if (lock == null) {
304         runnableEvent.doRun.run();
305     }
306     else {
307         synchronized(lock) {
308         try {
309             runnableEvent.doRun.run();
310         }
311         catch (Exception JavaDoc e) {
312             runnableEvent.exception = e;
313         }
314         finally {
315             if (runnableEvent.lock != null) {
316             runnableEvent.lock.notify();
317             }
318         }
319         }
320     }
321     }
322
323
324     /**
325      * A dummy Component subclass that (only) handles RunnableEvents. If the
326      * AWT System event queue is accessible (i.e. we're running as
327      * an application or as trusted code), RunnableEvents are dispatched
328      * to this component.
329      *
330      * @see #processRunnableEvent
331      */

332     private static class RunnableTarget extends Component
333     {
334         RunnableTarget() {
335             super();
336             enableEvents(RunnableEvent.EVENT_ID);
337         }
338
339         protected void processEvent(AWTEvent event) {
340         if (event instanceof RunnableEvent) {
341         processRunnableEvent((RunnableEvent)event);
342         }
343         }
344     }
345
346
347     /**
348      * Synchronized entry point to the applet support for AWT System
349      * event queue access. This method adds the event to the appropriate
350      * runnable canvas's queue and then has the canvas repaint(). Note
351      * that by the time the event dispatching thread gets to handling
352      * the repaint() (by calling runnableCanvas.update()), many runnable
353      * events may have been queued up.
354      *
355      * @see RunnableCanvas#addRunnableEvent
356      * @see RunnableCanvas#update
357      */

358     private static void postRunnableCanvasEvent(RunnableEvent e) {
359     synchronized (classLock) {
360         RunnableCanvas runnableCanvas = RunnableCanvas.lookup(e);
361
362         if (runnableCanvas == null) {
363
364         /* If this is a ComponentWorkRequest and we were unable to
365          * queue it, then clear the pending flag.
366          */

367         if (e.doRun instanceof ComponentWorkRequest) {
368             ComponentWorkRequest req = (ComponentWorkRequest)e.doRun;
369             synchronized(req) {
370             req.isPending = false;
371             }
372         }
373
374         /* If this is a Timer event let it know that it didn't fire.
375          */

376         if(e.doRun instanceof Timer.DoPostEvent JavaDoc) {
377             ((Timer.DoPostEvent JavaDoc)e.doRun).getTimer().cancelEvent();
378         }
379
380         /* We are unable to queue this event on a system event queue. Make
381          * sure that any code that's waiting for the runnable to finish
382          * doesn't hang.
383          */

384         if (e.lock != null) {
385             e.lock.notify();
386         }
387         return;
388         }
389
390         runnableCanvas.addRunnableEvent(e);
391         runnableCanvas.repaint();
392     }
393     }
394
395     
396     /**
397      * Return the current threads ThreadGroup, even on IE4.0.
398      * IE4.0 throws a SecurityException if you apply getThreadGroup()
399      * to the event dispatching thread. However a child of the
400      * event dispatching thread (same thread group) is OK.
401      */

402     private static ThreadGroup JavaDoc getThreadGroupSafely() {
403     return new Thread JavaDoc().getThreadGroup();
404     }
405
406
407     /**
408      * Applets don't have direct access to the AWT SystemEvent queue. To
409      * work around this we call RunnableCanvas.repaint() on a per applet
410      * instance of this class. The AWT deals with this by queuing a
411      * java.awt.PaintEvent for the event dispatching thread which
412      * is dispatched (Component.dispatchEvent()) the usual way.
413      * Component.dispatchEvent() handles PaintEvents by calling our update()
414      * method (on the event dispatching thread) which processes
415      * the RunnableEvents stashed in the runnableEvents vector.
416      */

417      private static class RunnableCanvas extends Canvas
418      {
419      private static final Graphics nullGraphics = new RunnableCanvasGraphics();
420      private static Hashtable runnableCanvasTable = new Hashtable(1);
421      private Vector runnableEvents = new Vector(2);
422      private boolean isRegistered = false;
423
424      RunnableCanvas(JRootPane JavaDoc rootPane) {
425          super();
426          setBounds(0, 0, 1, 1);
427
428          /* Remember the mapping from the current thread (and the current
429           * thread group) to this RunnableCanvas. Note that if a mapping
430           * has already been defined, e.g. this rootPane belongs to an
431           * existing applet, then leave the table alone. We're assuming that
432           * an applets addNotify method will always run before the addNotify
433           * method in any subsidiary windows the applet creates can run.
434           */

435          if (runnableCanvasTable.get(Thread.currentThread()) == null) {
436          try {
437              runnableCanvasTable.put(Thread.currentThread(), this);
438              runnableCanvasTable.put(getThreadGroupSafely(), this);
439              if (SwingUtilities.isEventDispatchThread()) {
440              isRegistered = true;
441              }
442          }
443          catch(Exception JavaDoc e) {
444              System.err.println("Can't register RunnableCanvas");
445              e.printStackTrace();
446          }
447          }
448          runnableCanvasTable.put(rootPane, this);
449          maybeRegisterEventDispatchThread();
450      }
451
452
453      /**
454       * If called on an event dispatching thread that we haven't seen
455       * before then make two hashtable entries in the runnableCanvasTable:
456       * <pre>
457       * current thread => this RunnableCanvas
458       * current thread group => this RunnableCanvas
459       * </pre>
460       * @see #lookup
461       */

462      private void maybeRegisterEventDispatchThread() {
463          /* Avoid the cost of a synchronized block (or method) in the
464           * common case, since this method is called each time paint is called.
465           */

466          if (!isRegistered) {
467          synchronized(this) {
468              if (!isRegistered && SwingUtilities.isEventDispatchThread()) {
469              Thread JavaDoc currentThread = Thread.currentThread();
470
471              /* If this event dispatching thread is already mapped to
472               * a runnableCanvas then don't replace the mapping (which
473               * we expect to be generated by the applet).
474               */

475              if (runnableCanvasTable.get(currentThread) != null) {
476                  isRegistered = true;
477              }
478              else {
479                  runnableCanvasTable.put(currentThread, this);
480                  runnableCanvasTable.put(getThreadGroupSafely(), this);
481                  isRegistered = true;
482              }
483              }
484          }
485          }
486      }
487
488
489      /**
490       * If we're running on the event dispatching thread then lookup
491       * the canvas with the current thread itself, otherwise use the
492       * current threads thread group. If there is no match for the
493       * ThreadGroup, the first visible RunnableCanvas is returned.
494       */

495      static RunnableCanvas lookup(RunnableEvent e)
496      {
497          /* If this is a ComponentWorkRequest, find the components
498           * JRootPane ancestor and use that as the index into the
499           * runnableCanvasTable. This case occurs when any thread,
500           * other than the event dispatching thead, calls repaint
501           */

502          if (e.doRun instanceof ComponentWorkRequest) {
503          ComponentWorkRequest req = (ComponentWorkRequest)e.doRun;
504          synchronized(req) {
505              JRootPane JavaDoc rootPane = SwingUtilities.getRootPane(req.component);
506              if(rootPane != null) {
507              return (RunnableCanvas)(runnableCanvasTable.get(rootPane));
508              }
509              /* Failure. There doesn't appear to be a RunnableCanvas to use
510               * so indicate that a new request will need to be queued, see
511               * RepaintManager.queueWorkRequest().
512               */

513              req.isPending = false;
514              return null;
515          }
516          }
517
518          /* If the current thread is in the runnableCanvasTable
519           * (e.g. we're on the event dispatching thread) we're done.
520           */

521          Object JavaDoc rv = runnableCanvasTable.get(Thread.currentThread());
522          if (rv != null) {
523          return (RunnableCanvas)rv;
524          }
525
526          /* At this point we're assuming that the calling thread isn't
527           * a system thread (like an image observer thread), so it's safe
528           * to lookup via the current threads ThreadGroup.
529           */

530          Object JavaDoc threadGroup;
531          try {
532          threadGroup = Thread.currentThread().getThreadGroup();
533          }
534          catch (SecurityException JavaDoc exc) {
535          return null;
536          }
537          RunnableCanvas rc = (RunnableCanvas)runnableCanvasTable.get(threadGroup);
538          
539          /* There's no RunnableCanvas associated with this thread group
540           * (so punt). Return the first visible RunnableCanvas.
541           */

542          if(rc == null) {
543          Enumeration keys = runnableCanvasTable.keys();
544          if(keys == null) {
545              return null;
546          }
547          while(keys.hasMoreElements()) {
548              Object JavaDoc key = keys.nextElement();
549              if ((key instanceof JRootPane JavaDoc) && ((JRootPane JavaDoc)key).isShowing()) {
550              return (RunnableCanvas)runnableCanvasTable.get(key);
551              }
552          }
553          }
554
555          return rc;
556      }
557
558
559      /**
560       * Adds the event to all the RunnableCanvases.
561       *
562       * @see #restartTimerQueueThread
563       */

564      static void postRunnableEventToAll(RunnableEvent e) {
565          // Determine the RunnableCanvas for the current thread. It
566
// may be null.
567
RunnableCanvas currentThreadCanvas;
568          ThreadGroup JavaDoc tg;
569          try {
570          tg = new Thread JavaDoc().getThreadGroup();
571          }
572          catch (SecurityException JavaDoc se) {
573          tg = null;
574          }
575          if(tg != null) {
576          currentThreadCanvas = (RunnableCanvas)runnableCanvasTable.
577                                 get(tg);
578          }
579          else
580          currentThreadCanvas = null;
581
582          // Add the event to all canvases, except the current one.
583
// Presumably the current one is no longer valid and will be
584
// going away shortly.
585
Enumeration keys = runnableCanvasTable.keys();
586          while(keys.hasMoreElements()) {
587          Object JavaDoc key = keys.nextElement();
588          if(key instanceof JRootPane JavaDoc) {
589              Object JavaDoc canvas = runnableCanvasTable.get(key);
590              if(canvas != currentThreadCanvas) {
591              RunnableCanvas rc = (RunnableCanvas)canvas;
592              rc.addRunnableEvent(e);
593              rc.repaint();
594              }
595          }
596          }
597      }
598
599
600      /**
601       * Remove the RunnableCanvas associated with this applet from the
602       * applets Layered pane and clear all of the runnableCanvasTable
603       * entries that point at it.
604       */

605      static void remove(JRootPane JavaDoc rootPane) {
606          RunnableCanvas rc = (RunnableCanvas)(runnableCanvasTable.get(rootPane));
607          if (rc != null) {
608          RunnableCanvas nextCanvas = null;
609          JLayeredPane JavaDoc layeredPane = rootPane.getLayeredPane();
610          layeredPane.remove((Component)rc);
611
612          Enumeration keys = runnableCanvasTable.keys();
613          while(keys.hasMoreElements()) {
614              Object JavaDoc key = keys.nextElement();
615              Object JavaDoc next = runnableCanvasTable.get(key);
616              if (rc == next) {
617              runnableCanvasTable.remove(key);
618              }
619              else if(nextCanvas == null) {
620              nextCanvas = (RunnableCanvas)next;
621              }
622          }
623
624          // If there are still events, either move them to another
625
// canvas, or mark the Timer type events as not having
626
// fired.
627
RunnableEvent[] events = rc.getRunnableCanvasEvents();
628          int numEvents = (events == null) ? 0 : events.length;
629          if(numEvents > 0) {
630              if(nextCanvas != null) {
631              for(int counter = 0; counter < numEvents; counter++) {
632                  RunnableEvent e = events[counter];
633                  if(e.doRun instanceof Timer.DoPostEvent JavaDoc)
634                  nextCanvas.addRunnableEvent(e);
635              }
636              nextCanvas.repaint();
637              }
638              else {
639              // Mark all Timer type event as not having fired.
640
for(int counter = 0; counter < numEvents; counter++) {
641                  RunnableEvent event = events[counter];
642                  if(event.doRun instanceof Timer.DoPostEvent JavaDoc) {
643                  ((Timer.DoPostEvent JavaDoc)event.doRun).getTimer().
644                                      cancelEvent();
645                  }
646              }
647              }
648          }
649          }
650      }
651
652
653      /**
654       * If there are events to be processed then we're showing. Note
655       * that the AWT code that dispatches paint events short circuits
656       * (does nothing) if isShowing() returns false.
657       */

658      public boolean isShowing() {
659          return runnableEvents.size() > 0;
660      }
661
662
663      /**
664       * Reduce the cost of repainting (since we're not going to draw
665       * anything) by returning a constant no-op graphics object.
666       */

667      public Graphics getGraphics() {
668          return nullGraphics;
669      }
670
671
672      /**
673       * Testing purposes only. This method shouldn't be called;
674       * the parent of this component should have a null layout
675       * manager.
676       */

677      public Dimension getPreferredSize() {
678          return new Dimension(1, 1);
679      }
680
681
682      /**
683       * Add a RunnableEvent to the queue that will be dispatched
684       * when this component is repainted.
685       * @see #update
686       */

687      synchronized void addRunnableEvent(RunnableEvent e) {
688          runnableEvents.addElement(e);
689      }
690
691
692      /**
693       * Return an (array) copy of the runnableEvents vector or
694       * null if the vector is empty. The update method processes
695       * a copy of the vector so that we don't have to hold
696       * the synchronized lock while calling processRunnableEvent().
697       * @see #update
698       */

699      private synchronized RunnableEvent[] getRunnableCanvasEvents() {
700          int n = runnableEvents.size();
701          if (n == 0) {
702          return null;
703          }
704          else {
705          RunnableEvent[] rv = new RunnableEvent[n];
706          for(int i = 0; i < n; i++) {
707              rv[i] = (RunnableEvent)(runnableEvents.elementAt(i));
708          }
709          runnableEvents.removeAllElements();
710          return rv;
711          }
712      }
713
714
715      public void paint(Graphics g) {
716          maybeRegisterEventDispatchThread();
717      }
718
719
720      /**
721       * Process all of the RunnableEvents that have accumulated
722       * since RunnableCanvas.repaint() was called.
723       */

724      public void update(Graphics g) {
725          RunnableEvent[] events = getRunnableCanvasEvents();
726          if (events != null) {
727          for(int i = 0; i < events.length; i++) {
728              processRunnableEvent(events[i]);
729          }
730          }
731      }
732     }
733
734
735     /**
736      * A no-op Graphics object for the RunnableCanvas component.
737      * Most AWT Component implementations handle update events
738      * like this:
739      * <pre>
740      * Graphics g = getGraphics();
741      * Rectangle r = ((PaintEvent)e).getUpdateRect();
742      * g.clipRect(r.x, r.y, r.width, r.height);
743      * update(g)
744      * g.dispose();
745      * </pre>
746      * Since the RunnableCanvas component isn't really going to do
747      * any painting we don't bother with creating/disposing real
748      * graphics objects, or setting any of the properties.
749      *
750      */

751     private static class RunnableCanvasGraphics extends Graphics
752     {
753     public Graphics create() {
754         return this;
755     }
756
757     /* We don't expect any of the following methods to be called but
758      * we still return marginally valid values for the get methods
759      * just in case.
760      */

761
762     public Rectangle getClipBounds() {
763         return new Rectangle(0, 0, Short.MAX_VALUE, Short.MAX_VALUE);
764     }
765
766     public Shape getClip() {
767         return (Shape)(getClipBounds());
768     }
769
770     public void dispose() {}
771     public void translate(int x, int y) {}
772     public Color getColor() { return Color.black; }
773     public void setColor(Color c) {}
774     public void setPaintMode() {}
775     public void setXORMode(Color c) {}
776     public Font getFont() { return null; }
777     public void setFont(Font font) {}
778     public FontMetrics getFontMetrics(Font f) { return null; }
779     public void clipRect(int x, int y, int width, int height) {}
780     public void setClip(int x, int y, int width, int height) {}
781     public void setClip(Shape clip) {}
782     public void copyArea(int x, int y, int w, int h, int dx, int dy) {}
783     public void drawLine(int x1, int y1, int x2, int y2) {}
784     public void fillRect(int x, int y, int width, int height) {}
785     public void clearRect(int x, int y, int width, int height) {}
786     public void drawRoundRect(int x, int y, int w, int h, int aw, int ah) {}
787     public void fillRoundRect(int x, int y, int w, int h, int aw, int ah) {}
788     public void drawOval(int x, int y, int w, int h) {}
789     public void fillOval(int x, int y, int w, int h) {}
790     public void drawArc(int x, int y, int w, int h, int sa, int aa) {}
791     public void fillArc(int x, int y, int w, int h, int sa, int aa) {}
792     public void drawPolyline(int xPoints[], int yPoints[], int nPoints) {}
793     public void drawPolygon(int xPoints[], int yPoints[], int nPoints) {}
794     public void fillPolygon(int xPoints[], int yPoints[], int nPoints) {}
795     public void drawString(String JavaDoc str, int x, int y) {}
796         public void drawString(java.text.AttributedCharacterIterator JavaDoc iterator, int x, int y) {}
797     public boolean drawImage(Image i, int x, int y, ImageObserver o) { return false; }
798     public boolean drawImage(Image i, int x, int y, int w, int h, ImageObserver o) { return false; }
799     public boolean drawImage(Image i, int x, int y, Color bgcolor, ImageObserver o) { return false; }
800     public boolean drawImage(Image i, int x, int y, int w, int h, Color c, ImageObserver o) { return false; }
801     public boolean drawImage(Image i,
802             int dx1, int dy1, int dx2, int dy2,
803         int sx1, int sy1, int sx2, int sy2, ImageObserver o)
804         { return false; }
805     public boolean drawImage(Image i,
806             int dx1, int dy1, int dx2, int dy2,
807         int sx1, int sy1, int sx2, int sy2, Color c, ImageObserver o)
808         { return false; }
809     }
810 }
811
Popular Tags