1 /* AWTUtilities.java -- Common utility methods for AWT and Swing.
2    Copyright (C) 2005, 2007  Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 package gnu.java.awt;
39 
40 import java.applet.Applet;
41 import java.awt.Component;
42 import java.awt.Container;
43 import java.awt.Font;
44 import java.awt.FontMetrics;
45 import java.awt.Insets;
46 import java.awt.Point;
47 import java.awt.Rectangle;
48 import java.awt.Toolkit;
49 import java.awt.Window;
50 import java.awt.event.KeyEvent;
51 import java.awt.event.MouseEvent;
52 import java.util.AbstractSequentialList;
53 import java.util.List;
54 import java.util.ListIterator;
55 import java.util.NoSuchElementException;
56 import java.util.WeakHashMap;
57 import java.lang.reflect.InvocationTargetException;
58 
59 /**
60  * This class mirrors the javax.swing.SwingUtilities class. It
61  * provides commonly needed functionalities for AWT classes without
62  * the need to reference classes in the javax.swing package.
63  */
64 public class AWTUtilities
65 {
66 
67   /**
68    * This List implementation wraps the Component[] returned by
69    * {@link Container#getComponents()} and iterates over the visible Components
70    * in that array. This class is used in {@link #getVisibleChildren}.
71    */
72   static class VisibleComponentList extends AbstractSequentialList
73   {
74     /**
75      * The ListIterator for this List.
76      */
77     class VisibleComponentIterator implements ListIterator
78     {
79       /** The current index in the Component[]. */
80       int index;
81 
82       /** The index in the List of visible Components. */
83       int listIndex;
84 
85       /**
86        * Creates a new VisibleComponentIterator that starts at the specified
87        * <code>listIndex</code>. The array of Components is searched from
88        * the beginning to find the matching array index.
89        *
90        * @param listIndex the index from where to begin iterating
91        */
VisibleComponentIterator(int listIndex)92       VisibleComponentIterator(int listIndex)
93       {
94         this.listIndex = listIndex;
95         int visibleComponentsFound = 0;
96         for (index = 0; visibleComponentsFound != listIndex; index++)
97           {
98             if (components[index].isVisible())
99               visibleComponentsFound++;
100           }
101       }
102 
103       /**
104        * Returns <code>true</code> if there are more visible components in the
105        * array, <code>false</code> otherwise.
106        *
107        * @return <code>true</code> if there are more visible components in the
108        *     array, <code>false</code> otherwise
109        */
hasNext()110       public boolean hasNext()
111       {
112         boolean hasNext = false;
113         for (int i = index; i < components.length; i++)
114           {
115             if (components[i].isVisible())
116               {
117                 hasNext = true;
118                 break;
119               }
120           }
121         return hasNext;
122       }
123 
124       /**
125        * Returns the next visible <code>Component</code> in the List.
126        *
127        * @return the next visible <code>Component</code> in the List
128        *
129        * @throws NoSuchElementException if there is no next element
130        */
next()131       public Object next()
132       {
133         Object o = null;
134         for (; index < components.length; index++)
135           {
136             if (components[index].isVisible())
137               {
138                 o = components[index];
139                 break;
140               }
141           }
142         if (o != null)
143           {
144             index++;
145             listIndex++;
146             return o;
147           }
148         else
149           throw new NoSuchElementException();
150       }
151 
152       /**
153        * Returns <code>true</code> if there are more visible components in the
154        * array in the reverse direction, <code>false</code> otherwise.
155        *
156        * @return <code>true</code> if there are more visible components in the
157        *     array in the reverse direction, <code>false</code> otherwise
158        */
hasPrevious()159       public boolean hasPrevious()
160       {
161         boolean hasPrevious = false;
162         for (int i = index - 1; i >= 0; i--)
163           {
164             if (components[i].isVisible())
165               {
166                 hasPrevious = true;
167                 break;
168               }
169           }
170         return hasPrevious;
171       }
172 
173       /**
174        * Returns the previous visible <code>Component</code> in the List.
175        *
176        * @return the previous visible <code>Component</code> in the List
177        *
178        * @throws NoSuchElementException if there is no previous element
179        */
previous()180       public Object previous()
181       {
182         Object o = null;
183         for (index--; index >= 0; index--)
184           {
185             if (components[index].isVisible())
186               {
187                 o = components[index];
188                 break;
189               }
190           }
191         if (o != null)
192           {
193             listIndex--;
194             return o;
195           }
196         else
197           throw new NoSuchElementException();
198       }
199 
200       /**
201        * Returns the index of the next element in the List.
202        *
203        * @return the index of the next element in the List
204        */
nextIndex()205       public int nextIndex()
206       {
207         return listIndex + 1;
208       }
209 
210       /**
211        * Returns the index of the previous element in the List.
212        *
213        * @return the index of the previous element in the List
214        */
previousIndex()215       public int previousIndex()
216       {
217         return listIndex - 1;
218       }
219 
220       /**
221        * This operation is not supported because the List is immutable.
222        *
223        * @throws UnsupportedOperationException because the List is immutable
224        */
remove()225       public void remove()
226       {
227         throw new UnsupportedOperationException
228           ("VisibleComponentList is immutable");
229       }
230 
231       /**
232        * This operation is not supported because the List is immutable.
233        *
234        * @param o not used here
235        *
236        * @throws UnsupportedOperationException because the List is immutable
237        */
set(Object o)238       public void set(Object o)
239       {
240         throw new UnsupportedOperationException
241           ("VisibleComponentList is immutable");
242       }
243 
244       /**
245        * This operation is not supported because the List is immutable.
246        *
247        * @param o not used here
248        *
249        * @throws UnsupportedOperationException because the List is immutable
250        */
add(Object o)251       public void add(Object o)
252       {
253         throw new UnsupportedOperationException
254           ("VisibleComponentList is immutable");
255       }
256     }
257 
258     /**
259      * The components over which we iterate. Only the visible components
260      * are returned by this List.
261      */
262     Component[] components;
263 
264     /**
265      * Creates a new instance of VisibleComponentList that wraps the specified
266      * <code>Component[]</code>.
267      *
268      * @param c the <code>Component[]</code> to be wrapped.
269      */
VisibleComponentList(Component[] c)270     VisibleComponentList(Component[] c)
271     {
272       components = c;
273     }
274 
275     /**
276      * Returns a {@link ListIterator} for iterating over this List.
277      *
278      * @return a {@link ListIterator} for iterating over this List
279      */
listIterator(int index)280     public ListIterator listIterator(int index)
281     {
282       return new VisibleComponentIterator(index);
283     }
284 
285     /**
286      * Returns the number of visible components in the wrapped Component[].
287      *
288      * @return the number of visible components
289      */
size()290     public int size()
291     {
292       int visibleComponents = 0;
293       for (int i = 0; i < components.length; i++)
294         if (components[i].isVisible())
295           visibleComponents++;
296       return visibleComponents;
297     }
298   }
299 
300   /**
301    * The cache for our List instances. We try to hold one instance of
302    * VisibleComponentList for each Component[] that is requested. Note
303    * that we use a WeakHashMap for caching, so that the cache itself
304    * does not keep the array or the List from beeing garbage collected
305    * if no other objects hold references to it.
306    */
307   static WeakHashMap visibleChildrenCache = new WeakHashMap();
308 
309   /**
310    * Returns the visible children of a {@link Container}. This method is
311    * commonly needed in LayoutManagers, because they only have to layout
312    * the visible children of a Container.
313    *
314    * @param c the Container from which to extract the visible children
315    *
316    * @return the visible children of <code>c</code>
317    */
getVisibleChildren(Container c)318   public static List getVisibleChildren(Container c)
319   {
320     Component[] children = c.getComponents();
321     Object o = visibleChildrenCache.get(children);
322     VisibleComponentList visibleChildren = null;
323     if (o == null)
324       {
325         visibleChildren = new VisibleComponentList(children);
326         visibleChildrenCache.put(children, visibleChildren);
327       }
328     else
329       visibleChildren = (VisibleComponentList) o;
330 
331     return visibleChildren;
332   }
333 
334   /**
335    * Calculates the portion of the base rectangle which is inside the
336    * insets.
337    *
338    * @param base The rectangle to apply the insets to
339    * @param insets The insets to apply to the base rectangle
340    * @param ret A rectangle to use for storing the return value, or
341    * <code>null</code>
342    *
343    * @return The calculated area inside the base rectangle and its insets,
344    * either stored in ret or a new Rectangle if ret is <code>null</code>
345    *
346    * @see #calculateInnerArea
347    */
calculateInsetArea(Rectangle base, Insets insets, Rectangle ret)348   public static Rectangle calculateInsetArea(Rectangle base, Insets insets,
349                                              Rectangle ret)
350   {
351     if (ret == null)
352       ret = new Rectangle();
353     ret.setBounds(base.x + insets.left, base.y + insets.top,
354         base.width - (insets.left + insets.right),
355         base.height - (insets.top + insets.bottom));
356     return ret;
357   }
358 
359   /**
360    * Calculates the bounds of a component in the component's own coordinate
361    * space. The result has the same height and width as the component's
362    * bounds, but its location is set to (0,0).
363    *
364    * @param aComponent The component to measure
365    *
366    * @return The component's bounds in its local coordinate space
367    */
getLocalBounds(Component aComponent)368   public static Rectangle getLocalBounds(Component aComponent)
369   {
370     Rectangle bounds = aComponent.getBounds();
371     return new Rectangle(0, 0, bounds.width, bounds.height);
372   }
373 
374   /**
375    * Returns the font metrics object for a given font. The metrics can be
376    * used to calculate crude bounding boxes and positioning information,
377    * for laying out components with textual elements.
378    *
379    * @param font The font to get metrics for
380    *
381    * @return The font's metrics
382    *
383    * @see java.awt.font.GlyphMetrics
384    */
getFontMetrics(Font font)385   public static FontMetrics getFontMetrics(Font font)
386   {
387     return Toolkit.getDefaultToolkit().getFontMetrics(font);
388   }
389 
390   /**
391    * Returns the least ancestor of <code>comp</code> which has the
392    * specified name.
393    *
394    * @param name The name to search for
395    * @param comp The component to search the ancestors of
396    *
397    * @return The nearest ancestor of <code>comp</code> with the given
398    * name, or <code>null</code> if no such ancestor exists
399    *
400    * @see java.awt.Component#getName
401    * @see #getAncestorOfClass
402    */
getAncestorNamed(String name, Component comp)403   public static Container getAncestorNamed(String name, Component comp)
404   {
405     while (comp != null && (comp.getName() != name))
406       comp = comp.getParent();
407     return (Container) comp;
408   }
409 
410   /**
411    * Returns the least ancestor of <code>comp</code> which is an instance
412    * of the specified class.
413    *
414    * @param c The class to search for
415    * @param comp The component to search the ancestors of
416    *
417    * @return The nearest ancestor of <code>comp</code> which is an instance
418    * of the given class, or <code>null</code> if no such ancestor exists
419    *
420    * @see #getAncestorOfClass
421    * @see #windowForComponent
422    * @see
423    *
424    */
getAncestorOfClass(Class c, Component comp)425   public static Container getAncestorOfClass(Class c, Component comp)
426   {
427     while (comp != null && (! c.isInstance(comp)))
428       comp = comp.getParent();
429     return (Container) comp;
430   }
431 
432   /**
433    * Equivalent to calling <code>getAncestorOfClass(Window, comp)</code>.
434    *
435    * @param comp The component to search for an ancestor window
436    *
437    * @return An ancestral window, or <code>null</code> if none exists
438    */
windowForComponent(Component comp)439   public static Window windowForComponent(Component comp)
440   {
441     return (Window) getAncestorOfClass(Window.class, comp);
442   }
443 
444   /**
445    * Returns the "root" of the component tree containint <code>comp</code>
446    * The root is defined as either the <em>least</em> ancestor of
447    * <code>comp</code> which is a {@link Window}, or the <em>greatest</em>
448    * ancestor of <code>comp</code> which is a {@link Applet} if no {@link
449    * Window} ancestors are found.
450    *
451    * @param comp The component to search for a root
452    *
453    * @return The root of the component's tree, or <code>null</code>
454    */
getRoot(Component comp)455   public static Component getRoot(Component comp)
456   {
457     Applet app = null;
458     Window win = null;
459 
460     while (comp != null)
461      {
462       if (win == null && comp instanceof Window)
463         win = (Window) comp;
464       else if (comp instanceof Applet)
465         app = (Applet) comp;
466       comp = comp.getParent();
467     }
468 
469     if (win != null)
470       return win;
471     else
472       return app;
473   }
474 
475   /**
476    * Return true if a descends from b, in other words if b is an
477    * ancestor of a.
478    *
479    * @param a The child to search the ancestry of
480    * @param b The potential ancestor to search for
481    *
482    * @return true if a is a descendent of b, false otherwise
483    */
isDescendingFrom(Component a, Component b)484   public static boolean isDescendingFrom(Component a, Component b)
485   {
486     while (true)
487      {
488       if (a == null || b == null)
489         return false;
490       if (a == b)
491         return true;
492       a = a.getParent();
493     }
494   }
495 
496   /**
497    * Returns the deepest descendent of parent which is both visible and
498    * contains the point <code>(x,y)</code>. Returns parent when either
499    * parent is not a container, or has no children which contain
500    * <code>(x,y)</code>. Returns <code>null</code> when either
501    * <code>(x,y)</code> is outside the bounds of parent, or parent is
502    * <code>null</code>.
503    *
504    * @param parent The component to search the descendents of
505    * @param x Horizontal coordinate to search for
506    * @param y Vertical coordinate to search for
507    *
508    * @return A component containing <code>(x,y)</code>, or
509    * <code>null</code>
510    *
511    * @see java.awt.Container#findComponentAt
512    */
getDeepestComponentAt(Component parent, int x, int y)513   public static Component getDeepestComponentAt(Component parent, int x, int y)
514   {
515     if (parent == null || (! parent.contains(x, y)))
516       return null;
517 
518     if (! (parent instanceof Container))
519       return parent;
520 
521     Container c = (Container) parent;
522     return c.findComponentAt(x, y);
523   }
524 
525   /**
526    * Converts a point from a component's local coordinate space to "screen"
527    * coordinates (such as the coordinate space mouse events are delivered
528    * in). This operation is equivalent to translating the point by the
529    * location of the component (which is the origin of its coordinate
530    * space).
531    *
532    * @param p The point to convert
533    * @param c The component which the point is expressed in terms of
534    *
535    * @see convertPointFromScreen
536    */
convertPointToScreen(Point p, Component c)537   public static void convertPointToScreen(Point p, Component c)
538   {
539     Point c0 = c.getLocationOnScreen();
540     p.translate(c0.x, c0.y);
541   }
542 
543   /**
544    * Converts a point from "screen" coordinates (such as the coordinate
545    * space mouse events are delivered in) to a component's local coordinate
546    * space. This operation is equivalent to translating the point by the
547    * negation of the component's location (which is the origin of its
548    * coordinate space).
549    *
550    * @param p The point to convert
551    * @param c The component which the point should be expressed in terms of
552    */
convertPointFromScreen(Point p, Component c)553   public static void convertPointFromScreen(Point p, Component c)
554   {
555     Point c0 = c.getLocationOnScreen();
556     p.translate(-c0.x, -c0.y);
557   }
558 
559   /**
560    * Converts a point <code>(x,y)</code> from the coordinate space of one
561    * component to another. This is equivalent to converting the point from
562    * <code>source</code> space to screen space, then back from screen space
563    * to <code>destination</code> space. If exactly one of the two
564    * Components is <code>null</code>, it is taken to refer to the root
565    * ancestor of the other component. If both are <code>null</code>, no
566    * transformation is done.
567    *
568    * @param source The component which the point is expressed in terms of
569    * @param x Horizontal coordinate of point to transform
570    * @param y Vertical coordinate of point to transform
571    * @param destination The component which the return value will be
572    * expressed in terms of
573    *
574    * @return The point <code>(x,y)</code> converted from the coordinate
575    *         space of the
576    * source component to the coordinate space of the destination component
577    *
578    * @see #convertPointToScreen
579    * @see #convertPointFromScreen
580    * @see #convertRectangle
581    * @see #getRoot
582    */
convertPoint(Component source, int x, int y, Component destination)583   public static Point convertPoint(Component source, int x, int y,
584                                    Component destination)
585   {
586     Point pt = new Point(x, y);
587 
588     if (source == null && destination == null)
589       return pt;
590 
591     if (source == null)
592       source = getRoot(destination);
593 
594     if (destination == null)
595       destination = getRoot(source);
596 
597     if (source.isShowing() && destination.isShowing())
598       {
599         convertPointToScreen(pt, source);
600         convertPointFromScreen(pt, destination);
601       }
602 
603     return pt;
604   }
605 
606 
607   /**
608    * Converts a rectangle from the coordinate space of one component to
609    * another. This is equivalent to converting the rectangle from
610    * <code>source</code> space to screen space, then back from screen space
611    * to <code>destination</code> space. If exactly one of the two
612    * Components is <code>null</code>, it is taken to refer to the root
613    * ancestor of the other component. If both are <code>null</code>, no
614    * transformation is done.
615    *
616    * @param source The component which the rectangle is expressed in terms of
617    * @param rect The rectangle to convert
618    * @param destination The component which the return value will be
619    * expressed in terms of
620    *
621    * @return A new rectangle, equal in size to the input rectangle, but
622    * with its position converted from the coordinate space of the source
623    * component to the coordinate space of the destination component
624    *
625    * @see #convertPointToScreen
626    * @see #convertPointFromScreen
627    * @see #convertPoint
628    * @see #getRoot
629    */
convertRectangle(Component source, Rectangle rect, Component destination)630   public static Rectangle convertRectangle(Component source, Rectangle rect,
631                                            Component destination)
632   {
633     Point pt = convertPoint(source, rect.x, rect.y, destination);
634     return new Rectangle(pt.x, pt.y, rect.width, rect.height);
635   }
636 
637   /**
638    * Convert a mouse event which refrers to one component to another.  This
639    * includes changing the mouse event's coordinate space, as well as the
640    * source property of the event. If <code>source</code> is
641    * <code>null</code>, it is taken to refer to <code>destination</code>'s
642    * root component. If <code>destination</code> is <code>null</code>, the
643    * new event will remain expressed in <code>source</code>'s coordinate
644    * system.
645    *
646    * @param source The component the mouse event currently refers to
647    * @param sourceEvent The mouse event to convert
648    * @param destination The component the new mouse event should refer to
649    *
650    * @return A new mouse event expressed in terms of the destination
651    * component's coordinate space, and with the destination component as
652    * its source
653    *
654    * @see #convertPoint
655    */
convertMouseEvent(Component source, MouseEvent sourceEvent, Component destination)656   public static MouseEvent convertMouseEvent(Component source,
657                                              MouseEvent sourceEvent,
658                                              Component destination)
659   {
660     Point newpt = convertPoint(source, sourceEvent.getX(), sourceEvent.getY(),
661                                destination);
662 
663     return new MouseEvent(destination, sourceEvent.getID(),
664                           sourceEvent.getWhen(), sourceEvent.getModifiers(),
665                           newpt.x, newpt.y, sourceEvent.getClickCount(),
666                           sourceEvent.isPopupTrigger(),
667                           sourceEvent.getButton());
668   }
669 
670 
671   /**
672    * Calls {@link java.awt.EventQueue.invokeLater} with the
673    * specified {@link Runnable}.
674    */
invokeLater(Runnable doRun)675   public static void invokeLater(Runnable doRun)
676   {
677     java.awt.EventQueue.invokeLater(doRun);
678   }
679 
680   /**
681    * Calls {@link java.awt.EventQueue.invokeAndWait} with the
682    * specified {@link Runnable}.
683    */
invokeAndWait(Runnable doRun)684   public static void invokeAndWait(Runnable doRun)
685   throws InterruptedException,
686   InvocationTargetException
687   {
688     java.awt.EventQueue.invokeAndWait(doRun);
689   }
690 
691   /**
692    * Calls {@link java.awt.EventQueue.isEventDispatchThread}.
693    */
isEventDispatchThread()694   public static boolean isEventDispatchThread()
695   {
696     return java.awt.EventQueue.isDispatchThread();
697   }
698 
699   /**
700    * Returns whether the specified key code is valid.
701    */
isValidKey(int keyCode)702   public static boolean isValidKey(int keyCode)
703   {
704     switch (keyCode)
705       {
706       case KeyEvent.VK_ENTER:
707       case KeyEvent.VK_BACK_SPACE:
708       case KeyEvent.VK_TAB:
709       case KeyEvent.VK_CANCEL:
710       case KeyEvent.VK_CLEAR:
711       case KeyEvent.VK_SHIFT:
712       case KeyEvent.VK_CONTROL:
713       case KeyEvent.VK_ALT:
714       case KeyEvent.VK_PAUSE:
715       case KeyEvent.VK_CAPS_LOCK:
716       case KeyEvent.VK_ESCAPE:
717       case KeyEvent.VK_SPACE:
718       case KeyEvent.VK_PAGE_UP:
719       case KeyEvent.VK_PAGE_DOWN:
720       case KeyEvent.VK_END:
721       case KeyEvent.VK_HOME:
722       case KeyEvent.VK_LEFT:
723       case KeyEvent.VK_UP:
724       case KeyEvent.VK_RIGHT:
725       case KeyEvent.VK_DOWN:
726       case KeyEvent.VK_COMMA:
727       case KeyEvent.VK_MINUS:
728       case KeyEvent.VK_PERIOD:
729       case KeyEvent.VK_SLASH:
730       case KeyEvent.VK_0:
731       case KeyEvent.VK_1:
732       case KeyEvent.VK_2:
733       case KeyEvent.VK_3:
734       case KeyEvent.VK_4:
735       case KeyEvent.VK_5:
736       case KeyEvent.VK_6:
737       case KeyEvent.VK_7:
738       case KeyEvent.VK_8:
739       case KeyEvent.VK_9:
740       case KeyEvent.VK_SEMICOLON:
741       case KeyEvent.VK_EQUALS:
742       case KeyEvent.VK_A:
743       case KeyEvent.VK_B:
744       case KeyEvent.VK_C:
745       case KeyEvent.VK_D:
746       case KeyEvent.VK_E:
747       case KeyEvent.VK_F:
748       case KeyEvent.VK_G:
749       case KeyEvent.VK_H:
750       case KeyEvent.VK_I:
751       case KeyEvent.VK_J:
752       case KeyEvent.VK_K:
753       case KeyEvent.VK_L:
754       case KeyEvent.VK_M:
755       case KeyEvent.VK_N:
756       case KeyEvent.VK_O:
757       case KeyEvent.VK_P:
758       case KeyEvent.VK_Q:
759       case KeyEvent.VK_R:
760       case KeyEvent.VK_S:
761       case KeyEvent.VK_T:
762       case KeyEvent.VK_U:
763       case KeyEvent.VK_V:
764       case KeyEvent.VK_W:
765       case KeyEvent.VK_X:
766       case KeyEvent.VK_Y:
767       case KeyEvent.VK_Z:
768       case KeyEvent.VK_OPEN_BRACKET:
769       case KeyEvent.VK_BACK_SLASH:
770       case KeyEvent.VK_CLOSE_BRACKET:
771       case KeyEvent.VK_NUMPAD0:
772       case KeyEvent.VK_NUMPAD1:
773       case KeyEvent.VK_NUMPAD2:
774       case KeyEvent.VK_NUMPAD3:
775       case KeyEvent.VK_NUMPAD4:
776       case KeyEvent.VK_NUMPAD5:
777       case KeyEvent.VK_NUMPAD6:
778       case KeyEvent.VK_NUMPAD7:
779       case KeyEvent.VK_NUMPAD8:
780       case KeyEvent.VK_NUMPAD9:
781       case KeyEvent.VK_MULTIPLY:
782       case KeyEvent.VK_ADD:
783       case KeyEvent.VK_SEPARATOR:
784       case KeyEvent.VK_SUBTRACT:
785       case KeyEvent.VK_DECIMAL:
786       case KeyEvent.VK_DIVIDE:
787       case KeyEvent.VK_DELETE:
788       case KeyEvent.VK_NUM_LOCK:
789       case KeyEvent.VK_SCROLL_LOCK:
790       case KeyEvent.VK_F1:
791       case KeyEvent.VK_F2:
792       case KeyEvent.VK_F3:
793       case KeyEvent.VK_F4:
794       case KeyEvent.VK_F5:
795       case KeyEvent.VK_F6:
796       case KeyEvent.VK_F7:
797       case KeyEvent.VK_F8:
798       case KeyEvent.VK_F9:
799       case KeyEvent.VK_F10:
800       case KeyEvent.VK_F11:
801       case KeyEvent.VK_F12:
802       case KeyEvent.VK_F13:
803       case KeyEvent.VK_F14:
804       case KeyEvent.VK_F15:
805       case KeyEvent.VK_F16:
806       case KeyEvent.VK_F17:
807       case KeyEvent.VK_F18:
808       case KeyEvent.VK_F19:
809       case KeyEvent.VK_F20:
810       case KeyEvent.VK_F21:
811       case KeyEvent.VK_F22:
812       case KeyEvent.VK_F23:
813       case KeyEvent.VK_F24:
814       case KeyEvent.VK_PRINTSCREEN:
815       case KeyEvent.VK_INSERT:
816       case KeyEvent.VK_HELP:
817       case KeyEvent.VK_META:
818       case KeyEvent.VK_BACK_QUOTE:
819       case KeyEvent.VK_QUOTE:
820       case KeyEvent.VK_KP_UP:
821       case KeyEvent.VK_KP_DOWN:
822       case KeyEvent.VK_KP_LEFT:
823       case KeyEvent.VK_KP_RIGHT:
824       case KeyEvent.VK_DEAD_GRAVE:
825       case KeyEvent.VK_DEAD_ACUTE:
826       case KeyEvent.VK_DEAD_CIRCUMFLEX:
827       case KeyEvent.VK_DEAD_TILDE:
828       case KeyEvent.VK_DEAD_MACRON:
829       case KeyEvent.VK_DEAD_BREVE:
830       case KeyEvent.VK_DEAD_ABOVEDOT:
831       case KeyEvent.VK_DEAD_DIAERESIS:
832       case KeyEvent.VK_DEAD_ABOVERING:
833       case KeyEvent.VK_DEAD_DOUBLEACUTE:
834       case KeyEvent.VK_DEAD_CARON:
835       case KeyEvent.VK_DEAD_CEDILLA:
836       case KeyEvent.VK_DEAD_OGONEK:
837       case KeyEvent.VK_DEAD_IOTA:
838       case KeyEvent.VK_DEAD_VOICED_SOUND:
839       case KeyEvent.VK_DEAD_SEMIVOICED_SOUND:
840       case KeyEvent.VK_AMPERSAND:
841       case KeyEvent.VK_ASTERISK:
842       case KeyEvent.VK_QUOTEDBL:
843       case KeyEvent.VK_LESS:
844       case KeyEvent.VK_GREATER:
845       case KeyEvent.VK_BRACELEFT:
846       case KeyEvent.VK_BRACERIGHT:
847       case KeyEvent.VK_AT:
848       case KeyEvent.VK_COLON:
849       case KeyEvent.VK_CIRCUMFLEX:
850       case KeyEvent.VK_DOLLAR:
851       case KeyEvent.VK_EURO_SIGN:
852       case KeyEvent.VK_EXCLAMATION_MARK:
853       case KeyEvent.VK_INVERTED_EXCLAMATION_MARK:
854       case KeyEvent.VK_LEFT_PARENTHESIS:
855       case KeyEvent.VK_NUMBER_SIGN:
856       case KeyEvent.VK_PLUS:
857       case KeyEvent.VK_RIGHT_PARENTHESIS:
858       case KeyEvent.VK_UNDERSCORE:
859       case KeyEvent.VK_FINAL:
860       case KeyEvent.VK_CONVERT:
861       case KeyEvent.VK_NONCONVERT:
862       case KeyEvent.VK_ACCEPT:
863       case KeyEvent.VK_MODECHANGE:
864       case KeyEvent.VK_KANA:
865       case KeyEvent.VK_KANJI:
866       case KeyEvent.VK_ALPHANUMERIC:
867       case KeyEvent.VK_KATAKANA:
868       case KeyEvent.VK_HIRAGANA:
869       case KeyEvent.VK_FULL_WIDTH:
870       case KeyEvent.VK_HALF_WIDTH:
871       case KeyEvent.VK_ROMAN_CHARACTERS:
872       case KeyEvent.VK_ALL_CANDIDATES:
873       case KeyEvent.VK_PREVIOUS_CANDIDATE:
874       case KeyEvent.VK_CODE_INPUT:
875       case KeyEvent.VK_JAPANESE_KATAKANA:
876       case KeyEvent.VK_JAPANESE_HIRAGANA:
877       case KeyEvent.VK_JAPANESE_ROMAN:
878       case KeyEvent.VK_KANA_LOCK:
879       case KeyEvent.VK_INPUT_METHOD_ON_OFF:
880       case KeyEvent.VK_CUT:
881       case KeyEvent.VK_COPY:
882       case KeyEvent.VK_PASTE:
883       case KeyEvent.VK_UNDO:
884       case KeyEvent.VK_AGAIN:
885       case KeyEvent.VK_FIND:
886       case KeyEvent.VK_PROPS:
887       case KeyEvent.VK_STOP:
888       case KeyEvent.VK_COMPOSE:
889       case KeyEvent.VK_ALT_GRAPH:
890       case KeyEvent.VK_BEGIN:
891       case KeyEvent.VK_CONTEXT_MENU:
892       case KeyEvent.VK_WINDOWS:
893         return true;
894       default:
895         return false;
896       }
897   }
898 }
899