001 /* 002 * $Id: WindowUtils.java 3352 2009-05-25 16:37:52Z kschaefe $ 003 * 004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle, 005 * Santa Clara, California 95054, U.S.A. All rights reserved. 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 020 */ 021 022 package org.jdesktop.swingx.util; 023 024 import java.awt.Component; 025 import java.awt.Container; 026 import java.awt.GraphicsConfiguration; 027 import java.awt.GraphicsDevice; 028 import java.awt.GraphicsEnvironment; 029 import java.awt.Insets; 030 import java.awt.MouseInfo; 031 import java.awt.Point; 032 import java.awt.Rectangle; 033 import java.awt.Toolkit; 034 import java.awt.Window; 035 import java.awt.event.ComponentAdapter; 036 import java.awt.event.ComponentListener; 037 import java.util.ArrayList; 038 import java.util.List; 039 import java.util.logging.Level; 040 import java.util.logging.Logger; 041 042 import javax.swing.JInternalFrame; 043 import javax.swing.JOptionPane; 044 import javax.swing.SwingUtilities; 045 046 /** 047 * Encapsulates various utilities for windows (ie: <code>Frame</code> and 048 * <code>Dialog</code> objects and descendants, in particular). 049 * 050 * @author Richard Bair 051 */ 052 public final class WindowUtils { 053 private static final Logger LOG = Logger.getLogger(WindowUtils.class 054 .getName()); 055 056 /** 057 * Hide the constructor - don't wan't anybody creating an instance of this 058 */ 059 private WindowUtils() { 060 } 061 062 /** 063 * <p> 064 * Returns the <code>Point</code> at which a window should be placed to 065 * center that window on the screen. 066 * </p> 067 * <p> 068 * Some thought was taken as to whether to implement a method such as this, 069 * or to simply make a method that, given a window, will center it. It was 070 * decided that it is better to not alter an object within a method. 071 * </p> 072 * 073 * @param window The window to calculate the center point for. This object 074 * can not be null. 075 * 076 * @return the <code>Point</code> at which the window should be placed to 077 * center that window on the screen. 078 */ 079 public static Point getPointForCentering(Window window) { 080 Rectangle usableBounds = getUsableDeviceBounds(window); 081 int screenWidth = usableBounds.width; 082 int screenHeight = usableBounds.height; 083 int width = window.getWidth(); 084 int height = window.getHeight(); 085 086 return new Point(((screenWidth - width) / 2) + usableBounds.x, 087 ((screenHeight - height) / 2) + usableBounds.y); 088 } 089 090 private static Rectangle getUsableDeviceBounds(Window window) { 091 Window owner = window.getOwner(); 092 GraphicsConfiguration gc = null; 093 094 if (owner == null) { 095 gc = GraphicsEnvironment.getLocalGraphicsEnvironment() 096 .getDefaultScreenDevice().getDefaultConfiguration(); 097 } else { 098 gc = owner.getGraphicsConfiguration(); 099 } 100 101 Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc); 102 Rectangle bounds = gc.getBounds(); 103 bounds.x += insets.left; 104 bounds.y += insets.top; 105 bounds.width -= (insets.left + insets.right); 106 bounds.height -= (insets.top + insets.bottom); 107 108 return bounds; 109 } 110 111 /** 112 * <p/> 113 * Returns the <code>Point</code> at which a window should be placed to 114 * center that window on the given desktop. 115 * </p> 116 * <p/> 117 * Some thought was taken as to whether to implement a method such as this, 118 * or to simply make a method that, given a window, will center it. It was 119 * decided that it is better to not alter an object within a method. 120 * </p> 121 * 122 * @param window The window (JInternalFrame) to calculate the center point 123 * for. This object can not be null. 124 * 125 * @return the <code>Point</code> at which the window should be placed to 126 * center that window on the given desktop 127 */ 128 public static Point getPointForCentering(JInternalFrame window) { 129 try { 130 //assert window != null; 131 Point mousePoint = MouseInfo.getPointerInfo().getLocation(); 132 GraphicsDevice[] devices = GraphicsEnvironment 133 .getLocalGraphicsEnvironment().getScreenDevices(); 134 for (GraphicsDevice device : devices) { 135 Rectangle bounds = device.getDefaultConfiguration().getBounds(); 136 //check to see if the mouse cursor is within these bounds 137 if (mousePoint.x >= bounds.x && mousePoint.y >= bounds.y 138 && mousePoint.x <= (bounds.x + bounds.width) 139 && mousePoint.y <= (bounds.y + bounds.height)) { 140 //this is it 141 int screenWidth = bounds.width; 142 int screenHeight = bounds.height; 143 int width = window.getWidth(); 144 int height = window.getHeight(); 145 return new Point(((screenWidth - width) / 2) + bounds.x, 146 ((screenHeight - height) / 2) + bounds 147 .y); 148 } 149 } 150 } catch (Exception e) { 151 LOG.log(Level.FINE, e.getLocalizedMessage() + 152 " - this can occur do to a Security exception in sandboxed apps"); 153 } 154 return new Point(0, 0); 155 } 156 157 /** 158 * <p/> 159 * Returns the <code>Point</code> at which a window should be placed in 160 * order to be staggered slightly from another "origin" window to 161 * ensure that the title areas of both windows remain visible to the user. 162 * </p> 163 * 164 * @param originWindow Window from which the staggered location will be calculated 165 * 166 * @return location staggered from the upper left location of the origin 167 * window 168 */ 169 public static Point getPointForStaggering(Window originWindow) { 170 Point origin = originWindow.getLocation(); 171 Insets insets = originWindow.getInsets(); 172 origin.x += insets.top; 173 origin.y += insets.top; 174 return origin; 175 } 176 177 public static Window findWindow(Component c) { 178 if (c == null) { 179 return JOptionPane.getRootFrame(); 180 } else if (c instanceof Window) { 181 return (Window) c; 182 } else { 183 return findWindow(c.getParent()); 184 } 185 } 186 187 public static List<Component> getAllComponents(final Container c) { 188 Component[] comps = c.getComponents(); 189 List<Component> compList = new ArrayList<Component>(); 190 for (Component comp : comps) { 191 compList.add(comp); 192 if (comp instanceof Container) { 193 compList.addAll(getAllComponents((Container) comp)); 194 } 195 } 196 return compList; 197 } 198 199 /** 200 * Installs/resets a ComponentListener to resize the 201 * given window to minWidth/Height if needed. 202 * 203 * @param window 204 * @param minWidth 205 * @param minHeight 206 */ 207 public static void setMinimumSizeManager(Window window, int minWidth, 208 int minHeight) { 209 ComponentListener[] listeners = window.getComponentListeners(); 210 ComponentListener listener = null; 211 for (ComponentListener l : listeners) { 212 if (l instanceof MinSizeComponentListener) { 213 listener = l; 214 break; 215 } 216 } 217 if (listener == null) { 218 window.addComponentListener(new MinSizeComponentListener( 219 window, minWidth, minHeight)); 220 } else { 221 ((MinSizeComponentListener) listener).resetSizes(minWidth, 222 minHeight); 223 } 224 } 225 226 /** 227 * Resets window size to minSize if needed. 228 * 229 * @author Patrick Wright 230 */ 231 public static class MinSizeComponentListener extends ComponentAdapter { 232 private Window window; 233 private int minHeight; 234 private int minWidth; 235 236 MinSizeComponentListener(Window frame, int minWidth, int minHeight) { 237 this.window = frame; 238 resetSizes(minWidth, minHeight); 239 } 240 241 public void resetSizes(int minWidth, int minHeight) { 242 this.minWidth = minWidth; 243 this.minHeight = minHeight; 244 adjustIfNeeded(window); 245 } 246 247 @Override 248 public void componentResized(java.awt.event.ComponentEvent evt) { 249 adjustIfNeeded((Window) evt.getComponent()); 250 } 251 252 private void adjustIfNeeded(final Window window) { 253 boolean doSize = false; 254 int newWidth = window.getWidth(); 255 int newHeight = window.getHeight(); 256 if (newWidth < minWidth) { 257 newWidth = minWidth; 258 doSize = true; 259 } 260 if (newHeight < minHeight) { 261 newHeight = minHeight; 262 doSize = true; 263 } 264 if (doSize) { 265 final int w = newWidth; 266 final int h = newHeight; 267 SwingUtilities.invokeLater(new Runnable() { 268 public void run() { 269 window.setSize(w, h); 270 } 271 }); 272 } 273 } 274 } 275 }