1 /* 2 * Copyright (c) 1997, 2003, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.java.swing.plaf.motif; 27 28 import javax.swing.*; 29 import java.awt.Rectangle; 30 import java.awt.Dimension; 31 import java.awt.Insets; 32 import java.awt.Color; 33 import java.awt.Graphics; 34 import java.awt.Component; 35 import java.awt.Point; 36 import javax.swing.plaf.*; 37 import java.io.Serializable; 38 39 /** 40 * <p> 41 * <strong>Warning:</strong> 42 * Serialized objects of this class will not be compatible with 43 * future Swing releases. The current serialization support is appropriate 44 * for short term storage or RMI between applications running the same 45 * version of Swing. A future release of Swing will provide support for 46 * long term persistence. 47 * 48 * @author David Kloba 49 */ 50 public class MotifDesktopPaneUI extends javax.swing.plaf.basic.BasicDesktopPaneUI 51 { 52 53 /// DesktopPaneUI methods 54 public static ComponentUI createUI(JComponent d) { 55 return new MotifDesktopPaneUI(); 56 } 57 58 public MotifDesktopPaneUI() { 59 } 60 61 protected void installDesktopManager() { 62 desktopManager = desktop.getDesktopManager(); 63 if(desktopManager == null) { 64 desktopManager = new MotifDesktopManager(); 65 desktop.setDesktopManager(desktopManager); 66 ((MotifDesktopManager)desktopManager).adjustIcons(desktop); 67 } 68 } 69 70 public Insets getInsets(JComponent c) {return new Insets(0,0,0,0);} 71 72 //////////////////////////////////////////////////////////////////////////////////// 73 /// DragPane class 74 //////////////////////////////////////////////////////////////////////////////////// 75 private class DragPane extends JComponent { 76 public void paint(Graphics g) { 77 g.setColor(Color.darkGray); 78 g.drawRect(0, 0, getWidth()-1, getHeight()-1); 79 } 80 }; 81 82 //////////////////////////////////////////////////////////////////////////////////// 83 /// MotifDesktopManager class 84 //////////////////////////////////////////////////////////////////////////////////// 85 private class MotifDesktopManager extends DefaultDesktopManager implements Serializable, UIResource { 86 JComponent dragPane; 87 boolean usingDragPane = false; 88 private transient JLayeredPane layeredPaneForDragPane; 89 int iconWidth, iconHeight; 90 91 // PENDING(klobad) this should be optimized 92 public void setBoundsForFrame(JComponent f, int newX, int newY, 93 int newWidth, int newHeight) { 94 if(!usingDragPane) { 95 boolean didResize; 96 didResize = (f.getWidth() != newWidth || f.getHeight() != newHeight); 97 Rectangle r = f.getBounds(); 98 f.setBounds(newX, newY, newWidth, newHeight); 99 SwingUtilities.computeUnion(newX, newY, newWidth, newHeight, r); 100 f.getParent().repaint(r.x, r.y, r.width, r.height); 101 if(didResize) { 102 f.validate(); 103 } 104 } else { 105 Rectangle r = dragPane.getBounds(); 106 dragPane.setBounds(newX, newY, newWidth, newHeight); 107 SwingUtilities.computeUnion(newX, newY, newWidth, newHeight, r); 108 dragPane.getParent().repaint(r.x, r.y, r.width, r.height); 109 } 110 } 111 112 public void beginDraggingFrame(JComponent f) { 113 usingDragPane = false; 114 if(f.getParent() instanceof JLayeredPane) { 115 if(dragPane == null) 116 dragPane = new DragPane(); 117 layeredPaneForDragPane = (JLayeredPane)f.getParent(); 118 layeredPaneForDragPane.setLayer(dragPane, Integer.MAX_VALUE); 119 dragPane.setBounds(f.getX(), f.getY(), f.getWidth(), f.getHeight()); 120 layeredPaneForDragPane.add(dragPane); 121 usingDragPane = true; 122 } 123 } 124 125 public void dragFrame(JComponent f, int newX, int newY) { 126 setBoundsForFrame(f, newX, newY, f.getWidth(), f.getHeight()); 127 } 128 129 public void endDraggingFrame(JComponent f) { 130 if(usingDragPane) { 131 layeredPaneForDragPane.remove(dragPane); 132 usingDragPane = false; 133 if (f instanceof JInternalFrame) { 134 setBoundsForFrame(f, dragPane.getX(), dragPane.getY(), 135 dragPane.getWidth(), dragPane.getHeight()); 136 } else if (f instanceof JInternalFrame.JDesktopIcon) { 137 adjustBoundsForIcon((JInternalFrame.JDesktopIcon)f, 138 dragPane.getX(), dragPane.getY()); 139 } 140 } 141 } 142 143 public void beginResizingFrame(JComponent f, int direction) { 144 usingDragPane = false; 145 if(f.getParent() instanceof JLayeredPane) { 146 if(dragPane == null) 147 dragPane = new DragPane(); 148 JLayeredPane p = (JLayeredPane)f.getParent(); 149 p.setLayer(dragPane, Integer.MAX_VALUE); 150 dragPane.setBounds(f.getX(), f.getY(), 151 f.getWidth(), f.getHeight()); 152 p.add(dragPane); 153 usingDragPane = true; 154 } 155 } 156 157 public void resizeFrame(JComponent f, int newX, int newY, 158 int newWidth, int newHeight) { 159 setBoundsForFrame(f, newX, newY, newWidth, newHeight); 160 } 161 162 public void endResizingFrame(JComponent f) { 163 if(usingDragPane) { 164 JLayeredPane p = (JLayeredPane)f.getParent(); 165 p.remove(dragPane); 166 usingDragPane = false; 167 setBoundsForFrame(f, dragPane.getX(), dragPane.getY(), 168 dragPane.getWidth(), dragPane.getHeight()); 169 } 170 } 171 172 public void iconifyFrame(JInternalFrame f) { 173 JInternalFrame.JDesktopIcon icon = f.getDesktopIcon(); 174 Point p = icon.getLocation(); 175 adjustBoundsForIcon(icon, p.x, p.y); 176 super.iconifyFrame(f); 177 } 178 179 /** 180 * Change positions of icons in the desktop pane so that 181 * they do not overlap 182 */ 183 protected void adjustIcons(JDesktopPane desktop) { 184 // We need to know Motif icon size 185 JInternalFrame.JDesktopIcon icon = new JInternalFrame.JDesktopIcon( 186 new JInternalFrame()); 187 Dimension iconSize = icon.getPreferredSize(); 188 iconWidth = iconSize.width; 189 iconHeight = iconSize.height; 190 191 JInternalFrame[] frames = desktop.getAllFrames(); 192 for (int i=0; i<frames.length; i++) { 193 icon = frames[i].getDesktopIcon(); 194 Point ip = icon.getLocation(); 195 adjustBoundsForIcon(icon, ip.x, ip.y); 196 } 197 } 198 199 /** 200 * Change positions of icon so that it doesn't overlap 201 * other icons. 202 */ 203 protected void adjustBoundsForIcon(JInternalFrame.JDesktopIcon icon, 204 int x, int y) { 205 JDesktopPane c = icon.getDesktopPane(); 206 207 int maxy = c.getHeight(); 208 int w = iconWidth; 209 int h = iconHeight; 210 c.repaint(x, y, w, h); 211 x = x < 0 ? 0 : x; 212 y = y < 0 ? 0 : y; 213 214 /* Fix for disappearing icons. If the y value is maxy then this 215 * algorithm would place the icon in a non-displayed cell. Never 216 * to be ssen again.*/ 217 y = y >= maxy ? (maxy - 1) : y; 218 219 /* Compute the offset for the cell we are trying to go in. */ 220 int lx = (x / w) * w; 221 int ygap = maxy % h; 222 int ly = ((y-ygap) / h) * h + ygap; 223 224 /* How far are we into the cell we dropped the icon in. */ 225 int dx = x - lx; 226 int dy = y - ly; 227 228 /* Set coordinates for the icon. */ 229 x = dx < w/2 ? lx: lx + w; 230 y = dy < h/2 ? ly: ((ly + h) < maxy ? ly + h: ly); 231 232 while (getIconAt(c, icon, x, y) != null) { 233 x += w; 234 } 235 236 /* Cancel the move if the x value was moved off screen. */ 237 if (x > c.getWidth()) { 238 return; 239 } 240 if (icon.getParent() != null) { 241 setBoundsForFrame(icon, x, y, w, h); 242 } else { 243 icon.setLocation(x, y); 244 } 245 } 246 247 protected JInternalFrame.JDesktopIcon getIconAt(JDesktopPane desktop, 248 JInternalFrame.JDesktopIcon icon, int x, int y) { 249 250 JInternalFrame.JDesktopIcon currentIcon = null; 251 Component[] components = desktop.getComponents(); 252 253 for (int i=0; i<components.length; i++) { 254 Component comp = components[i]; 255 if (comp instanceof JInternalFrame.JDesktopIcon && 256 comp != icon) { 257 258 Point p = comp.getLocation(); 259 if (p.x == x && p.y == y) { 260 return (JInternalFrame.JDesktopIcon)comp; 261 } 262 } 263 } 264 return null; 265 } 266 }; /// END of MotifDesktopManager 267 }