1 /**
2  * The utillib library.
3  * More information is available at http://www.jinchess.com/.
4  * Copyright (C) 2002, 2003 Alexander Maryanovsky.
5  * All rights reserved.
6  *
7  * The utillib library is free software; you can redistribute
8  * it and/or modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * The utillib library is distributed in the hope that it will
13  * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with utillib library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 
22 
23 package free.util;
24 
25 import java.awt.*;
26 import java.lang.reflect.*;
27 
28 
29 /**
30  * A collection of AWT related utilities.
31  */
32 
33 public class AWTUtilities{
34 
35 
36 
37   /**
38    * Packs and centers the given window relative to the given component. The
39    * specified component may be <code>null</code>, in which case the window will
40    * be centered on the screen. The method also makes sure that the target
41    * window is fully visible by calling <code>forceToScreen</code>.
42    */
43 
centerWindow(Window target, Component parent)44   public static void centerWindow(Window target, Component parent){
45     target.pack();
46 
47     Dimension size = target.getSize();
48     Rectangle parentBounds = parent == null || !parent.isShowing() ?
49       getUsableScreenBounds() :
50       new Rectangle(parent.getLocationOnScreen(), parent.getSize());
51 
52     target.setLocation(parentBounds.x + (parentBounds.width - size.width)/2, parentBounds.y + (parentBounds.height - size.height)/2);
53 
54     forceToScreen(target);
55   }
56 
57 
58 
59   /**
60    * Reposition the specified window so that it necessarily fits on the screen,
61    * while trying to minimize changes.
62    */
63 
forceToScreen(Window window)64   public static void forceToScreen(Window window){
65     Dimension screenSize = window.getToolkit().getScreenSize();
66     Rectangle bounds = window.getBounds();
67 
68     bounds.width = Math.min(bounds.width, screenSize.width);
69     bounds.height = Math.min(bounds.height, screenSize.height);
70     bounds.x = Math.min(Math.max(bounds.x, 0), screenSize.width - bounds.width);
71     bounds.y = Math.min(Math.max(bounds.y, 0), screenSize.height - bounds.height);
72 
73     window.setBounds(bounds);
74   }
75 
76 
77 
78 
79   /**
80    * Returns the parent Frame of the specified <code>Component</code> or
81    * <code>null</code> if none exists.
82    */
83 
frameForComponent(Component component)84   public static Frame frameForComponent(Component component){
85     while (component != null){
86       if (component instanceof Frame)
87         return (Frame)component;
88       component = component.getParent();
89     }
90 
91     return null;
92   }
93 
94 
95 
96 
97   /**
98    * Returns a list of available font names. Under JDK1.1 it uses
99    * <code>Toolkit.getFontList()</code> while under JDK1.2 (via reflection),
100    * <code>GraphicsEnvironment.getAvailableFontFamilyNames()</code>
101    */
102 
getAvailableFontNames()103   public static String [] getAvailableFontNames(){
104     if (PlatformUtils.isJavaBetterThan("1.2")){
105       try{
106         // The equivalent of "return GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();"
107         Class geClass = Class.forName("java.awt.GraphicsEnvironment");
108         Method getLocalGraphicsEnvironmentMethod = geClass.getMethod("getLocalGraphicsEnvironment", new Class[0]);
109         Object localGE = getLocalGraphicsEnvironmentMethod.invoke(null, new Object[0]);
110         Method getAvailableFontFamilyNamesMethod = geClass.getMethod("getAvailableFontFamilyNames", new Class[0]);
111         String [] fontNames = (String [])getAvailableFontFamilyNamesMethod.invoke(localGE, new Object[0]);
112         return fontNames;
113       } catch (ClassNotFoundException e){e.printStackTrace();}
114         catch (NoSuchMethodException e){e.printStackTrace();}
115         catch (IllegalAccessException e){e.printStackTrace();}
116         catch (InvocationTargetException e){e.printStackTrace();}
117       return null;
118     }
119     else
120       return Toolkit.getDefaultToolkit().getFontList();
121   }
122 
123 
124 
125   /**
126    * Returns the state of the specified frame, as specified by
127    * <code>Frame.getExtendedState()</code> if running under JDK 1.4 or later,
128    * otherwise returns 0. The call to <code>Frame.getExtendedState()</code> is
129    * done via reflection to avoid runtime errors.
130    */
131 
getExtendedFrameState(Frame frame)132   public static int getExtendedFrameState(Frame frame){
133     if (PlatformUtils.isJavaBetterThan("1.4")){
134       try{
135         Class frameClass = Class.forName("java.awt.Frame");
136         Method getExtendedStateMethod = frameClass.getMethod("getExtendedState", new Class[0]);
137         Integer state = (Integer)getExtendedStateMethod.invoke(frame, new Object[0]);
138         return state.intValue();
139       } catch (ClassNotFoundException e){e.printStackTrace();}
140         catch (NoSuchMethodException e){e.printStackTrace();}
141         catch (IllegalAccessException e){e.printStackTrace();}
142         catch (InvocationTargetException e){e.printStackTrace();}
143     }
144 
145     return 0;
146   }
147 
148 
149 
150   /**
151    * Sets the state of the specified frame, as specified by
152    * <code>Frame.setExtendedState</code> if running in JDK 1.4 or later,
153    * otherwise does nothing. The call to <code>Frame.setExtendedState()</code>
154    * is done via reflection to avoid runtime errors.
155    */
156 
setExtendedFrameState(Frame frame, int state)157   public static void setExtendedFrameState(Frame frame, int state){
158     if (PlatformUtils.isJavaBetterThan("1.4")){
159       try{
160         Class frameClass = Class.forName("java.awt.Frame");
161         Method setExtendedStateMethod = frameClass.getMethod("setExtendedState", new Class[]{int.class});
162         setExtendedStateMethod.invoke(frame, new Object[]{new Integer(state)});
163       } catch (ClassNotFoundException e){e.printStackTrace();}
164         catch (NoSuchMethodException e){e.printStackTrace();}
165         catch (IllegalAccessException e){e.printStackTrace();}
166         catch (InvocationTargetException e){e.printStackTrace();}
167     }
168   }
169 
170 
171 
172   /**
173    * Attempts to determine the usable screen bounds of the default screen
174    * device. If the require java.awt API is not available under the JVM we're
175    * running in, this will simply return the screen bounds obtained via
176    * <code>Toolkit.getScreenSize()</code>.
177    */
178 
getUsableScreenBounds()179   public static Rectangle getUsableScreenBounds(){
180     if (PlatformUtils.isJavaBetterThan("1.4")){
181       try{
182         Class graphicsEnvironmentClass = Class.forName("java.awt.GraphicsEnvironment");
183         Class graphicsDeviceClass = Class.forName("java.awt.GraphicsDevice");
184         Class graphicsConfigurationClass = Class.forName("java.awt.GraphicsConfiguration");
185 
186         Class [] emptyClassArr = new Class[0];
187         Method getLocalGraphicsEnvironmentMethod =
188           graphicsEnvironmentClass.getMethod("getLocalGraphicsEnvironment", emptyClassArr);
189         Method getDefaultScreenDeviceMethod =
190           graphicsEnvironmentClass.getMethod("getDefaultScreenDevice", emptyClassArr);
191         Method getDefaultConfigurationMethod =
192           graphicsDeviceClass.getMethod("getDefaultConfiguration", emptyClassArr);
193         Method getBoundsMethod =
194           graphicsConfigurationClass.getMethod("getBounds", emptyClassArr);
195         Method getScreenInsetsMethod =
196           Toolkit.class.getMethod("getScreenInsets", new Class[]{graphicsConfigurationClass});
197 
198         Object [] emptyObjArr = new Object[0];
199         Object graphicsEnvironment = getLocalGraphicsEnvironmentMethod.invoke(null, emptyObjArr);
200         Object defaultScreenDevice = getDefaultScreenDeviceMethod.invoke(graphicsEnvironment, emptyObjArr);
201         Object defaultConfiguration = getDefaultConfigurationMethod.invoke(defaultScreenDevice, emptyObjArr);
202         Rectangle bounds = (Rectangle)getBoundsMethod.invoke(defaultConfiguration, emptyObjArr);
203         Insets insets =
204           (Insets)getScreenInsetsMethod.invoke(Toolkit.getDefaultToolkit(), new Object[]{defaultConfiguration});
205 
206         bounds.x += insets.left;
207         bounds.y += insets.top;
208         bounds.width -= insets.left + insets.right;
209         bounds.height -= insets.top + insets.bottom;
210 
211         return bounds;
212       } catch (ClassNotFoundException e){e.printStackTrace();}
213         catch (SecurityException e){e.printStackTrace();}
214         catch (NoSuchMethodException e){e.printStackTrace();}
215         catch (IllegalArgumentException e){e.printStackTrace();}
216         catch (IllegalAccessException e){e.printStackTrace();}
217         catch (InvocationTargetException e){e.printStackTrace();}
218     }
219 
220     return new Rectangle(new Point(0, 0), Toolkit.getDefaultToolkit().getScreenSize());
221   }
222 
223 
224 
225 
226   /**
227    * Enables or disables all the components within the specified container.
228    *
229    * This is a rather hacky method - it doesn't work well if there are both
230    * enabled and disabled components in the container.
231    */
232 
setContainerEnabled(Container container, boolean enabled)233   public static void setContainerEnabled(Container container, boolean enabled){
234     Component [] children = container.getComponents();
235     for (int i = 0; i < children.length; i++){
236       Component child = children[i];
237       child.setEnabled(enabled);
238       if (child instanceof Container)
239         setContainerEnabled((Container)child, enabled);
240     }
241   }
242 
243 
244 
245 }
246