Java/Swing JFC/Swing Utilities

Материал из Java эксперт
Версия от 18:01, 31 мая 2010; (обсуждение)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Center that window on the given desktop.

 
/*
 * $Id: WindowUtils.java,v 1.16 2009/05/25 16:37:52 kschaefe Exp $
 *
 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.JInternalFrame;
/**
 * Encapsulates various utilities for windows (ie: <code>Frame</code> and
 * <code>Dialog</code> objects and descendants, in particular).
 *
 * @author Richard Bair
 */
public class Utils {
  /**
   * <p/>
   * Returns the <code>Point</code> at which a window should be placed to
   * center that window on the given desktop.
   * </p>
   * <p/>
   * Some thought was taken as to whether to implement a method such as this,
   * or to simply make a method that, given a window, will center it.  It was
   * decided that it is better to not alter an object within a method.
   * </p>
   *
   * @param window  The window (JInternalFrame) to calculate the center point
   *                for.  This object can not be null.
   *
   * @return the <code>Point</code> at which the window should be placed to
   *         center that window on the given desktop
   */
  public static Point getPointForCentering(JInternalFrame window) {
      try {
          //assert window != null;
          Point mousePoint = MouseInfo.getPointerInfo().getLocation();
          GraphicsDevice[] devices = GraphicsEnvironment
                  .getLocalGraphicsEnvironment().getScreenDevices();
          for (GraphicsDevice device : devices) {
              Rectangle bounds = device.getDefaultConfiguration().getBounds();
              //check to see if the mouse cursor is within these bounds
              if (mousePoint.x >= bounds.x && mousePoint.y >= bounds.y
                  && mousePoint.x <= (bounds.x + bounds.width)
                  && mousePoint.y <= (bounds.y + bounds.height)) {
                  //this is it
                  int screenWidth = bounds.width;
                  int screenHeight = bounds.height;
                  int width = window.getWidth();
                  int height = window.getHeight();
                  return new Point(((screenWidth - width) / 2) + bounds.x,
                                      ((screenHeight - height) / 2) + bounds
                                              .y);
              }
          }
      } catch (Exception e) {
         
      }
      return new Point(0, 0);
  }
}





Change the sizes of all the passed buttons to be the size of the largest one.

   
/*
 * Copyright (C) 2001-2004 Colin Bell
 * colbell@users.sourceforge.net
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

import java.awt.ruponent;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.geom.Rectangle2D;
import java.beans.PropertyVetoException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.SwingUtilities;
/**
 * Common GUI utilities accessed via static methods.
 * 
 * @author 
 */
public class GUIUtils {

  /**
   * Change the sizes of all the passed buttons to be the size of the largest
   * one.
   * 
   * @param btns
   *          Array of buttons to eb resized.
   * 
   * @throws IllegalArgumentException
   *           If <TT>btns</TT> is <TT>null</TT>.
   */
  public static void setJButtonSizesTheSame(JButton[] btns) {
    if (btns == null) {
      throw new IllegalArgumentException("null JButton[] passed");
    }
    // Get the largest width and height
    final Dimension maxSize = new Dimension(0, 0);
    for (int i = 0; i < btns.length; ++i) {
      final JButton btn = btns[i];
      final FontMetrics fm = btn.getFontMetrics(btn.getFont());
      Rectangle2D bounds = fm.getStringBounds(btn.getText(), btn.getGraphics());
      int boundsHeight = (int) bounds.getHeight();
      int boundsWidth = (int) bounds.getWidth();
      maxSize.width = boundsWidth > maxSize.width ? boundsWidth : maxSize.width;
      maxSize.height = boundsHeight > maxSize.height ? boundsHeight : maxSize.height;
    }
    Insets insets = btns[0].getInsets();
    maxSize.width += insets.left + insets.right;
    maxSize.height += insets.top + insets.bottom;
    for (int i = 0; i < btns.length; ++i) {
      JButton btn = btns[i];
      btn.setPreferredSize(maxSize);
    }
  }
}





Convert a coordinate on a screen to a coordinate relative to a component"s bounds

  
    
import java.awt.Point;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
public class Main {
  public static void main(String[] argv) {
    JButton component = new JButton();
    Point pt = new Point(component.getLocation());
    SwingUtilities.convertPointFromScreen(pt, component);
  }
}





Convert a coordinate relative to a component"s bounds to screen coordinates

  
import java.awt.Point;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
public class Main {
  public static void main(String[] argv) {

    JButton component = new JButton();
    Point pt = new Point(component.getLocation());
    SwingUtilities.convertPointToScreen(pt, component);
  }
}





Converts a Swing key stroke descriptor to a familiar Emacs-like name

 
/*
 * $Id: Utilities.java,v 1.11 2008/10/14 22:31:46 rah003 Exp $
 *
 * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

import java.awt.ruponent;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
/**
 * Contribution from NetBeans: Issue #319-swingx.
 * <p>
 * 
 * PENDING: need to reconcile with OS, JVM... added as-is because needed the
 * shortcut handling to fix #
 * 
 * @author apple
 */
public class Utilities {
    private Utilities() {
    }
    
    private static final int CTRL_WILDCARD_MASK = 32768;
    private static final int ALT_WILDCARD_MASK = CTRL_WILDCARD_MASK * 2;
    
    /** Operating system is Windows NT. */
    public static final int OS_WINNT = 1 << 0;
    /** Operating system is Windows 95. */
    public static final int OS_WIN95 = OS_WINNT << 1;
    /** Operating system is Windows 98. */
    public static final int OS_WIN98 = OS_WIN95 << 1;
    /** Operating system is Solaris. */
    public static final int OS_SOLARIS = OS_WIN98 << 1;
    /** Operating system is Linux. */
    public static final int OS_LINUX = OS_SOLARIS << 1;
    /** Operating system is HP-UX. */
    public static final int OS_HP = OS_LINUX << 1;
    /** Operating system is IBM AIX. */
    public static final int OS_AIX = OS_HP << 1;
    /** Operating system is SGI IRIX. */
    public static final int OS_IRIX = OS_AIX << 1;
    /** Operating system is Sun OS. */
    public static final int OS_SUNOS = OS_IRIX << 1;
    /** Operating system is Compaq TRU64 Unix */
    public static final int OS_TRU64 = OS_SUNOS << 1;
    /** Operating system is OS/2. */
    public static final int OS_OS2 = OS_TRU64 << 2;
    /** Operating system is Mac. */
    public static final int OS_MAC = OS_OS2 << 1;
    /** Operating system is Windows 2000. */
    public static final int OS_WIN2000 = OS_MAC << 1;
    /** Operating system is Compaq OpenVMS */
    public static final int OS_VMS = OS_WIN2000 << 1;
    /**
     *Operating system is one of the Windows variants but we don"t know which
     *one it is
     */
    public static final int OS_WIN_OTHER = OS_VMS << 1;
    /** Operating system is unknown. */
    public static final int OS_OTHER = OS_WIN_OTHER << 1;
    /** Operating system is FreeBSD
     * @since 4.50
     */
    public static final int OS_FREEBSD = OS_OTHER << 1;
    /** A mask for Windows platforms. */
    public static final int OS_WINDOWS_MASK = OS_WINNT | OS_WIN95 | OS_WIN98 | OS_WIN2000 | OS_WIN_OTHER;
    /** A mask for Unix platforms. */
    public static final int OS_UNIX_MASK = OS_SOLARIS | OS_LINUX | OS_HP | OS_AIX | OS_IRIX | OS_SUNOS | OS_TRU64 |
        OS_MAC | OS_FREEBSD;
    /** A height of the windows"s taskbar */
    public static final int TYPICAL_WINDOWS_TASKBAR_HEIGHT = 27;
    /** A height of the Mac OS X"s menu */
    private static final int TYPICAL_MACOSX_MENU_HEIGHT = 24;
    
    private static int operatingSystem = -1;
    
    /** reference to map that maps allowed key names to their values (String, Integer)
    and reference to map for mapping of values to their names */
    private static Reference<Object> namesAndValues;
    /** Get the operating system.
    * @return one of the <code>OS_*</code> constants (such as {@link #OS_WINNT})
    */
    public static int getOperatingSystem() {
        if (operatingSystem == -1) {
            String osName = System.getProperty("os.name");
            if ("Windows NT".equals(osName)) { // NOI18N
                operatingSystem = OS_WINNT;
            } else if ("Windows 95".equals(osName)) { // NOI18N
                operatingSystem = OS_WIN95;
            } else if ("Windows 98".equals(osName)) { // NOI18N
                operatingSystem = OS_WIN98;
            } else if ("Windows 2000".equals(osName)) { // NOI18N
                operatingSystem = OS_WIN2000;
            } else if (osName.startsWith("Windows ")) { // NOI18N
                operatingSystem = OS_WIN_OTHER;
            } else if ("Solaris".equals(osName)) { // NOI18N
                operatingSystem = OS_SOLARIS;
            } else if (osName.startsWith("SunOS")) { // NOI18N
                operatingSystem = OS_SOLARIS;
            }
            // JDK 1.4 b2 defines os.name for me as "Redhat Linux" -jglick
            else if (osName.endsWith("Linux")) { // NOI18N
                operatingSystem = OS_LINUX;
            } else if ("HP-UX".equals(osName)) { // NOI18N
                operatingSystem = OS_HP;
            } else if ("AIX".equals(osName)) { // NOI18N
                operatingSystem = OS_AIX;
            } else if ("Irix".equals(osName)) { // NOI18N
                operatingSystem = OS_IRIX;
            } else if ("SunOS".equals(osName)) { // NOI18N
                operatingSystem = OS_SUNOS;
            } else if ("Digital UNIX".equals(osName)) { // NOI18N
                operatingSystem = OS_TRU64;
            } else if ("OS/2".equals(osName)) { // NOI18N
                operatingSystem = OS_OS2;
            } else if ("OpenVMS".equals(osName)) { // NOI18N
                operatingSystem = OS_VMS;
            } else if (osName.equals("Mac OS X")) { // NOI18N
                operatingSystem = OS_MAC;
            } else if (osName.startsWith("Darwin")) { // NOI18N
                operatingSystem = OS_MAC;
            } else if (osName.toLowerCase(Locale.US).startsWith("freebsd")) { // NOI18N 
                operatingSystem = OS_FREEBSD;
            } else {
                operatingSystem = OS_OTHER;
            }
        }
        return operatingSystem;
    }

    /**
     * Finds out the monitor where the user currently has the input focus.
     * This method is usually used to help the client code to figure out on
     * which monitor it should place newly created windows/frames/dialogs.
     *
     * @return the GraphicsConfiguration of the monitor which currently has the
     * input focus
     */
    private static GraphicsConfiguration getCurrentGraphicsConfiguration() {
        Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
        if (focusOwner != null) {
            Window w = SwingUtilities.getWindowAncestor(focusOwner);
            if (w != null) {
                return w.getGraphicsConfiguration();
            }
        }
        return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    }
    /**
     * Returns the usable area of the screen where applications can place its
     * windows.  The method subtracts from the screen the area of taskbars,
     * system menus and the like.  The screen this method applies to is the one
     * which is considered current, ussually the one where the current input
     * focus is.
     *
     * @return the rectangle of the screen where one can place windows
     *
     * @since 2.5
     */
    public static Rectangle getUsableScreenBounds() {
        return getUsableScreenBounds(getCurrentGraphicsConfiguration());
    }
    /**
     * Returns the usable area of the screen where applications can place its
     * windows.  The method subtracts from the screen the area of taskbars,
     * system menus and the like.
     *
     * @param gconf the GraphicsConfiguration of the monitor
     * @return the rectangle of the screen where one can place windows
     *
     * @since 2.5
     */
    public static Rectangle getUsableScreenBounds(GraphicsConfiguration gconf) {
        if (gconf == null) {
            gconf = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
        }
        Rectangle bounds = new Rectangle(gconf.getBounds());
        String str;
        str = System.getProperty("netbeans.screen.insets"); // NOI18N
        if (str != null) {
            StringTokenizer st = new StringTokenizer(str, ", "); // NOI18N
            if (st.countTokens() == 4) {
                try {
                    bounds.y = Integer.parseInt(st.nextToken());
                    bounds.x = Integer.parseInt(st.nextToken());
                    bounds.height -= (bounds.y + Integer.parseInt(st.nextToken()));
                    bounds.width -= (bounds.x + Integer.parseInt(st.nextToken()));
                } catch (NumberFormatException ex) {
                    Logger.getAnonymousLogger().log(Level.WARNING, null, ex);
                }
            }
            return bounds;
        }
        str = System.getProperty("netbeans.taskbar.height"); // NOI18N
        if (str != null) {
            bounds.height -= Integer.getInteger(str, 0).intValue();
            return bounds;
        }
        try {
            Toolkit toolkit = Toolkit.getDefaultToolkit();
            Insets insets = toolkit.getScreenInsets(gconf);
            bounds.y += insets.top;
            bounds.x += insets.left;
            bounds.height -= (insets.top + insets.bottom);
            bounds.width -= (insets.left + insets.right);
        } catch (Exception ex) {
            Logger.getAnonymousLogger().log(Level.WARNING, null, ex);
        }
        return bounds;
    }
    
    /** Initialization of the names and values
    * @return array of two hashmaps first maps
    *   allowed key names to their values (String, Integer)
    *  and second
    * hashtable for mapping of values to their names (Integer, String)
    */
    private static synchronized HashMap[] initNameAndValues() {
        if (namesAndValues != null) {
            HashMap[] arr = (HashMap[]) namesAndValues.get();
            if (arr != null) {
                return arr;
            }
        }
        Field[] fields;
        // JW - fix Issue #353-swingx: play nicer inside sandbox.
        try {
            fields = KeyEvent.class.getDeclaredFields();
//           fields = KeyEvent.class.getFields();
        } catch (SecurityException e) { 
            // JW: need to do better? What are the use-cases where we don"t have
            // any access to the fields?
            fields = new Field[0];
        }
        HashMap<String,Integer> names = new HashMap<String,Integer>(((fields.length * 4) / 3) + 5, 0.75f);
        HashMap<Integer,String> values = new HashMap<Integer,String>(((fields.length * 4) / 3) + 5, 0.75f);
        for (int i = 0; i < fields.length; i++) {
            if (Modifier.isStatic(fields[i].getModifiers())) {
                String name = fields[i].getName();
                if (name.startsWith("VK_")) { // NOI18N
                    // exclude VK
                    name = name.substring(3);
                    try {
                        int numb = fields[i].getInt(null);
                        Integer value = new Integer(numb);
                        names.put(name, value);
                        values.put(value, name);
                    } catch (IllegalArgumentException ex) {
                    } catch (IllegalAccessException ex) {
                    }
                }
            }
        }
        if (names.get("CONTEXT_MENU") == null) { // NOI18N
            Integer n = new Integer(0x20C);
            names.put("CONTEXT_MENU", n); // NOI18N
            values.put(n, "CONTEXT_MENU"); // NOI18N
            n = new Integer(0x20D);
            names.put("WINDOWS", n); // NOI18N
            values.put(n, "WINDOWS"); // NOI18N
        }
        HashMap[] arr = { names, values };
        namesAndValues = new SoftReference<Object>(arr);
        return arr;
    }
    /** Converts a Swing key stroke descriptor to a familiar Emacs-like name.
    * @param stroke key description
    * @return name of the key (e.g. <code>CS-F1</code> for control-shift-function key one)
    * @see #stringToKey
    */
    public static String keyToString(KeyStroke stroke) {
        StringBuffer sb = new StringBuffer();
        // add modifiers that must be pressed
        if (addModifiers(sb, stroke.getModifiers())) {
            sb.append("-");
        }
        HashMap[] namesAndValues = initNameAndValues();
        String c = (String) namesAndValues[1].get(new Integer(stroke.getKeyCode()));
        if (c == null) {
            sb.append(stroke.getKeyChar());
        } else {
            sb.append(c);
        }
        return sb.toString();
    }
    /** Construct a new key description from a given universal string
    * description.
    * Provides mapping between Emacs-like textual key descriptions and the
    * <code>KeyStroke</code> object used in Swing.
    * <P>
    * This format has following form:
    * <P><code>[C][A][S][M]-<em>identifier</em></code>
    * <p>Where:
    * <UL>
    * <LI> <code>C</code> stands for the Control key
    * <LI> <code>A</code> stands for the Alt key
    * <LI> <code>S</code> stands for the Shift key
    * <LI> <code>M</code> stands for the Meta key
    * </UL>
    * The format also supports two wildcard codes, to support differences in
    * platforms.  These are the preferred choices for registering keystrokes,
    * since platform conflicts will automatically be handled:
    * <UL>
    * <LI> <code>D</code> stands for the default menu accelerator - the Control
    *  key on most platforms, the Command (meta) key on Macintosh</LI>
    * <LI> <code>O</code> stands for the alternate accelerator - the Alt key on
    *  most platforms, the Ctrl key on Macintosh (Macintosh uses Alt as a
    *  secondary shift key for composing international characters - if you bind
    *  Alt-8 to an action, a mac user with a French keyboard will not be able
    *  to type the <code>[</code> character, which is a significant handicap</LI>
    * </UL>
    * If you use the wildcard characters, and specify a key which will conflict
    * with keys the operating system consumes, it will be mapped to whichever
    * choice can work - for example, on Macintosh, Command-Q is always consumed
    * by the operating system, so <code>D-Q</code> will always map to Control-Q.
    * <p>
    * Every modifier before the hyphen must be pressed.
    * <em>identifier</EM> can be any text constant from {@link KeyEvent} but
    * without the leading <code>VK_</code> characters. So {@link KeyEvent#VK_ENTER} is described as
    * <code>ENTER</code>.
    *
    * @param s the string with the description of the key
    * @return key description object, or <code>null</code> if the string does not represent any valid key
    */
    public static KeyStroke stringToKey(String s) {
        StringTokenizer st = new StringTokenizer(s.toUpperCase(Locale.ENGLISH), "-", true); // NOI18N
        int needed = 0;
        HashMap names = initNameAndValues()[0];
        int lastModif = -1;
        try {
            for (;;) {
                String el = st.nextToken();
                // required key
                if (el.equals("-")) { // NOI18N
                    if (lastModif != -1) {
                        needed |= lastModif;
                        lastModif = -1;
                    }
                    continue;
                }
                // if there is more elements
                if (st.hasMoreElements()) {
                    // the text should describe modifiers
                    lastModif = readModifiers(el);
                } else {
                    // last text must be the key code
                    Integer i = (Integer) names.get(el);
                    boolean wildcard = (needed & CTRL_WILDCARD_MASK) != 0;
                    //Strip out the explicit mask - KeyStroke won"t know
                    //what to do with it
                    needed = needed & ~CTRL_WILDCARD_MASK;
                    boolean macAlt = (needed & ALT_WILDCARD_MASK) != 0;
                    needed = needed & ~ALT_WILDCARD_MASK;
                    if (i != null) {
                        //#26854 - Default accelerator should be Command on mac
                        if (wildcard) {
                            needed |= getMenuShortCutKeyMask();
                            if ((getOperatingSystem() & OS_MAC) != 0) {
                                if (!usableKeyOnMac(i.intValue(), needed)) {
                                    needed &= ~getMenuShortCutKeyMask();
                                    needed |= KeyEvent.CTRL_MASK;
                                }
                            }
                        }
                        if (macAlt) {
                            if (getOperatingSystem() == OS_MAC) {
                                needed |= KeyEvent.CTRL_MASK;
                            } else {
                                needed |= KeyEvent.ALT_MASK;
                            }
                        }
                        return KeyStroke.getKeyStroke(i.intValue(), needed);
                    } else {
                        return null;
                    }
                }
            }
        } catch (NoSuchElementException ex) {
            return null;
        }
    }
    /**
     * need to guard against headlessExceptions when testing.
     * @return the acceletor mask for shortcuts.
     */
    private static int getMenuShortCutKeyMask() {
        if (GraphicsEnvironment.isHeadless()) {
            return ((getOperatingSystem() & OS_MAC) != 0) ? 
                    KeyEvent.META_MASK : KeyEvent.CTRL_MASK;
        }
 
        return Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
    }
    private static boolean usableKeyOnMac(int key, int mask) {
        //All permutations fail for Q except ctrl
        if (key == KeyEvent.VK_Q) {
            return false;
        }
        boolean isMeta = ((mask & KeyEvent.META_MASK) != 0) || ((mask & KeyEvent.CTRL_DOWN_MASK) != 0);
        boolean isAlt = ((mask & KeyEvent.ALT_MASK) != 0) || ((mask & KeyEvent.ALT_DOWN_MASK) != 0);
        boolean isOnlyMeta = isMeta && ((mask & ~(KeyEvent.META_DOWN_MASK | KeyEvent.META_MASK)) == 0);
        //Mac OS consumes keys Command+ these keys - the app will never see
        //them, so CTRL should not be remapped for these
        if (isOnlyMeta) {
            return (key != KeyEvent.VK_H) && (key != KeyEvent.VK_SPACE) && (key != KeyEvent.VK_TAB);
        } else return !((key == KeyEvent.VK_D) && isMeta && isAlt);
    }
    /** Convert a space-separated list of Emacs-like key binding names to a list of Swing key strokes.
    * @param s the string with keys
    * @return array of key strokes, or <code>null</code> if the string description is not valid
    * @see #stringToKey
    */
    public static KeyStroke[] stringToKeys(String s) {
        StringTokenizer st = new StringTokenizer(s.toUpperCase(Locale.ENGLISH), " "); // NOI18N
        ArrayList<KeyStroke> arr = new ArrayList<KeyStroke>();
        while (st.hasMoreElements()) {
            s = st.nextToken();
            KeyStroke k = stringToKey(s);
            if (k == null) {
                return null;
            }
            arr.add(k);
        }
        return arr.toArray(new KeyStroke[arr.size()]);
    }
    /** Adds characters for modifiers to the buffer.
    * @param buf buffer to add to
    * @param modif modifiers to add (KeyEvent.XXX_MASK)
    * @return true if something has been added
    */
    private static boolean addModifiers(StringBuffer buf, int modif) {
        boolean b = false;
        if ((modif & KeyEvent.CTRL_MASK) != 0) {
            buf.append("C"); // NOI18N
            b = true;
        }
        if ((modif & KeyEvent.ALT_MASK) != 0) {
            buf.append("A"); // NOI18N
            b = true;
        }
        if ((modif & KeyEvent.SHIFT_MASK) != 0) {
            buf.append("S"); // NOI18N
            b = true;
        }
        if ((modif & KeyEvent.META_MASK) != 0) {
            buf.append("M"); // NOI18N
            b = true;
        }
        if ((modif & CTRL_WILDCARD_MASK) != 0) {
            buf.append("D");
            b = true;
        }
        if ((modif & ALT_WILDCARD_MASK) != 0) {
            buf.append("O");
            b = true;
        }
        return b;
    }
    /** Reads for modifiers and creates integer with required mask.
    * @param s string with modifiers
    * @return integer with mask
    * @exception NoSuchElementException if some letter is not modifier
    */
    private static int readModifiers(String s) throws NoSuchElementException {
        int m = 0;
        for (int i = 0; i < s.length(); i++) {
            switch (s.charAt(i)) {
            case "C":
                m |= KeyEvent.CTRL_MASK;
                break;
            case "A":
                m |= KeyEvent.ALT_MASK;
                break;
            case "M":
                m |= KeyEvent.META_MASK;
                break;
            case "S":
                m |= KeyEvent.SHIFT_MASK;
                break;
            case "D":
                m |= CTRL_WILDCARD_MASK;
                break;
            case "O":
                m |= ALT_WILDCARD_MASK;
                break;
            default:
                throw new NoSuchElementException(s);
            }
        }
        return m;
    }
    
    
}





Get Owning Frame for Component

   
/*
 * Copyright (C) 2001-2004 Colin Bell
 * colbell@users.sourceforge.net
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

import java.awt.ruponent;
import java.awt.Frame;
import javax.swing.SwingUtilities;
/**
 * Common GUI utilities accessed via static methods.
 * 
 * @author 
 */
public class GUIUtils {
  /**
   * Return the owning <CODE>Frame</CODE> for the passed component of <CODE>null</CODE>
   * if it doesn"t have one.
   * 
   * @throws IllegalArgumentException
   *           If <TT>wind</TT> is <TT>null</TT>.
   */
  public static Frame getOwningFrame(Component comp) {
    if (comp == null) {
      throw new IllegalArgumentException("null Component passed");
    }
    if (comp instanceof Frame) {
      return (Frame) comp;
    }
    return getOwningFrame(SwingUtilities.windowForComponent(comp));
  }
}





Get Screen Bounds For

   
/*
 * Copyright (C) 2001-2004 Colin Bell
 * colbell@users.sourceforge.net
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

import java.awt.ruponent;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.geom.Rectangle2D;
import java.beans.PropertyVetoException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.SwingUtilities;
/**
 * Common GUI utilities accessed via static methods.
 * 
 * @author 
 */
public class GUIUtils {

  public static Rectangle getScreenBoundsFor(Rectangle rc) {
    final GraphicsDevice[] gds = GraphicsEnvironment.getLocalGraphicsEnvironment()
        .getScreenDevices();
    final List<GraphicsConfiguration> configs = new ArrayList<GraphicsConfiguration>();
    for (int i = 0; i < gds.length; i++) {
      GraphicsConfiguration gc = gds[i].getDefaultConfiguration();
      if (rc.intersects(gc.getBounds())) {
        configs.add(gc);
      }
    }
    GraphicsConfiguration selected = null;
    if (configs.size() > 0) {
      for (Iterator<GraphicsConfiguration> it = configs.iterator(); it.hasNext();) {
        GraphicsConfiguration gcc = it.next();
        if (selected == null)
          selected = gcc;
        else {
          if (gcc.getBounds().contains(rc.x + 20, rc.y + 20)) {
            selected = gcc;
            break;
          }
        }
      }
    } else {
      selected = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()
          .getDefaultConfiguration();
    }
    int x = selected.getBounds().x;
    int y = selected.getBounds().y;
    int w = selected.getBounds().width;
    int h = selected.getBounds().height;
    return new Rectangle(x, y, w, h);
  }
}





Getting the JFrame of a Component

  
import java.awt.ruponent;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.SwingUtilities;
public class Main {
  public static void main(String[] argv) throws Exception {
    // Create an action
    Action action = new AbstractAction("Action Label") {
      // This method is called when the action is triggered
      public void actionPerformed(ActionEvent evt) {
        Component c = (Component) evt.getSource();
        // Get the frame
        Component frame = SwingUtilities.getRoot(c);
        // Hide the frame
        frame.setVisible(false);
      }
    };
  }
}





Get Top Frame

   
/*
    GNU LESSER GENERAL PUBLIC LICENSE
    Copyright (C) 2006 The Lobo Project
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.
    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    Contact info: lobochief@users.sourceforge.net
*/
import java.awt.*;
public class GUITasks {
  public static Frame getTopFrame() {
    Frame[] frames = Frame.getFrames();
    for(int i = 0; i < frames.length; i++) {
      if(frames[i].getFocusOwner() != null) {
        return frames[i];
      }
    }
    if(frames.length > 0) {
      return frames[0];
    }
    return null;
  }
  
  public static void drawDashed(Graphics g, int x1, int y1, int x2, int y2, int dashSize, int gapSize) {
    if(x2 < x1) {
      int temp = x1;
      x1 = x2;
      x2 = temp;
    }
    if(y2 < y1) {
      int temp = y1;
      y1 = y2;
      y2 = temp;
    }
    int totalDash = dashSize + gapSize;
    if(y1 == y2) {
      int virtualStartX = (x1 / totalDash) * totalDash;
      for(int x = virtualStartX; x < x2; x += totalDash) {
        int topX = x + dashSize;
        if(topX > x2) {
          topX = x2;
        }
        int firstX = x;
        if(firstX < x1) {
          firstX = x1;
        }
        if(firstX < topX) {
          g.drawLine(firstX, y1, topX, y1);
        }
      }
    }
    else if(x1 == x2) {
      int virtualStartY = (y1 / totalDash) * totalDash;
      for(int y = virtualStartY; y < y2; y += totalDash) {
        int topY = y + dashSize;
        if(topY > y2) {
          topY = y2;
        }
        int firstY = y;
        if(firstY < y1) {
          firstY = y1;
        }
        if(firstY < topY) {
          g.drawLine(x1, firstY, x1, topY);
        }
      }     
    }
    else {
      // Not supported
      g.drawLine(x1, y1, x2, y2);
    }
  }
}





Get Top Level Ancestor

   
import java.applet.Applet;
import java.awt.ruponent;
import java.awt.Container;
import java.awt.Point;
import java.awt.Window;
import java.util.ArrayList;
import javax.swing.RootPaneContainer;
import javax.swing.SwingUtilities;
/**
 * Copyright (C) 2004 NNL Technology AB
 * Visit www.infonode.net for information about InfoNode(R) 
 * products and how to contact NNL Technology AB.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
 * MA 02111-1307, USA.
 */

// $Id: ComponentUtil.java,v 1.25 2005/12/04 13:46:04 jesper Exp $

public class Util {

  public static Component getTopLevelAncestor(Component c) {
    while (c != null) {
      if (c instanceof Window || c instanceof Applet)
        break;
      c = c.getParent();
    }
    return c;
  }
}





Handle long-running tasks in a Swing application

  
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Main {
  private static JButton good = new JButton("Good");
  private static JLabel resultLabel = new JLabel("Ready", JLabel.CENTER);
  public static void main(String[] args) {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel p = new JPanel();
    p.setOpaque(true);
    p.setLayout(new FlowLayout());
    p.add(good);
    f.add(p, BorderLayout.CENTER);
    f.add(resultLabel, BorderLayout.SOUTH);
    good.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ev) {
        resultLabel.setText("Working . . .");
        good.setEnabled(false);
        Thread worker = new Thread() {
          public void run() {
            try {
              Thread.sleep(5000);
            } catch (InterruptedException ex) {
            }
            SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                resultLabel.setText("Ready");
                good.setEnabled(true);
              }
            });
          }
        };
        worker.start(); // So we don"t hold up the dispatch thread.
      }
    });
    f.setSize(300, 100);
    f.setVisible(true);
  }
}





Returns the usable area of the screen

 
/*
 * $Id: Utilities.java,v 1.11 2008/10/14 22:31:46 rah003 Exp $
 *
 * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

import java.awt.ruponent;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
/**
 * Contribution from NetBeans: Issue #319-swingx.
 * <p>
 * 
 * PENDING: need to reconcile with OS, JVM... added as-is because needed the
 * shortcut handling to fix #
 * 
 * @author apple
 */
public class Utilities {
    private Utilities() {
    }
    
    private static final int CTRL_WILDCARD_MASK = 32768;
    private static final int ALT_WILDCARD_MASK = CTRL_WILDCARD_MASK * 2;
    
    /** Operating system is Windows NT. */
    public static final int OS_WINNT = 1 << 0;
    /** Operating system is Windows 95. */
    public static final int OS_WIN95 = OS_WINNT << 1;
    /** Operating system is Windows 98. */
    public static final int OS_WIN98 = OS_WIN95 << 1;
    /** Operating system is Solaris. */
    public static final int OS_SOLARIS = OS_WIN98 << 1;
    /** Operating system is Linux. */
    public static final int OS_LINUX = OS_SOLARIS << 1;
    /** Operating system is HP-UX. */
    public static final int OS_HP = OS_LINUX << 1;
    /** Operating system is IBM AIX. */
    public static final int OS_AIX = OS_HP << 1;
    /** Operating system is SGI IRIX. */
    public static final int OS_IRIX = OS_AIX << 1;
    /** Operating system is Sun OS. */
    public static final int OS_SUNOS = OS_IRIX << 1;
    /** Operating system is Compaq TRU64 Unix */
    public static final int OS_TRU64 = OS_SUNOS << 1;
    /** Operating system is OS/2. */
    public static final int OS_OS2 = OS_TRU64 << 2;
    /** Operating system is Mac. */
    public static final int OS_MAC = OS_OS2 << 1;
    /** Operating system is Windows 2000. */
    public static final int OS_WIN2000 = OS_MAC << 1;
    /** Operating system is Compaq OpenVMS */
    public static final int OS_VMS = OS_WIN2000 << 1;
    /**
     *Operating system is one of the Windows variants but we don"t know which
     *one it is
     */
    public static final int OS_WIN_OTHER = OS_VMS << 1;
    /** Operating system is unknown. */
    public static final int OS_OTHER = OS_WIN_OTHER << 1;
    /** Operating system is FreeBSD
     * @since 4.50
     */
    public static final int OS_FREEBSD = OS_OTHER << 1;
    /** A mask for Windows platforms. */
    public static final int OS_WINDOWS_MASK = OS_WINNT | OS_WIN95 | OS_WIN98 | OS_WIN2000 | OS_WIN_OTHER;
    /** A mask for Unix platforms. */
    public static final int OS_UNIX_MASK = OS_SOLARIS | OS_LINUX | OS_HP | OS_AIX | OS_IRIX | OS_SUNOS | OS_TRU64 |
        OS_MAC | OS_FREEBSD;
    /** A height of the windows"s taskbar */
    public static final int TYPICAL_WINDOWS_TASKBAR_HEIGHT = 27;
    /** A height of the Mac OS X"s menu */
    private static final int TYPICAL_MACOSX_MENU_HEIGHT = 24;
    
    private static int operatingSystem = -1;
    
    /** reference to map that maps allowed key names to their values (String, Integer)
    and reference to map for mapping of values to their names */
    private static Reference<Object> namesAndValues;
    /** Get the operating system.
    * @return one of the <code>OS_*</code> constants (such as {@link #OS_WINNT})
    */
    public static int getOperatingSystem() {
        if (operatingSystem == -1) {
            String osName = System.getProperty("os.name");
            if ("Windows NT".equals(osName)) { // NOI18N
                operatingSystem = OS_WINNT;
            } else if ("Windows 95".equals(osName)) { // NOI18N
                operatingSystem = OS_WIN95;
            } else if ("Windows 98".equals(osName)) { // NOI18N
                operatingSystem = OS_WIN98;
            } else if ("Windows 2000".equals(osName)) { // NOI18N
                operatingSystem = OS_WIN2000;
            } else if (osName.startsWith("Windows ")) { // NOI18N
                operatingSystem = OS_WIN_OTHER;
            } else if ("Solaris".equals(osName)) { // NOI18N
                operatingSystem = OS_SOLARIS;
            } else if (osName.startsWith("SunOS")) { // NOI18N
                operatingSystem = OS_SOLARIS;
            }
            // JDK 1.4 b2 defines os.name for me as "Redhat Linux" -jglick
            else if (osName.endsWith("Linux")) { // NOI18N
                operatingSystem = OS_LINUX;
            } else if ("HP-UX".equals(osName)) { // NOI18N
                operatingSystem = OS_HP;
            } else if ("AIX".equals(osName)) { // NOI18N
                operatingSystem = OS_AIX;
            } else if ("Irix".equals(osName)) { // NOI18N
                operatingSystem = OS_IRIX;
            } else if ("SunOS".equals(osName)) { // NOI18N
                operatingSystem = OS_SUNOS;
            } else if ("Digital UNIX".equals(osName)) { // NOI18N
                operatingSystem = OS_TRU64;
            } else if ("OS/2".equals(osName)) { // NOI18N
                operatingSystem = OS_OS2;
            } else if ("OpenVMS".equals(osName)) { // NOI18N
                operatingSystem = OS_VMS;
            } else if (osName.equals("Mac OS X")) { // NOI18N
                operatingSystem = OS_MAC;
            } else if (osName.startsWith("Darwin")) { // NOI18N
                operatingSystem = OS_MAC;
            } else if (osName.toLowerCase(Locale.US).startsWith("freebsd")) { // NOI18N 
                operatingSystem = OS_FREEBSD;
            } else {
                operatingSystem = OS_OTHER;
            }
        }
        return operatingSystem;
    }

    /**
     * Finds out the monitor where the user currently has the input focus.
     * This method is usually used to help the client code to figure out on
     * which monitor it should place newly created windows/frames/dialogs.
     *
     * @return the GraphicsConfiguration of the monitor which currently has the
     * input focus
     */
    private static GraphicsConfiguration getCurrentGraphicsConfiguration() {
        Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
        if (focusOwner != null) {
            Window w = SwingUtilities.getWindowAncestor(focusOwner);
            if (w != null) {
                return w.getGraphicsConfiguration();
            }
        }
        return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    }
    /**
     * Returns the usable area of the screen where applications can place its
     * windows.  The method subtracts from the screen the area of taskbars,
     * system menus and the like.  The screen this method applies to is the one
     * which is considered current, ussually the one where the current input
     * focus is.
     *
     * @return the rectangle of the screen where one can place windows
     *
     * @since 2.5
     */
    public static Rectangle getUsableScreenBounds() {
        return getUsableScreenBounds(getCurrentGraphicsConfiguration());
    }
    /**
     * Returns the usable area of the screen where applications can place its
     * windows.  The method subtracts from the screen the area of taskbars,
     * system menus and the like.
     *
     * @param gconf the GraphicsConfiguration of the monitor
     * @return the rectangle of the screen where one can place windows
     *
     * @since 2.5
     */
    public static Rectangle getUsableScreenBounds(GraphicsConfiguration gconf) {
        if (gconf == null) {
            gconf = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
        }
        Rectangle bounds = new Rectangle(gconf.getBounds());
        String str;
        str = System.getProperty("netbeans.screen.insets"); // NOI18N
        if (str != null) {
            StringTokenizer st = new StringTokenizer(str, ", "); // NOI18N
            if (st.countTokens() == 4) {
                try {
                    bounds.y = Integer.parseInt(st.nextToken());
                    bounds.x = Integer.parseInt(st.nextToken());
                    bounds.height -= (bounds.y + Integer.parseInt(st.nextToken()));
                    bounds.width -= (bounds.x + Integer.parseInt(st.nextToken()));
                } catch (NumberFormatException ex) {
                    Logger.getAnonymousLogger().log(Level.WARNING, null, ex);
                }
            }
            return bounds;
        }
        str = System.getProperty("netbeans.taskbar.height"); // NOI18N
        if (str != null) {
            bounds.height -= Integer.getInteger(str, 0).intValue();
            return bounds;
        }
        try {
            Toolkit toolkit = Toolkit.getDefaultToolkit();
            Insets insets = toolkit.getScreenInsets(gconf);
            bounds.y += insets.top;
            bounds.x += insets.left;
            bounds.height -= (insets.top + insets.bottom);
            bounds.width -= (insets.left + insets.right);
        } catch (Exception ex) {
            Logger.getAnonymousLogger().log(Level.WARNING, null, ex);
        }
        return bounds;
    }
    
    /** Initialization of the names and values
    * @return array of two hashmaps first maps
    *   allowed key names to their values (String, Integer)
    *  and second
    * hashtable for mapping of values to their names (Integer, String)
    */
    private static synchronized HashMap[] initNameAndValues() {
        if (namesAndValues != null) {
            HashMap[] arr = (HashMap[]) namesAndValues.get();
            if (arr != null) {
                return arr;
            }
        }
        Field[] fields;
        // JW - fix Issue #353-swingx: play nicer inside sandbox.
        try {
            fields = KeyEvent.class.getDeclaredFields();
//           fields = KeyEvent.class.getFields();
        } catch (SecurityException e) { 
            // JW: need to do better? What are the use-cases where we don"t have
            // any access to the fields?
            fields = new Field[0];
        }
        HashMap<String,Integer> names = new HashMap<String,Integer>(((fields.length * 4) / 3) + 5, 0.75f);
        HashMap<Integer,String> values = new HashMap<Integer,String>(((fields.length * 4) / 3) + 5, 0.75f);
        for (int i = 0; i < fields.length; i++) {
            if (Modifier.isStatic(fields[i].getModifiers())) {
                String name = fields[i].getName();
                if (name.startsWith("VK_")) { // NOI18N
                    // exclude VK
                    name = name.substring(3);
                    try {
                        int numb = fields[i].getInt(null);
                        Integer value = new Integer(numb);
                        names.put(name, value);
                        values.put(value, name);
                    } catch (IllegalArgumentException ex) {
                    } catch (IllegalAccessException ex) {
                    }
                }
            }
        }
        if (names.get("CONTEXT_MENU") == null) { // NOI18N
            Integer n = new Integer(0x20C);
            names.put("CONTEXT_MENU", n); // NOI18N
            values.put(n, "CONTEXT_MENU"); // NOI18N
            n = new Integer(0x20D);
            names.put("WINDOWS", n); // NOI18N
            values.put(n, "WINDOWS"); // NOI18N
        }
        HashMap[] arr = { names, values };
        namesAndValues = new SoftReference<Object>(arr);
        return arr;
    }
    /** Converts a Swing key stroke descriptor to a familiar Emacs-like name.
    * @param stroke key description
    * @return name of the key (e.g. <code>CS-F1</code> for control-shift-function key one)
    * @see #stringToKey
    */
    public static String keyToString(KeyStroke stroke) {
        StringBuffer sb = new StringBuffer();
        // add modifiers that must be pressed
        if (addModifiers(sb, stroke.getModifiers())) {
            sb.append("-");
        }
        HashMap[] namesAndValues = initNameAndValues();
        String c = (String) namesAndValues[1].get(new Integer(stroke.getKeyCode()));
        if (c == null) {
            sb.append(stroke.getKeyChar());
        } else {
            sb.append(c);
        }
        return sb.toString();
    }
    /** Construct a new key description from a given universal string
    * description.
    * Provides mapping between Emacs-like textual key descriptions and the
    * <code>KeyStroke</code> object used in Swing.
    * <P>
    * This format has following form:
    * <P><code>[C][A][S][M]-<em>identifier</em></code>
    * <p>Where:
    * <UL>
    * <LI> <code>C</code> stands for the Control key
    * <LI> <code>A</code> stands for the Alt key
    * <LI> <code>S</code> stands for the Shift key
    * <LI> <code>M</code> stands for the Meta key
    * </UL>
    * The format also supports two wildcard codes, to support differences in
    * platforms.  These are the preferred choices for registering keystrokes,
    * since platform conflicts will automatically be handled:
    * <UL>
    * <LI> <code>D</code> stands for the default menu accelerator - the Control
    *  key on most platforms, the Command (meta) key on Macintosh</LI>
    * <LI> <code>O</code> stands for the alternate accelerator - the Alt key on
    *  most platforms, the Ctrl key on Macintosh (Macintosh uses Alt as a
    *  secondary shift key for composing international characters - if you bind
    *  Alt-8 to an action, a mac user with a French keyboard will not be able
    *  to type the <code>[</code> character, which is a significant handicap</LI>
    * </UL>
    * If you use the wildcard characters, and specify a key which will conflict
    * with keys the operating system consumes, it will be mapped to whichever
    * choice can work - for example, on Macintosh, Command-Q is always consumed
    * by the operating system, so <code>D-Q</code> will always map to Control-Q.
    * <p>
    * Every modifier before the hyphen must be pressed.
    * <em>identifier</EM> can be any text constant from {@link KeyEvent} but
    * without the leading <code>VK_</code> characters. So {@link KeyEvent#VK_ENTER} is described as
    * <code>ENTER</code>.
    *
    * @param s the string with the description of the key
    * @return key description object, or <code>null</code> if the string does not represent any valid key
    */
    public static KeyStroke stringToKey(String s) {
        StringTokenizer st = new StringTokenizer(s.toUpperCase(Locale.ENGLISH), "-", true); // NOI18N
        int needed = 0;
        HashMap names = initNameAndValues()[0];
        int lastModif = -1;
        try {
            for (;;) {
                String el = st.nextToken();
                // required key
                if (el.equals("-")) { // NOI18N
                    if (lastModif != -1) {
                        needed |= lastModif;
                        lastModif = -1;
                    }
                    continue;
                }
                // if there is more elements
                if (st.hasMoreElements()) {
                    // the text should describe modifiers
                    lastModif = readModifiers(el);
                } else {
                    // last text must be the key code
                    Integer i = (Integer) names.get(el);
                    boolean wildcard = (needed & CTRL_WILDCARD_MASK) != 0;
                    //Strip out the explicit mask - KeyStroke won"t know
                    //what to do with it
                    needed = needed & ~CTRL_WILDCARD_MASK;
                    boolean macAlt = (needed & ALT_WILDCARD_MASK) != 0;
                    needed = needed & ~ALT_WILDCARD_MASK;
                    if (i != null) {
                        //#26854 - Default accelerator should be Command on mac
                        if (wildcard) {
                            needed |= getMenuShortCutKeyMask();
                            if ((getOperatingSystem() & OS_MAC) != 0) {
                                if (!usableKeyOnMac(i.intValue(), needed)) {
                                    needed &= ~getMenuShortCutKeyMask();
                                    needed |= KeyEvent.CTRL_MASK;
                                }
                            }
                        }
                        if (macAlt) {
                            if (getOperatingSystem() == OS_MAC) {
                                needed |= KeyEvent.CTRL_MASK;
                            } else {
                                needed |= KeyEvent.ALT_MASK;
                            }
                        }
                        return KeyStroke.getKeyStroke(i.intValue(), needed);
                    } else {
                        return null;
                    }
                }
            }
        } catch (NoSuchElementException ex) {
            return null;
        }
    }
    /**
     * need to guard against headlessExceptions when testing.
     * @return the acceletor mask for shortcuts.
     */
    private static int getMenuShortCutKeyMask() {
        if (GraphicsEnvironment.isHeadless()) {
            return ((getOperatingSystem() & OS_MAC) != 0) ? 
                    KeyEvent.META_MASK : KeyEvent.CTRL_MASK;
        }
 
        return Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
    }
    private static boolean usableKeyOnMac(int key, int mask) {
        //All permutations fail for Q except ctrl
        if (key == KeyEvent.VK_Q) {
            return false;
        }
        boolean isMeta = ((mask & KeyEvent.META_MASK) != 0) || ((mask & KeyEvent.CTRL_DOWN_MASK) != 0);
        boolean isAlt = ((mask & KeyEvent.ALT_MASK) != 0) || ((mask & KeyEvent.ALT_DOWN_MASK) != 0);
        boolean isOnlyMeta = isMeta && ((mask & ~(KeyEvent.META_DOWN_MASK | KeyEvent.META_MASK)) == 0);
        //Mac OS consumes keys Command+ these keys - the app will never see
        //them, so CTRL should not be remapped for these
        if (isOnlyMeta) {
            return (key != KeyEvent.VK_H) && (key != KeyEvent.VK_SPACE) && (key != KeyEvent.VK_TAB);
        } else return !((key == KeyEvent.VK_D) && isMeta && isAlt);
    }
    /** Convert a space-separated list of Emacs-like key binding names to a list of Swing key strokes.
    * @param s the string with keys
    * @return array of key strokes, or <code>null</code> if the string description is not valid
    * @see #stringToKey
    */
    public static KeyStroke[] stringToKeys(String s) {
        StringTokenizer st = new StringTokenizer(s.toUpperCase(Locale.ENGLISH), " "); // NOI18N
        ArrayList<KeyStroke> arr = new ArrayList<KeyStroke>();
        while (st.hasMoreElements()) {
            s = st.nextToken();
            KeyStroke k = stringToKey(s);
            if (k == null) {
                return null;
            }
            arr.add(k);
        }
        return arr.toArray(new KeyStroke[arr.size()]);
    }
    /** Adds characters for modifiers to the buffer.
    * @param buf buffer to add to
    * @param modif modifiers to add (KeyEvent.XXX_MASK)
    * @return true if something has been added
    */
    private static boolean addModifiers(StringBuffer buf, int modif) {
        boolean b = false;
        if ((modif & KeyEvent.CTRL_MASK) != 0) {
            buf.append("C"); // NOI18N
            b = true;
        }
        if ((modif & KeyEvent.ALT_MASK) != 0) {
            buf.append("A"); // NOI18N
            b = true;
        }
        if ((modif & KeyEvent.SHIFT_MASK) != 0) {
            buf.append("S"); // NOI18N
            b = true;
        }
        if ((modif & KeyEvent.META_MASK) != 0) {
            buf.append("M"); // NOI18N
            b = true;
        }
        if ((modif & CTRL_WILDCARD_MASK) != 0) {
            buf.append("D");
            b = true;
        }
        if ((modif & ALT_WILDCARD_MASK) != 0) {
            buf.append("O");
            b = true;
        }
        return b;
    }
    /** Reads for modifiers and creates integer with required mask.
    * @param s string with modifiers
    * @return integer with mask
    * @exception NoSuchElementException if some letter is not modifier
    */
    private static int readModifiers(String s) throws NoSuchElementException {
        int m = 0;
        for (int i = 0; i < s.length(); i++) {
            switch (s.charAt(i)) {
            case "C":
                m |= KeyEvent.CTRL_MASK;
                break;
            case "A":
                m |= KeyEvent.ALT_MASK;
                break;
            case "M":
                m |= KeyEvent.META_MASK;
                break;
            case "S":
                m |= KeyEvent.SHIFT_MASK;
                break;
            case "D":
                m |= CTRL_WILDCARD_MASK;
                break;
            case "O":
                m |= ALT_WILDCARD_MASK;
                break;
            default:
                throw new NoSuchElementException(s);
            }
        }
        return m;
    }
    
    
}





Swing invoke and wait

  
/*
Code from Desktop Java Live Source
URL: http://www.sourcebeat.ru/downloads/
*/

import javax.swing.*;
import java.lang.reflect.InvocationTargetException;
public class InvokeAndWaitExample extends JPanel {
    private Thread progressThread;
    private JProgressBar progressBar;
    private boolean keepRunning;

    public InvokeAndWaitExample() {
        this.keepRunning = true;
        this.progressThread = new ProgressThread();
        this.progressBar = new JProgressBar();
        this.progressBar.setMaximum(100);
        add(this.progressBar);
        System.out.println(keepRunning);
        this.progressThread.start();
    }
    private class ProgressThread extends Thread {
        public void run() {
            int count = 0;
            while (keepRunning) {
                try {
                    Thread.sleep(40);
                } catch (InterruptedException e) {
                }
                final int cval = count;
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        progressBar.setValue(cval);
                    }
                });
                count++;

                if (count == 101) {
                    count = 0;
                } else if (count == 50) {
                    final int[] returnValue = new int[1];
                    try {
                        SwingUtilities.invokeAndWait(new Runnable() {
                            public void run() {
                                returnValue[0] = JOptionPane.showConfirmDialog(progressBar, "Would you like to reset progress?", "Prompt", JOptionPane.YES_NO_OPTION);
                            }
                        });
                        if (returnValue[0] == JOptionPane.YES_OPTION) {
                            count = 0;
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    public static void main(String[] a){
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(1);
      f.add(new InvokeAndWaitExample());
      f.pack();
      f.setVisible(true);
    } 
    
}





Swing invoke later

  
/*
Code from Desktop Java Live Source
URL: http://www.sourcebeat.ru/downloads/
*/

import javax.swing.*;
import java.awt.event.ActionEvent;
public class InvokeLaterExample extends JPanel {
    private JLabel statusArea;
    private DefaultListModel listModel;
    public InvokeLaterExample() {
        JButton button = new JButton(new LongRunningModelFillAction());
        add(button);
        JList list = new JList();
        this.listModel = new DefaultListModel();
        this.listModel.addElement("An Empty List Model");
        list.setModel(listModel);
        add(new JScrollPane(list));
        add(new JLabel("Status:"));
        this.statusArea = new JLabel();
        add(this.statusArea);
    }
    private class LongRunningModelFillAction extends AbstractAction {
        public LongRunningModelFillAction() {
            super("Fill Model");
        }
        public void actionPerformed(ActionEvent e) {
            InvokeLaterExample.this.listModel.removeAllElements();
            InvokeLaterExample.this.listModel.addElement("Calculating...");
            PopulationRunnable populationRunnable = new PopulationRunnable();
            Thread populationThread = new Thread(populationRunnable);
            populationThread.start();
        }
    }
    private class PopulationRunnable implements Runnable {
        public void run() {
            final Object[] values = new Object[100];
            for (int i = 1; i <= 100; i++) {
                values[i - 1] = "Value" + i;

                if ((i % 10) == 0) {
                    final int progress = i;
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            InvokeLaterExample.this.statusArea.setText("Calculated " + progress);
                        }
                    });
                }
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                }
            }
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    InvokeLaterExample.this.statusArea.setText("");
                    InvokeLaterExample.this.listModel.removeAllElements();
                    for (int i = 0; i < values.length; i++) {
                        InvokeLaterExample.this.listModel.addElement(values[i]);
                    }
                }
            });
        }
    }
    public static void main(String[] a){
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(1);
      f.add(new InvokeLaterExample());
      f.pack();
      f.setVisible(true);
    } 
    
}





Swing Utilities getWindowAncestor

  
/*
Code from Desktop Java Live Source
URL: http://www.sourcebeat.ru/downloads/
*/

import javax.swing.*;
import java.awt.event.ActionEvent;
public class DialogBlockingExample {
    public static JPanel createPanel() {
        JPanel panel = new JPanel();
        JButton button = new JButton(new DialogAction(panel));
        panel.add(button);
        return panel;
    }
    private static class DialogAction extends AbstractAction {
        private JPanel panel;
        public DialogAction(JPanel panel) {
            super("Open Dialog");
            this.panel = panel;
        }
        public void actionPerformed(ActionEvent e) {
            JDialog dialog = new JDialog((JFrame) SwingUtilities.getWindowAncestor(panel), true);
            dialog.getContentPane().add(new JLabel("A Dialog"));
            dialog.setVisible(true);
            putValue(Action.NAME, "Dialog Already Shown");
        }
    }
    
    public static void main(String[] a){
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(1);
      f.add(createPanel());
      f.pack();
      f.setVisible(true);
    } 
}





Swing worker Example

  
import javax.swing.*;
import java.awt.event.ActionEvent;
public class SwingWorkerExample extends JPanel {
    private JLabel statusArea;
    private DefaultListModel listModel;
    public SwingWorkerExample() {
        JButton button = new JButton(new LongRunningModelFillAction());
        add(button);
        JList list = new JList();
        this.listModel = new DefaultListModel();
        this.listModel.addElement("An Empty List Model");
        list.setModel(listModel);
        add(new JScrollPane(list));
        add(new JLabel("Status:"));
        this.statusArea = new JLabel();
        add(this.statusArea);
    }
    private class LongRunningModelFillAction extends AbstractAction {
        public LongRunningModelFillAction() {
            super("Fill Model");
        }
        public void actionPerformed(ActionEvent e) {
            PopulationWorker populationWorker = new PopulationWorker();
            populationWorker.start();
        }
    }
    private class PopulationWorker extends SwingWorker {
        public Object construct() {
            Object[] values = new Object[100];
            for (int i = 1; i <= 100; i++) {
                values[i - 1] = "Value" + i;

                if ((i % 10) == 0) {
                    final int progress = i;
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            SwingWorkerExample.this.statusArea.setText("Calculated " + progress);
                        }
                    });
                }
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                }
            }
            return values;
        }
        public void start() {
            SwingWorkerExample.this.listModel.removeAllElements();
            SwingWorkerExample.this.listModel.addElement("Calculating...");
            super.start();
        }
        public void finished() {
            SwingWorkerExample.this.statusArea.setText("");
            SwingWorkerExample.this.listModel.removeAllElements();
            Object[] values = (Object[]) getValue();
            for (int i = 0; i < values.length; i++) {
                SwingWorkerExample.this.listModel.addElement(values[i]);
            }
        }
    }
    public static void main(String[] a){
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(1);
      f.add(new SwingWorkerExample());
      f.pack();
      f.setVisible(true);
    } 
}

/*
 * $Id: SwingWorker.java,v 1.1.1.1 2004/06/16 01:43:39 davidson1 Exp $
 *
 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 */

/**
 * This is the 3rd version of SwingWorker (also known as
 * SwingWorker 3), an abstract class that you subclass to
 * perform GUI-related work in a dedicated thread.  For
 * instructions on using this class, see:
 * 
 * http://java.sun.ru/docs/books/tutorial/uiswing/misc/threads.html
 *
 * Note that the API changed slightly in the 3rd version:
 * You must now invoke start() on the SwingWorker after
 * creating it.
 */
abstract class SwingWorker {
    private Object value;  // see getValue(), setValue()
    private Thread thread;
    /** 
     * Class to maintain reference to current worker thread
     * under separate synchronization control.
     */
    private static class ThreadVar {
        private Thread thread;
        ThreadVar(Thread t) { thread = t; }
        synchronized Thread get() { return thread; }
        synchronized void clear() { thread = null; }
    }
    private ThreadVar threadVar;
    /** 
     * Get the value produced by the worker thread, or null if it 
     * hasn"t been constructed yet.
     */
    protected synchronized Object getValue() { 
        return value; 
    }
    /** 
     * Set the value produced by worker thread 
     */
    private synchronized void setValue(Object x) { 
        value = x; 
    }
    /** 
     * Compute the value to be returned by the <code>get</code> method. 
     */
    public abstract Object construct();
    /**
     * Called on the event dispatching thread (not on the worker thread)
     * after the <code>construct</code> method has returned.
     */
    public void finished() {
    }
    /**
     * A new method that interrupts the worker thread.  Call this method
     * to force the worker to stop what it"s doing.
     */
    public void interrupt() {
        Thread t = threadVar.get();
        if (t != null) {
            t.interrupt();
        }
        threadVar.clear();
    }
    /**
     * Return the value created by the <code>construct</code> method.  
     * Returns null if either the constructing thread or the current
     * thread was interrupted before a value was produced.
     * 
     * @return the value created by the <code>construct</code> method
     */
    public Object get() {
        while (true) {  
            Thread t = threadVar.get();
            if (t == null) {
                return getValue();
            }
            try {
                t.join();
            }
            catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // propagate
                return null;
            }
        }
    }

    /**
     * Start a thread that will call the <code>construct</code> method
     * and then exit.
     */
    public SwingWorker() {
        final Runnable doFinished = new Runnable() {
           public void run() { finished(); }
        };
        Runnable doConstruct = new Runnable() { 
            public void run() {
                try {
                    setValue(construct());
                }
                finally {
                    threadVar.clear();
                }
                SwingUtilities.invokeLater(doFinished);
            }
        };
        Thread t = new Thread(doConstruct);
        threadVar = new ThreadVar(t);
    }
    /**
     * Start the worker thread.
     */
    public void start() {
        Thread t = threadVar.get();
        if (t != null) {
            t.start();
        }
    }
}