J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. |
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 4 | * |
| 5 | * This code is free software; you can redistribute it and/or modify it |
| 6 | * under the terms of the GNU General Public License version 2 only, as |
| 7 | * published by the Free Software Foundation. Sun designates this |
| 8 | * particular file as subject to the "Classpath" exception as provided |
| 9 | * by Sun in the LICENSE file that accompanied this code. |
| 10 | * |
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 14 | * version 2 for more details (a copy is included in the LICENSE file that |
| 15 | * accompanied this code). |
| 16 | * |
| 17 | * You should have received a copy of the GNU General Public License version |
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| 20 | * |
| 21 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| 22 | * CA 95054 USA or visit www.sun.com if you need additional information or |
| 23 | * have any questions. |
| 24 | */ |
| 25 | |
| 26 | package javax.swing.plaf.basic; |
| 27 | |
| 28 | import java.awt.*; |
| 29 | import java.awt.event.*; |
| 30 | import javax.swing.*; |
| 31 | import javax.swing.event.*; |
| 32 | import javax.swing.border.*; |
| 33 | import javax.swing.plaf.*; |
| 34 | import java.beans.*; |
| 35 | import java.util.EventListener; |
| 36 | import java.io.Serializable; |
| 37 | |
| 38 | |
| 39 | /** |
| 40 | * Basic L&F for a minimized window on a desktop. |
| 41 | * |
| 42 | * @author David Kloba |
| 43 | * @author Steve Wilson |
| 44 | * @author Rich Schiavi |
| 45 | */ |
| 46 | public class BasicDesktopIconUI extends DesktopIconUI { |
| 47 | |
| 48 | protected JInternalFrame.JDesktopIcon desktopIcon; |
| 49 | protected JInternalFrame frame; |
| 50 | |
| 51 | /** |
| 52 | * The title pane component used in the desktop icon. |
| 53 | * |
| 54 | * @since 1.5 |
| 55 | */ |
| 56 | protected JComponent iconPane; |
| 57 | MouseInputListener mouseInputListener; |
| 58 | |
| 59 | |
| 60 | |
| 61 | public static ComponentUI createUI(JComponent c) { |
| 62 | return new BasicDesktopIconUI(); |
| 63 | } |
| 64 | |
| 65 | public BasicDesktopIconUI() { |
| 66 | } |
| 67 | |
| 68 | public void installUI(JComponent c) { |
| 69 | desktopIcon = (JInternalFrame.JDesktopIcon)c; |
| 70 | frame = desktopIcon.getInternalFrame(); |
| 71 | installDefaults(); |
| 72 | installComponents(); |
| 73 | |
| 74 | // Update icon layout if frame is already iconified |
| 75 | JInternalFrame f = desktopIcon.getInternalFrame(); |
| 76 | if (f.isIcon() && f.getParent() == null) { |
| 77 | JDesktopPane desktop = desktopIcon.getDesktopPane(); |
| 78 | if (desktop != null) { |
| 79 | DesktopManager desktopManager = desktop.getDesktopManager(); |
| 80 | if (desktopManager instanceof DefaultDesktopManager) { |
| 81 | desktopManager.iconifyFrame(f); |
| 82 | } |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | installListeners(); |
| 87 | JLayeredPane.putLayer(desktopIcon, JLayeredPane.getLayer(frame)); |
| 88 | } |
| 89 | |
| 90 | public void uninstallUI(JComponent c) { |
| 91 | uninstallDefaults(); |
| 92 | uninstallComponents(); |
| 93 | |
| 94 | // Force future UI to relayout icon |
| 95 | JInternalFrame f = desktopIcon.getInternalFrame(); |
| 96 | if (f.isIcon()) { |
| 97 | JDesktopPane desktop = desktopIcon.getDesktopPane(); |
| 98 | if (desktop != null) { |
| 99 | DesktopManager desktopManager = desktop.getDesktopManager(); |
| 100 | if (desktopManager instanceof DefaultDesktopManager) { |
| 101 | // This will cause DefaultDesktopManager to layout the icon |
| 102 | f.putClientProperty("wasIconOnce", null); |
| 103 | // Move aside to allow fresh layout of all icons |
| 104 | desktopIcon.setLocation(Integer.MIN_VALUE, 0); |
| 105 | } |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | uninstallListeners(); |
| 110 | frame = null; |
| 111 | desktopIcon = null; |
| 112 | } |
| 113 | |
| 114 | protected void installComponents() { |
| 115 | iconPane = new BasicInternalFrameTitlePane(frame); |
| 116 | desktopIcon.setLayout(new BorderLayout()); |
| 117 | desktopIcon.add(iconPane, BorderLayout.CENTER); |
| 118 | } |
| 119 | |
| 120 | protected void uninstallComponents() { |
| 121 | desktopIcon.remove(iconPane); |
| 122 | desktopIcon.setLayout(null); |
| 123 | iconPane = null; |
| 124 | } |
| 125 | |
| 126 | protected void installListeners() { |
| 127 | mouseInputListener = createMouseInputListener(); |
| 128 | desktopIcon.addMouseMotionListener(mouseInputListener); |
| 129 | desktopIcon.addMouseListener(mouseInputListener); |
| 130 | } |
| 131 | |
| 132 | protected void uninstallListeners() { |
| 133 | desktopIcon.removeMouseMotionListener(mouseInputListener); |
| 134 | desktopIcon.removeMouseListener(mouseInputListener); |
| 135 | mouseInputListener = null; |
| 136 | } |
| 137 | |
| 138 | protected void installDefaults() { |
| 139 | LookAndFeel.installBorder(desktopIcon, "DesktopIcon.border"); |
| 140 | LookAndFeel.installProperty(desktopIcon, "opaque", Boolean.TRUE); |
| 141 | } |
| 142 | |
| 143 | protected void uninstallDefaults() { |
| 144 | LookAndFeel.uninstallBorder(desktopIcon); |
| 145 | } |
| 146 | |
| 147 | protected MouseInputListener createMouseInputListener() { |
| 148 | return new MouseInputHandler(); |
| 149 | } |
| 150 | |
| 151 | public Dimension getPreferredSize(JComponent c) { |
| 152 | return desktopIcon.getLayout().preferredLayoutSize(desktopIcon); |
| 153 | } |
| 154 | |
| 155 | public Dimension getMinimumSize(JComponent c) { |
| 156 | Dimension dim = new Dimension(iconPane.getMinimumSize()); |
| 157 | Border border = frame.getBorder(); |
| 158 | |
| 159 | if (border != null) { |
| 160 | dim.height += border.getBorderInsets(frame).bottom + |
| 161 | border.getBorderInsets(frame).top; |
| 162 | } |
| 163 | return dim; |
| 164 | } |
| 165 | |
| 166 | /** |
| 167 | * Desktop icons can not be resized. Therefore, we should always |
| 168 | * return the minimum size of the desktop icon. |
| 169 | * |
| 170 | * @see #getMinimumSize |
| 171 | */ |
| 172 | public Dimension getMaximumSize(JComponent c){ |
| 173 | return iconPane.getMaximumSize(); |
| 174 | } |
| 175 | |
| 176 | public Insets getInsets(JComponent c) { |
| 177 | JInternalFrame iframe = desktopIcon.getInternalFrame(); |
| 178 | Border border = iframe.getBorder(); |
| 179 | if(border != null) |
| 180 | return border.getBorderInsets(iframe); |
| 181 | |
| 182 | return new Insets(0,0,0,0); |
| 183 | } |
| 184 | |
| 185 | public void deiconize() { |
| 186 | try { frame.setIcon(false); } catch (PropertyVetoException e2) { } |
| 187 | } |
| 188 | |
| 189 | /** |
| 190 | * Listens for mouse movements and acts on them. |
| 191 | * |
| 192 | * This inner class is marked "public" due to a compiler bug. |
| 193 | * This class should be treated as a "protected" inner class. |
| 194 | * Instantiate it only within subclasses of <Foo>. |
| 195 | */ |
| 196 | public class MouseInputHandler extends MouseInputAdapter |
| 197 | { |
| 198 | // _x & _y are the mousePressed location in absolute coordinate system |
| 199 | int _x, _y; |
| 200 | // __x & __y are the mousePressed location in source view's coordinate system |
| 201 | int __x, __y; |
| 202 | Rectangle startingBounds; |
| 203 | |
| 204 | public void mouseReleased(MouseEvent e) { |
| 205 | _x = 0; |
| 206 | _y = 0; |
| 207 | __x = 0; |
| 208 | __y = 0; |
| 209 | startingBounds = null; |
| 210 | |
| 211 | JDesktopPane d; |
| 212 | if((d = desktopIcon.getDesktopPane()) != null) { |
| 213 | DesktopManager dm = d.getDesktopManager(); |
| 214 | dm.endDraggingFrame(desktopIcon); |
| 215 | } |
| 216 | |
| 217 | } |
| 218 | |
| 219 | public void mousePressed(MouseEvent e) { |
| 220 | Point p = SwingUtilities.convertPoint((Component)e.getSource(), |
| 221 | e.getX(), e.getY(), null); |
| 222 | __x = e.getX(); |
| 223 | __y = e.getY(); |
| 224 | _x = p.x; |
| 225 | _y = p.y; |
| 226 | startingBounds = desktopIcon.getBounds(); |
| 227 | |
| 228 | JDesktopPane d; |
| 229 | if((d = desktopIcon.getDesktopPane()) != null) { |
| 230 | DesktopManager dm = d.getDesktopManager(); |
| 231 | dm.beginDraggingFrame(desktopIcon); |
| 232 | } |
| 233 | |
| 234 | try { frame.setSelected(true); } catch (PropertyVetoException e1) { } |
| 235 | if(desktopIcon.getParent() instanceof JLayeredPane) { |
| 236 | ((JLayeredPane)desktopIcon.getParent()).moveToFront(desktopIcon); |
| 237 | } |
| 238 | |
| 239 | if(e.getClickCount() > 1) { |
| 240 | if(frame.isIconifiable() && frame.isIcon()) { |
| 241 | deiconize(); |
| 242 | } |
| 243 | } |
| 244 | |
| 245 | } |
| 246 | |
| 247 | public void mouseMoved(MouseEvent e) {} |
| 248 | |
| 249 | public void mouseDragged(MouseEvent e) { |
| 250 | Point p; |
| 251 | int newX, newY, newW, newH; |
| 252 | int deltaX; |
| 253 | int deltaY; |
| 254 | Dimension min; |
| 255 | Dimension max; |
| 256 | p = SwingUtilities.convertPoint((Component)e.getSource(), |
| 257 | e.getX(), e.getY(), null); |
| 258 | |
| 259 | Insets i = desktopIcon.getInsets(); |
| 260 | int pWidth, pHeight; |
| 261 | pWidth = ((JComponent)desktopIcon.getParent()).getWidth(); |
| 262 | pHeight = ((JComponent)desktopIcon.getParent()).getHeight(); |
| 263 | |
| 264 | if (startingBounds == null) { |
| 265 | // (STEVE) Yucky work around for bug ID 4106552 |
| 266 | return; |
| 267 | } |
| 268 | newX = startingBounds.x - (_x - p.x); |
| 269 | newY = startingBounds.y - (_y - p.y); |
| 270 | // Make sure we stay in-bounds |
| 271 | if(newX + i.left <= -__x) |
| 272 | newX = -__x - i.left; |
| 273 | if(newY + i.top <= -__y) |
| 274 | newY = -__y - i.top; |
| 275 | if(newX + __x + i.right > pWidth) |
| 276 | newX = pWidth - __x - i.right; |
| 277 | if(newY + __y + i.bottom > pHeight) |
| 278 | newY = pHeight - __y - i.bottom; |
| 279 | |
| 280 | JDesktopPane d; |
| 281 | if((d = desktopIcon.getDesktopPane()) != null) { |
| 282 | DesktopManager dm = d.getDesktopManager(); |
| 283 | dm.dragFrame(desktopIcon, newX, newY); |
| 284 | } else { |
| 285 | moveAndRepaint(desktopIcon, newX, newY, |
| 286 | desktopIcon.getWidth(), desktopIcon.getHeight()); |
| 287 | } |
| 288 | return; |
| 289 | } |
| 290 | |
| 291 | public void moveAndRepaint(JComponent f, int newX, int newY, |
| 292 | int newWidth, int newHeight) { |
| 293 | Rectangle r = f.getBounds(); |
| 294 | f.setBounds(newX, newY, newWidth, newHeight); |
| 295 | SwingUtilities.computeUnion(newX, newY, newWidth, newHeight, r); |
| 296 | f.getParent().repaint(r.x, r.y, r.width, r.height); |
| 297 | } |
| 298 | }; /// End MotionListener |
| 299 | |
| 300 | } |