/* * 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) 2010 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.Dimension; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Point; import java.awt.Rectangle; /** * A restriction that ensures that the title of each dialog is always visible. * @author Benjamin Sigg */ public class MediumBoundaryRestriction extends AbstractBoundaryRestriction{ @Override public Rectangle checkSize( ScreenDockWindow window ){ Point center = window.getTitleCenter(); if( center == null ){ Rectangle target = window.getWindowBounds(); center = new Point( target.width/2, target.height/2 ); } return validate( window, window.getWindowBounds(), center, center ); } @Override public Rectangle checkSize( ScreenDockWindow window, Rectangle target ){ Point center = window.getTitleCenter(); Point search; if( center == null ){ center = new Point( target.width/2, target.height/2 ); search = center; } else{ Rectangle bounds = window.getWindowBounds(); search = new Point( center ); search.x += target.x - bounds.x; search.y += target.y - bounds.y; } return validate( window, target, center, search ); } /** * Ensures that <code>center</code> will be in a visible part of the screen. * @param window the window whose boundaries are checked * @param target the next boundaries for a window * @param center the point that should remain visible * @param search the point used to find the best matching screen device * @return a set of boundaries that is as close to <code>target</code> as possible */ protected Rectangle validate( ScreenDockWindow window, Rectangle target, Point center, Point search ) { Rectangle screen = findDevice( search.x + target.x, search.y + target.y ); if( screen == null ){ return null; } Rectangle original; if( center.equals( search )){ original = screen; } else { original = findDevice( center.x + target.x, center.y + target.y ); } if( !original.equals( screen )){ center = search; } Rectangle result = new Rectangle( target ); Dimension minimum = getMinimumSize( window ); result.width = Math.max( minimum.width, result.width ); result.height = Math.max( minimum.height, result.height ); result.x = Math.max( screen.x - center.x, result.x ); result.y = Math.max( screen.y - center.y, result.y ); result.x = Math.min( screen.x + screen.width - center.x, result.x ); result.y = Math.min( screen.y + screen.height - center.y, result.y ); return result; } /** * Gets the minimum size of <code>window</code>, the default implementation just calls * {@link ScreenDockWindow#getMinimumWindowSize()}, but subclasses may override this method * to use another algorithm for finding the minimum window size. * @param window the window whose minimum size is required * @return the minimum size, must not be <code>null</code> */ protected Dimension getMinimumSize( ScreenDockWindow window ){ return window.getMinimumWindowSize(); } /** * Finds and returns the boundaries of the screen in which <code>x/y</code> are. * @param x some x coordinate * @param y some y coordinate * @return the boundaries of the nearest screen containing <code>x/y</code> or <code>null</code> */ protected Rectangle findDevice( int x, int y ){ GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); GraphicsDevice best = null; int bestDist = 0; for( GraphicsDevice device : devices ){ Rectangle bounds = device.getDefaultConfiguration().getBounds(); int dist = dist( bounds.x, bounds.width, x ) + dist( bounds.y, bounds.height, y ); if( best == null || dist < bestDist ){ best = device; bestDist = dist; } } if( best == null ){ return null; } return best.getDefaultConfiguration().getBounds(); } private int dist( int x, int width, int pos ){ if( pos < x ){ return x - pos; } if( pos > x + width ){ return pos - x - width; } return 0; } }