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