001: /*
002: * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.java.swing.plaf.motif;
027:
028: import javax.swing.*;
029: import java.awt.Rectangle;
030: import java.awt.Dimension;
031: import java.awt.Insets;
032: import java.awt.Color;
033: import java.awt.Graphics;
034: import java.awt.Component;
035: import java.awt.Point;
036: import javax.swing.plaf.*;
037: import java.io.Serializable;
038:
039: /**
040: * <p>
041: * <strong>Warning:</strong>
042: * Serialized objects of this class will not be compatible with
043: * future Swing releases. The current serialization support is appropriate
044: * for short term storage or RMI between applications running the same
045: * version of Swing. A future release of Swing will provide support for
046: * long term persistence.
047: *
048: * @version 1.32 05/05/07
049: * @author David Kloba
050: */
051: public class MotifDesktopPaneUI extends
052: javax.swing.plaf.basic.BasicDesktopPaneUI {
053:
054: /// DesktopPaneUI methods
055: public static ComponentUI createUI(JComponent d) {
056: return new MotifDesktopPaneUI();
057: }
058:
059: public MotifDesktopPaneUI() {
060: }
061:
062: protected void installDesktopManager() {
063: desktopManager = desktop.getDesktopManager();
064: if (desktopManager == null) {
065: desktopManager = new MotifDesktopManager();
066: desktop.setDesktopManager(desktopManager);
067: ((MotifDesktopManager) desktopManager).adjustIcons(desktop);
068: }
069: }
070:
071: public Insets getInsets(JComponent c) {
072: return new Insets(0, 0, 0, 0);
073: }
074:
075: ////////////////////////////////////////////////////////////////////////////////////
076: /// DragPane class
077: ////////////////////////////////////////////////////////////////////////////////////
078: private class DragPane extends JComponent {
079: public void paint(Graphics g) {
080: g.setColor(Color.darkGray);
081: g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
082: }
083: };
084:
085: ////////////////////////////////////////////////////////////////////////////////////
086: /// MotifDesktopManager class
087: ////////////////////////////////////////////////////////////////////////////////////
088: private class MotifDesktopManager extends DefaultDesktopManager
089: implements Serializable, UIResource {
090: JComponent dragPane;
091: boolean usingDragPane = false;
092: private transient JLayeredPane layeredPaneForDragPane;
093: int iconWidth, iconHeight;
094:
095: // PENDING(klobad) this should be optimized
096: public void setBoundsForFrame(JComponent f, int newX, int newY,
097: int newWidth, int newHeight) {
098: if (!usingDragPane) {
099: boolean didResize;
100: didResize = (f.getWidth() != newWidth || f.getHeight() != newHeight);
101: Rectangle r = f.getBounds();
102: f.setBounds(newX, newY, newWidth, newHeight);
103: SwingUtilities.computeUnion(newX, newY, newWidth,
104: newHeight, r);
105: f.getParent().repaint(r.x, r.y, r.width, r.height);
106: if (didResize) {
107: f.validate();
108: }
109: } else {
110: Rectangle r = dragPane.getBounds();
111: dragPane.setBounds(newX, newY, newWidth, newHeight);
112: SwingUtilities.computeUnion(newX, newY, newWidth,
113: newHeight, r);
114: dragPane.getParent().repaint(r.x, r.y, r.width,
115: r.height);
116: }
117: }
118:
119: public void beginDraggingFrame(JComponent f) {
120: usingDragPane = false;
121: if (f.getParent() instanceof JLayeredPane) {
122: if (dragPane == null)
123: dragPane = new DragPane();
124: layeredPaneForDragPane = (JLayeredPane) f.getParent();
125: layeredPaneForDragPane.setLayer(dragPane,
126: Integer.MAX_VALUE);
127: dragPane.setBounds(f.getX(), f.getY(), f.getWidth(), f
128: .getHeight());
129: layeredPaneForDragPane.add(dragPane);
130: usingDragPane = true;
131: }
132: }
133:
134: public void dragFrame(JComponent f, int newX, int newY) {
135: setBoundsForFrame(f, newX, newY, f.getWidth(), f
136: .getHeight());
137: }
138:
139: public void endDraggingFrame(JComponent f) {
140: if (usingDragPane) {
141: layeredPaneForDragPane.remove(dragPane);
142: usingDragPane = false;
143: if (f instanceof JInternalFrame) {
144: setBoundsForFrame(f, dragPane.getX(), dragPane
145: .getY(), dragPane.getWidth(), dragPane
146: .getHeight());
147: } else if (f instanceof JInternalFrame.JDesktopIcon) {
148: adjustBoundsForIcon(
149: (JInternalFrame.JDesktopIcon) f, dragPane
150: .getX(), dragPane.getY());
151: }
152: }
153: }
154:
155: public void beginResizingFrame(JComponent f, int direction) {
156: usingDragPane = false;
157: if (f.getParent() instanceof JLayeredPane) {
158: if (dragPane == null)
159: dragPane = new DragPane();
160: JLayeredPane p = (JLayeredPane) f.getParent();
161: p.setLayer(dragPane, Integer.MAX_VALUE);
162: dragPane.setBounds(f.getX(), f.getY(), f.getWidth(), f
163: .getHeight());
164: p.add(dragPane);
165: usingDragPane = true;
166: }
167: }
168:
169: public void resizeFrame(JComponent f, int newX, int newY,
170: int newWidth, int newHeight) {
171: setBoundsForFrame(f, newX, newY, newWidth, newHeight);
172: }
173:
174: public void endResizingFrame(JComponent f) {
175: if (usingDragPane) {
176: JLayeredPane p = (JLayeredPane) f.getParent();
177: p.remove(dragPane);
178: usingDragPane = false;
179: setBoundsForFrame(f, dragPane.getX(), dragPane.getY(),
180: dragPane.getWidth(), dragPane.getHeight());
181: }
182: }
183:
184: public void iconifyFrame(JInternalFrame f) {
185: JInternalFrame.JDesktopIcon icon = f.getDesktopIcon();
186: Point p = icon.getLocation();
187: adjustBoundsForIcon(icon, p.x, p.y);
188: super .iconifyFrame(f);
189: }
190:
191: /**
192: * Change positions of icons in the desktop pane so that
193: * they do not overlap
194: */
195: protected void adjustIcons(JDesktopPane desktop) {
196: // We need to know Motif icon size
197: JInternalFrame.JDesktopIcon icon = new JInternalFrame.JDesktopIcon(
198: new JInternalFrame());
199: Dimension iconSize = icon.getPreferredSize();
200: iconWidth = iconSize.width;
201: iconHeight = iconSize.height;
202:
203: JInternalFrame[] frames = desktop.getAllFrames();
204: for (int i = 0; i < frames.length; i++) {
205: icon = frames[i].getDesktopIcon();
206: Point ip = icon.getLocation();
207: adjustBoundsForIcon(icon, ip.x, ip.y);
208: }
209: }
210:
211: /**
212: * Change positions of icon so that it doesn't overlap
213: * other icons.
214: */
215: protected void adjustBoundsForIcon(
216: JInternalFrame.JDesktopIcon icon, int x, int y) {
217: JDesktopPane c = icon.getDesktopPane();
218:
219: int maxy = c.getHeight();
220: int w = iconWidth;
221: int h = iconHeight;
222: c.repaint(x, y, w, h);
223: x = x < 0 ? 0 : x;
224: y = y < 0 ? 0 : y;
225:
226: /* Fix for disappearing icons. If the y value is maxy then this
227: * algorithm would place the icon in a non-displayed cell. Never
228: * to be ssen again.*/
229: y = y >= maxy ? (maxy - 1) : y;
230:
231: /* Compute the offset for the cell we are trying to go in. */
232: int lx = (x / w) * w;
233: int ygap = maxy % h;
234: int ly = ((y - ygap) / h) * h + ygap;
235:
236: /* How far are we into the cell we dropped the icon in. */
237: int dx = x - lx;
238: int dy = y - ly;
239:
240: /* Set coordinates for the icon. */
241: x = dx < w / 2 ? lx : lx + w;
242: y = dy < h / 2 ? ly : ((ly + h) < maxy ? ly + h : ly);
243:
244: while (getIconAt(c, icon, x, y) != null) {
245: x += w;
246: }
247:
248: /* Cancel the move if the x value was moved off screen. */
249: if (x > c.getWidth()) {
250: return;
251: }
252: if (icon.getParent() != null) {
253: setBoundsForFrame(icon, x, y, w, h);
254: } else {
255: icon.setLocation(x, y);
256: }
257: }
258:
259: protected JInternalFrame.JDesktopIcon getIconAt(
260: JDesktopPane desktop, JInternalFrame.JDesktopIcon icon,
261: int x, int y) {
262:
263: JInternalFrame.JDesktopIcon currentIcon = null;
264: Component[] components = desktop.getComponents();
265:
266: for (int i = 0; i < components.length; i++) {
267: Component comp = components[i];
268: if (comp instanceof JInternalFrame.JDesktopIcon
269: && comp != icon) {
270:
271: Point p = comp.getLocation();
272: if (p.x == x && p.y == y) {
273: return (JInternalFrame.JDesktopIcon) comp;
274: }
275: }
276: }
277: return null;
278: }
279: }; /// END of MotifDesktopManager
280: }
|