001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package javax.swing;
019:
020: import java.awt.Color;
021: import java.awt.Component;
022: import java.awt.Container;
023: import java.awt.Dimension;
024: import java.awt.Graphics;
025: import java.awt.Rectangle;
026:
027: import java.beans.PropertyVetoException;
028:
029: import java.io.Serializable;
030:
031: import org.apache.harmony.x.swing.Utilities;
032:
033: /**
034: * <p>
035: * <i>DefaultDesktopManager</i>
036: * </p>
037: * <h3>Implementation Notes:</h3>
038: * <ul>
039: * <li>The <code>serialVersionUID</code> fields are explicitly declared as a performance
040: * optimization, not as a guarantee of serialization compatibility.</li>
041: * </ul>
042: */
043: public class DefaultDesktopManager implements DesktopManager,
044: Serializable {
045: private static final long serialVersionUID = 3138850139820361176L;
046:
047: private static final String WAS_ICON_PROPERTY = "wasIcon";
048:
049: private transient boolean isOutlineDragging;
050:
051: private transient Rectangle prevOutlineBounds;
052:
053: // is true if we have begun to drag/resize but didn't move the mouse
054: private transient boolean shouldClearOutline = true;
055:
056: public void minimizeFrame(JInternalFrame f) {
057: Rectangle bounds = getPreviousBounds(f);
058: setBoundsForFrame(f, bounds.x, bounds.y, bounds.width,
059: bounds.height);
060: }
061:
062: public void maximizeFrame(JInternalFrame f) {
063: Container desktop = f.getParent();
064: if (desktop == null) {
065: return;
066: }
067: setPreviousBounds(f, f.getBounds());
068: Rectangle innerBounds = getInnerBounds(desktop);
069: setBoundsForFrame(f, innerBounds.x, innerBounds.y,
070: innerBounds.width, innerBounds.height);
071: try {
072: f.setSelected(true);
073: } catch (PropertyVetoException e) {
074: }
075: }
076:
077: public void iconifyFrame(JInternalFrame f) {
078: Container desktop = f.getParent();
079: if (desktop == null) {
080: return;
081: }
082: if (!wasIcon(f)) {
083: f.getDesktopIcon().setBounds(getBoundsForIconOf(f));
084: }
085: JLayeredPane.putLayer(f.getDesktopIcon(), f.getLayer());
086: try {
087: f.setSelected(false);
088: } catch (PropertyVetoException e) {
089: }
090: desktop.remove(f);
091: desktop.add(f.getDesktopIcon());
092: setWasIcon(f, Boolean.TRUE);
093: moveSelectionToNextFrame(desktop);
094: repaint(desktop, f.getBounds());
095: }
096:
097: public void deiconifyFrame(JInternalFrame f) {
098: addFrame(f, true);
099: }
100:
101: public void openFrame(JInternalFrame f) {
102: addFrame(f, false);
103: }
104:
105: public void deactivateFrame(JInternalFrame f) {
106: JDesktopPane desktop = f.getDesktopPane();
107: if (desktop != null) {
108: desktop.setSelectedFrame(null);
109: }
110: }
111:
112: public void closeFrame(JInternalFrame f) {
113: try {
114: f.setSelected(false);
115: } catch (PropertyVetoException e) {
116: }
117: removeIconFor(f);
118: Container desktop = f.getParent();
119: if (desktop == null) {
120: return;
121: }
122: desktop.remove(f);
123: repaint(desktop, f.getBounds());
124: moveSelectionToNextFrame(desktop);
125: }
126:
127: public void activateFrame(JInternalFrame f) {
128: JDesktopPane desktop = f.getDesktopPane();
129: if (desktop == null || desktop.getSelectedFrame() == f) {
130: return;
131: }
132: if (desktop.getSelectedFrame() != null) {
133: try {
134: desktop.getSelectedFrame().setSelected(false);
135: } catch (PropertyVetoException e) {
136: }
137: }
138: desktop.moveToFront(f);
139: desktop.setSelectedFrame(f);
140: }
141:
142: public void setBoundsForFrame(JComponent f, int x, int y,
143: int width, int height) {
144: f.setBounds(x, y, width, height);
145: }
146:
147: public void beginResizingFrame(JComponent f, int direction) {
148: beginDragFrameOperation(f);
149: }
150:
151: public void resizeFrame(JComponent f, int x, int y, int width,
152: int height) {
153: if (isOutlineDragging) {
154: moveFrameOutline(f, x, y, width, height);
155: } else {
156: setBoundsForFrame(f, x, y, width, height);
157: }
158: }
159:
160: public void endResizingFrame(JComponent f) {
161: endDragFrameOperation(f);
162: }
163:
164: public void beginDraggingFrame(JComponent f) {
165: beginDragFrameOperation(f);
166: }
167:
168: public void dragFrame(JComponent f, int x, int y) {
169: if (isOutlineDragging) {
170: moveFrameOutline(f, x, y, prevOutlineBounds.width,
171: prevOutlineBounds.height);
172: } else {
173: setBoundsForFrame(f, x, y, f.getWidth(), f.getHeight());
174: }
175: }
176:
177: public void endDraggingFrame(JComponent f) {
178: endDragFrameOperation(f);
179: }
180:
181: protected void setWasIcon(JInternalFrame f, Boolean value) {
182: f.putClientProperty(WAS_ICON_PROPERTY, value);
183: }
184:
185: protected boolean wasIcon(JInternalFrame f) {
186: Object value = f.getClientProperty(WAS_ICON_PROPERTY);
187: return value instanceof Boolean ? ((Boolean) value)
188: .booleanValue() : false;
189: }
190:
191: protected void setPreviousBounds(JInternalFrame f, Rectangle bounds) {
192: f.setNormalBounds(bounds);
193: }
194:
195: protected Rectangle getPreviousBounds(JInternalFrame f) {
196: return f.getNormalBounds();
197: }
198:
199: protected Rectangle getBoundsForIconOf(JInternalFrame f) {
200: if (wasIcon(f)) {
201: return f.getDesktopIcon().getBounds();
202: }
203: Dimension iconSize = f.getDesktopIcon().getSize();
204: Rectangle result = new Rectangle(0, 0, iconSize.width,
205: iconSize.height);
206: Container desktop = f.getParent();
207: if (desktop == null) {
208: return result;
209: }
210: Rectangle innerBounds = getInnerBounds(desktop);
211: // maximum x position
212: int totalWidth = innerBounds.width - iconSize.width;
213: if (totalWidth < 0) {
214: totalWidth = 0;
215: }
216: result.y = (int) innerBounds.getMaxY() - iconSize.height;
217: while (true) {
218: for (result.x = innerBounds.x; result.x <= totalWidth; result.x += iconSize.width) {
219: if (isFreeDesktopIconPosition(desktop, result)) {
220: return result;
221: }
222: }
223: result.y -= iconSize.height;
224: }
225: }
226:
227: protected void removeIconFor(JInternalFrame f) {
228: Container desktop = f.getDesktopIcon().getParent();
229: if (desktop == null) {
230: return;
231: }
232: desktop.remove(f.getDesktopIcon());
233: repaint(desktop, f.getDesktopIcon().getBounds());
234: }
235:
236: private boolean isFreeDesktopIconPosition(Container desktop,
237: Rectangle bounds) {
238: for (int i = 0; i < desktop.getComponentCount(); i++) {
239: Component c = desktop.getComponent(i);
240: Rectangle occupiedBouds = null;
241: if (c instanceof JInternalFrame.JDesktopIcon) {
242: occupiedBouds = c.getBounds();
243: } else if (c instanceof JInternalFrame) {
244: JInternalFrame f = (JInternalFrame) c;
245: if (wasIcon(f)) {
246: occupiedBouds = f.getDesktopIcon().getBounds();
247: }
248: }
249: if (occupiedBouds != null
250: && bounds.intersects(occupiedBouds)) {
251: return false;
252: }
253: }
254: return true;
255: }
256:
257: private void moveSelectionToNextFrame(Container desktop) {
258: for (int i = 0; i < desktop.getComponentCount(); i++) {
259: if (desktop.getComponent(i) instanceof JInternalFrame) {
260: try {
261: ((JInternalFrame) desktop.getComponent(i))
262: .setSelected(true);
263: break;
264: } catch (PropertyVetoException e) {
265: }
266: }
267: }
268: }
269:
270: private void paintOutline(JComponent f, int x, int y, int width,
271: int height) {
272: Graphics g = f.getParent().getGraphics();
273: g = g.create();
274: g.setXORMode(Color.WHITE);
275: if (shouldClearOutline) {
276: g.drawRect(prevOutlineBounds.x, prevOutlineBounds.y,
277: prevOutlineBounds.width - 1,
278: prevOutlineBounds.height - 1);
279: } else {
280: shouldClearOutline = true;
281: }
282: g.drawRect(x, y, width - 1, height - 1);
283: g.dispose();
284: }
285:
286: private void repaint(Container desktop, Rectangle clipRect) {
287: desktop.repaint(clipRect.x, clipRect.y, clipRect.width,
288: clipRect.height);
289: }
290:
291: private void addFrame(JInternalFrame f, boolean select) {
292: Container desktop = f.getDesktopIcon().getParent();
293: if (desktop == null) {
294: return;
295: }
296: removeIconFor(f);
297: if (!select) {
298: desktop.add(f);
299: } else {
300: desktop.add(f, 0);
301: try {
302: f.setSelected(true);
303: } catch (PropertyVetoException e) {
304: }
305: }
306: }
307:
308: private void beginDragFrameOperation(JComponent f) {
309: isOutlineDragging = false;
310: if (!(f.getParent() instanceof JDesktopPane)) {
311: return;
312: }
313: JDesktopPane desktop = (JDesktopPane) f.getParent();
314: if (desktop.getDragMode() == JDesktopPane.OUTLINE_DRAG_MODE) {
315: isOutlineDragging = true;
316: prevOutlineBounds = f.getBounds(prevOutlineBounds);
317: shouldClearOutline = false;
318: }
319: }
320:
321: private void endDragFrameOperation(JComponent f) {
322: if (isOutlineDragging) {
323: setBoundsForFrame(f, prevOutlineBounds.x,
324: prevOutlineBounds.y, prevOutlineBounds.width,
325: prevOutlineBounds.height);
326: isOutlineDragging = false;
327: }
328: }
329:
330: private void moveFrameOutline(JComponent f, int x, int y,
331: int width, int height) {
332: paintOutline(f, x, y, width, height);
333: prevOutlineBounds.setBounds(x, y, width, height);
334: }
335:
336: private Rectangle getInnerBounds(Container parent) {
337: Rectangle innerBounds = new Rectangle(0, 0, parent.getWidth(),
338: parent.getHeight());
339: return Utilities
340: .subtractInsets(innerBounds, parent.getInsets());
341: }
342: }
|