/* * 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) 2009 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.common.action.panel; import java.awt.Component; import java.awt.Dialog; import java.awt.Frame; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Point; import java.awt.Rectangle; import java.awt.Window; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import javax.swing.JDialog; import javax.swing.SwingUtilities; import bibliothek.gui.dock.common.action.CPanelPopup; /** * A {@link PanelPopupWindow} managing a {@link JDialog}. * @author Benjamin Sigg */ public class DialogWindow extends AbstractPanelPopupWindow{ /** the dialog which is managed by this window */ private JDialog dialog; /** the owner of this dialog */ private CPanelPopup panel; /** a listener to {@link #dialog} */ private WindowListener listener = new WindowAdapter(){ @Override public void windowClosed( WindowEvent e ){ closing(); } @Override public void windowClosing( WindowEvent e ){ closing(); } @Override public void windowDeactivated( WindowEvent e ){ if( panel.isCloseOnFocusLost() ){ close(); } } }; /** * Creates a new window. * @param owner the parent of the dialog * @param panel the owner of the dialog */ public DialogWindow( Component owner, CPanelPopup panel ){ this.panel = panel; dialog = createDialog( owner ); dialog.setDefaultCloseOperation( JDialog.DO_NOTHING_ON_CLOSE ); dialog.addWindowListener( listener ); } /** * Sets whether the dialog has a decoration or not. * @param undecorated whether to decorate or not * @see JDialog#setUndecorated(boolean) */ public void setUndecorated( boolean undecorated ){ dialog.setUndecorated( undecorated ); } /** * Sets the contents of the dialog. * @param content the contents, may be <code>null</code> */ public void setContent( Component content ){ dialog.getContentPane().removeAll(); if( content != null ){ dialog.add( content ); } } /** * Shows the dialog at the given screen location. * @param x the dialogs location * @param y the dialogs location */ public void open( int x, int y ){ dialog.pack(); dialog.setLocation( x, y ); validateBounds(); dialog.setVisible( true ); } /** * Opens the dialog relative to <code>relativeTo</code>. * @param relativeTo some component */ public void open( Component relativeTo ){ dialog.pack(); dialog.setLocationRelativeTo( relativeTo ); validateBounds(); dialog.setVisible( true ); } private void validateBounds(){ Rectangle bounds = dialog.getBounds(); Point location = dialog.getLocation(); GraphicsConfiguration bestConfiguration = null; int bestDistance = 0; GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment(); for( GraphicsDevice device : environment.getScreenDevices() ){ GraphicsConfiguration configuration = device.getDefaultConfiguration(); Rectangle screenBounds = configuration.getBounds(); if( screenBounds.contains( location )){ bestConfiguration = configuration; bestDistance = 0; } else{ int dx; int dy; if( screenBounds.x <= location.x && screenBounds.x + screenBounds.width >= location.x ){ dx = 0; } else{ dx = Math.min(Math.abs(screenBounds.x - location.x), Math.abs(screenBounds.x + screenBounds.width - location.x)); } if( screenBounds.y <= location.y && screenBounds.y + screenBounds.height >= location.y ){ dy = 0; } else{ dy = Math.min(Math.abs(screenBounds.y - location.y), Math.abs(screenBounds.y + screenBounds.height - location.y)); } int delta = dx + dy; if( delta < bestDistance || bestConfiguration == null ){ bestDistance = delta; bestConfiguration = configuration; } } } bounds = validateBounds( bounds, bestConfiguration ); if( bounds != null ){ dialog.setBounds( bounds ); } } public boolean isOpen(){ return dialog.isVisible(); } public void close(){ dialog.setVisible( false ); } private void closing(){ dialog.dispose(); dialog.removeWindowListener( listener ); fireClosed(); } /** * Creates a new dialog with the ancestor window of <code>owner</code> * as owner. * @param owner some component * @return the new dialog */ protected JDialog createDialog( Component owner ){ Window window = SwingUtilities.getWindowAncestor( owner ); if( window instanceof Frame ) return new JDialog( (Frame)window ); if( window instanceof Dialog ) return new JDialog( (Dialog)window ); return new JDialog(); } }