/* * Bibliothek - DockingFrames * Library built on Java/Swing, allows the user to "drag and drop" * panels containing any Swing-Component the developer likes to add. * * Copyright (C) 2007 Benjamin Sigg * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA * * Benjamin Sigg * benjamin_sigg@gmx.ch * CH - Switzerland */ package bibliothek.gui.dock.station.screen; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Insets; import java.awt.Rectangle; import java.awt.Toolkit; /** * A restriction that ensures that each dialog is always visible on exactly one * screen. * @author Benjamin Sigg */ public class HardBoundaryRestriction extends AbstractBoundaryRestriction{ @Override protected Rectangle checkSize( ScreenDockWindow window ){ return checkSize( window, window.getWindowBounds() ); } @Override protected Rectangle checkSize( ScreenDockWindow window, Rectangle target ){ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] screens = ge.getScreenDevices(); int x = target.x; int y = target.y; int width = target.width; int height = target.height; double fit = -1.0; GraphicsDevice best = null; for( GraphicsDevice screen : screens ){ double check = measureBounds( window, x, y, width, height, screen ); if( check > fit ){ fit = check; best = screen; } } if( best == null ) return null; else return boundsInDevice( window, x, y, width, height, best ); } /** * Checks how good <code>window</code> fits into the screen <code>device</code> * @param window the window that is checked * @param x the desired x-coordinate * @param y the desired y-coordinate * @param width the desired width * @param height the desired height * @param device the targeted screen * @return a value between 0 and 1, where 0 means "does not fit" and * 1 means "perfect". */ protected double measureBounds( ScreenDockWindow window, int x, int y, int width, int height, GraphicsDevice device ){ if( width == 0 || height == 0 ) return 0.0; Rectangle next = new Rectangle( x, y, width, height ); Rectangle screen = device.getDefaultConfiguration().getBounds(); Rectangle intersection = screen.intersection( next ); if( intersection.width <= 0 || intersection.height <= 0 ) return 0.0; return (intersection.width * intersection.height) / ((double)next.width * next.height); } /** * Calculates size and location of <code>dialog</code> such that it is * in <code>device</code>. * @param window the window to check * @param x the desired x-coordinate * @param y the desired y-coordinate * @param width the desired width * @param height the desired height * @param device the screen in which to show this dialog * @return the new bounds, can be <code>null</code> */ protected Rectangle boundsInDevice( ScreenDockWindow window, int x, int y, int width, int height, GraphicsDevice device ){ Rectangle size = device.getDefaultConfiguration().getBounds(); Insets insets = Toolkit.getDefaultToolkit().getScreenInsets( device.getDefaultConfiguration() ); if( insets == null ) insets = new Insets( 0,0,0,0 ); width = Math.min( size.width-insets.left-insets.right, width ); height = Math.min( size.height-insets.top-insets.bottom, height ); x = Math.max( x, size.x+insets.left ); y = Math.max( y, size.y+insets.right ); x = Math.min( x, size.width - insets.left - insets.right - width + size.x ); y = Math.min( y, size.height - insets.top - insets.bottom - height + size.y ); return new Rectangle( x, y, width, height ); } }