/******************************************************************************** * * * (c) Copyright 2010 Verizon Communications USA and The Open University UK * * * * This software is freely distributed in accordance with * * the GNU Lesser General Public (LGPL) license, version 3 or later * * as published by the Free Software Foundation. * * For details see LGPL: http://www.fsf.org/licensing/licenses/lgpl.html * * and GPL: http://www.fsf.org/licensing/licenses/gpl-3.0.html * * * * This software is provided by the copyright holders and contributors "as is" * * and any express or implied warranties, including, but not limited to, the * * implied warranties of merchantability and fitness for a particular purpose * * are disclaimed. In no event shall the copyright owner or contributors be * * liable for any direct, indirect, incidental, special, exemplary, or * * consequential damages (including, but not limited to, procurement of * * substitute goods or services; loss of use, data, or profits; or business * * interruption) however caused and on any theory of liability, whether in * * contract, strict liability, or tort (including negligence or otherwise) * * arising in any way out of the use of this software, even if advised of the * * possibility of such damage. * * * ********************************************************************************/ package com.compendium.ui; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.beans.PropertyVetoException; import javax.swing.DefaultDesktopManager; import javax.swing.JComponent; import javax.swing.JDesktopPane; import javax.swing.JInternalFrame; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This subclass of DefaultDesktopManager is to fix a Mac bug with closing frames. * Also it has code from Gerald Nunn to activate scrollbars when frame dragged off right/bottom * * @author Michelle Bachler / Gerald Nunn */ public class UIDesktopManager extends DefaultDesktopManager { static final Logger log = LoggerFactory.getLogger(UIDesktopManager.class); //private UIDesktopPane desktop; private JDesktopPane desktop; public UIDesktopManager(JDesktopPane desktop) { this.desktop = desktop; } // This is called anytime a frame is moved. This // implementation keeps the frame from leaving the desktop. public void dragFrame(JComponent f, int x, int y) { if (f instanceof JInternalFrame) { // Deal only w/internal frames JInternalFrame frame = (JInternalFrame) f; JDesktopPane desk = frame.getDesktopPane(); Dimension d = desk.getSize(); // Nothing all that fancy below, just figuring out how to adjust // to keep the frame on the desktop. if (x < 0) { // too far left? x = 0; // flush against the left side } else { if (x + frame.getWidth() > d.width) { // too far right? x = d.width - frame.getWidth(); // flush against right side } } if (y < 0) { // too high? y = 0; // flush against the top } else { if (y + frame.getHeight() > d.height) { // too low? y = d.height - frame.getHeight(); // flush against the // bottom } } } // Pass along the (possibly cropped) values to the normal drag handler. super.dragFrame(f, x, y); } // CODE that worked alon with UIDesktopPane To try and implement and scrollable desktop // Was buggy and so removed and dragFrame method added until more time to fix. /*public void endResizingFrame(JComponent f) { super.endResizingFrame(f); //resizeDesktop(); } public void endDraggingFrame(JComponent f) { super.endDraggingFrame(f); //resizeDesktop(); } public void setNormalSize() { JScrollPane scrollPane=getScrollPane(); int x = 0; int y = 0; Insets scrollInsets = getScrollPaneInsets(); if (scrollPane != null) { Dimension d = scrollPane.getVisibleRect().getSize(); if (scrollPane.getBorder() != null) { d.setSize(d.getWidth() - scrollInsets.left - scrollInsets.right, d.getHeight() - scrollInsets.top - scrollInsets.bottom); } d.setSize(d.getWidth() - 20, d.getHeight() - 20); desktop.setAllSize(x,y); scrollPane.invalidate(); scrollPane.validate(); } } private Insets getScrollPaneInsets() { JScrollPane scrollPane=getScrollPane(); if (scrollPane==null) return new Insets(0,0,0,0); else return getScrollPane().getBorder().getBorderInsets(scrollPane); } private JScrollPane getScrollPane() { if (desktop.getParent() instanceof JViewport) { JViewport viewPort = (JViewport)desktop.getParent(); if (viewPort.getParent() instanceof JScrollPane) return (JScrollPane)viewPort.getParent(); } return null; } protected void resizeDesktop() { int x = 0; int y = 0; JScrollPane scrollPane = getScrollPane(); Insets scrollInsets = getScrollPaneInsets(); if (scrollPane != null) { JInternalFrame allFrames[] = desktop.getAllFrames(); for (int i = 0; i < allFrames.length; i++) { if (allFrames[i].getX()+allFrames[i].getWidth()> x) { x = allFrames[i].getX() + allFrames[i].getWidth(); } if (allFrames[i].getY()+allFrames[i].getHeight()>y) { y = allFrames[i].getY() + allFrames[i].getHeight(); } } Dimension d=scrollPane.getVisibleRect().getSize(); if (scrollPane.getBorder() != null) { d.setSize(d.getWidth() - scrollInsets.left - scrollInsets.right, d.getHeight() - scrollInsets.top - scrollInsets.bottom); } if (x <= d.getWidth()) { x = ((int)d.getWidth()) - 20; } if (y <= d.getHeight()) { y = ((int)d.getHeight()) - 20; } desktop.setAllSize(x,y); scrollPane.invalidate(); scrollPane.validate(); } }*/ // ORIGINAL MANAGER CODE /** * Removes the frame, and, if necessary, the * <code>desktopIcon</code>, from its parent. * * @param f the <code>JInternalFrame</code> to be removed. */ public void closeFrame(JInternalFrame f) { boolean findNext = f.isSelected(); Container c = f.getParent(); JDesktopPane pane = getDesktopPane((JComponent)f); if (findNext) try { f.setSelected(false); } catch (PropertyVetoException e2) { } if(c != null) { c.remove(f); c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight()); } removeIconFor(f); if(f.getNormalBounds() != null) f.setNormalBounds(null); if(wasIcon(f)) setWasIcon(f, null); if (findNext) myActivateNextFrame(c, pane); } /** * When a frame is closed find the next internal frame in the correct order to bring to the front. * * @param c, the container to look in. * @param pane, the associated desktop pane. */ private void myActivateNextFrame(Container c, JDesktopPane pane) { int i; JInternalFrame nextFrame = null; if (pane == null) { if (c == null) return; for (i = 0; i < c.getComponentCount(); i++) { if (c.getComponent(i) instanceof JInternalFrame) { nextFrame = (JInternalFrame) c.getComponent(i); break; } } } else { JInternalFrame[] frames = pane.getAllFrames(); if (frames.length > 0) nextFrame = frames[0]; } if (nextFrame != null) { try { nextFrame.setSelected(true); } catch (PropertyVetoException e2) { log.info("frame selection failing as ;"+e2.getMessage());} //$NON-NLS-1$ nextFrame.moveToFront(); } } /** * Return the desktop pane associated with the given component. * * @param frame, the component to get the JDesktopPane for. * @return JDesktopPane, if found, else null. */ JDesktopPane getDesktopPane( JComponent frame ) { JDesktopPane pane = null; Component c = frame.getParent(); // Find the JDesktopPane while ( pane == null ) { if ( c instanceof JDesktopPane ) { pane = (JDesktopPane)c; } else if ( c == null ) { break; } else { c = c.getParent(); } } return pane; } }