2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
28 import java.awt.Container;
29 import java.awt.Rectangle;
30 import java.beans.PropertyVetoException;
31 import java.util.Vector;
33 import javax.swing.DefaultDesktopManager;
34 import javax.swing.JInternalFrame;
36 import com.apple.laf.AquaInternalFramePaneUI;
39 * Based on AquaInternalFrameManager
41 * DesktopManager implementation for Aqua
43 * Mac is more like Windows than it's like Motif/Basic
45 * From WindowsDesktopManager:
47 * This class implements a DesktopManager which more closely follows the MDI
48 * model than the DefaultDesktopManager. Unlike the DefaultDesktopManager
49 * policy, MDI requires that the selected and activated child frames are the
50 * same, and that that frame always be the top-most window.
52 * The maximized state is managed by the DesktopManager with MDI, instead of
53 * just being a property of the individual child frame. This means that if the
54 * currently selected window is maximized and another window is selected, that
55 * new window will be maximized.
58 * https://raw.githubusercontent.com/frohoff/jdk8u-jdk/master/src/macosx/classes/com/apple/laf/AquaInternalFrameManager.java
60 * @see com.sun.java.swing.plaf.windows.WindowsDesktopManager
62 public class AquaInternalFrameManager extends DefaultDesktopManager
66 /* The frame which is currently selected/activated.
67 * We store this value to enforce Mac's single-selection model.
69 JInternalFrame fCurrentFrame;
71 JInternalFrame fInitialFrame;
73 AquaInternalFramePaneUI fCurrentPaneUI;
75 /* The list of frames, sorted by order of creation.
76 * This list is necessary because by default the order of
77 * child frames in the JDesktopPane changes during frame
78 * activation (the activated frame is moved to index 0).
79 * We preserve the creation order so that "next" and "previous"
80 * frame actions make sense.
82 Vector<JInternalFrame> fChildFrames = new Vector<>(1);
85 public void closeFrame(final JInternalFrame f)
87 if (f == fCurrentFrame)
91 fChildFrames.removeElement(f);
96 public void deiconifyFrame(final JInternalFrame f)
98 JInternalFrame.JDesktopIcon desktopIcon;
100 desktopIcon = f.getDesktopIcon();
101 // If the icon moved, move the frame to that spot before expanding it
102 // reshape does delta checks for us
103 f.reshape(desktopIcon.getX(), desktopIcon.getY(), f.getWidth(),
105 super.deiconifyFrame(f);
108 void addIcon(final Container c,
109 final JInternalFrame.JDesktopIcon desktopIcon)
115 * Removes the frame from its parent and adds its desktopIcon to the parent.
118 public void iconifyFrame(final JInternalFrame f)
120 // Same as super except doesn't deactivate it
121 JInternalFrame.JDesktopIcon desktopIcon;
124 desktopIcon = f.getDesktopIcon();
125 // Position depends on *current* position of frame, unlike super which
126 // reuses the first position
127 final Rectangle r = getBoundsForIconOf(f);
128 desktopIcon.setBounds(r.x, r.y, r.width, r.height);
137 addIcon(c, desktopIcon);
138 c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight());
141 // WindowsDesktopManager code
143 public void activateFrame(final JInternalFrame f)
149 super.activateFrame(f);
152 // If this is the first activation, add to child list.
153 if (fChildFrames.indexOf(f) == -1)
155 fChildFrames.addElement(f);
158 if (fCurrentFrame != null && f != fCurrentFrame)
160 if (fCurrentFrame.isSelected())
162 fCurrentFrame.setSelected(false);
166 if (f != null && !f.isSelected())
172 } catch (final PropertyVetoException e)
177 private void switchFrame(final boolean next)
179 if (fCurrentFrame == null)
181 // initialize first frame we find
182 if (fInitialFrame != null)
184 activateFrame(fInitialFrame);
189 final int count = fChildFrames.size();
192 // No other child frames.
196 final int currentIndex = fChildFrames.indexOf(fCurrentFrame);
197 if (currentIndex == -1)
199 // the "current frame" is no longer in the list
200 fCurrentFrame = null;
207 nextIndex = currentIndex + 1;
208 if (nextIndex == count)
215 nextIndex = currentIndex - 1;
218 nextIndex = count - 1;
221 final JInternalFrame f = fChildFrames.elementAt(nextIndex);
227 * Activate the next child JInternalFrame, as determined by the frames'
228 * Z-order. If there is only one child frame, it remains activated. If there
229 * are no child frames, nothing happens.
231 public void activateNextFrame()
237 * same as above but will activate a frame if none have been selected
239 public void activateNextFrame(final JInternalFrame f)
246 * Activate the previous child JInternalFrame, as determined by the frames'
247 * Z-order. If there is only one child frame, it remains activated. If there
248 * are no child frames, nothing happens.
250 public void activatePreviousFrame()