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;
37 * Based on AquaInternalFrameManager
39 * DesktopManager implementation for Aqua
41 * Mac is more like Windows than it's like Motif/Basic
43 * From WindowsDesktopManager:
45 * This class implements a DesktopManager which more closely follows the MDI
46 * model than the DefaultDesktopManager. Unlike the DefaultDesktopManager
47 * policy, MDI requires that the selected and activated child frames are the
48 * same, and that that frame always be the top-most window.
50 * The maximized state is managed by the DesktopManager with MDI, instead of
51 * just being a property of the individual child frame. This means that if the
52 * currently selected window is maximized and another window is selected, that
53 * new window will be maximized.
56 * https://raw.githubusercontent.com/frohoff/jdk8u-jdk/master/src/macosx/classes/com/apple/laf/AquaInternalFrameManager.java
58 * Patch from Jim Procter - when the most recently opened frame is closed,
59 * correct behaviour is to go to the next most recent frame, rather than wrap
60 * around to the bottom of the window stack (as the original implementation
63 * @see com.sun.java.swing.plaf.windows.WindowsDesktopManager
65 public class AquaInternalFrameManager extends DefaultDesktopManager
69 /* The frame which is currently selected/activated.
70 * We store this value to enforce Mac's single-selection model.
72 JInternalFrame fCurrentFrame;
74 JInternalFrame fInitialFrame;
76 /* The list of frames, sorted by order of creation.
77 * This list is necessary because by default the order of
78 * child frames in the JDesktopPane changes during frame
79 * activation (the activated frame is moved to index 0).
80 * We preserve the creation order so that "next" and "previous"
81 * frame actions make sense.
83 Vector<JInternalFrame> fChildFrames = new Vector<>(1);
86 public void closeFrame(final JInternalFrame f)
88 if (f == fCurrentFrame)
90 boolean mostRecentFrame = fChildFrames
91 .indexOf(f) == fChildFrames.size() - 1;
98 activatePreviousFrame();
101 fChildFrames.removeElement(f);
106 public void deiconifyFrame(final JInternalFrame f)
108 JInternalFrame.JDesktopIcon desktopIcon;
110 desktopIcon = f.getDesktopIcon();
111 // If the icon moved, move the frame to that spot before expanding it
112 // reshape does delta checks for us
113 f.reshape(desktopIcon.getX(), desktopIcon.getY(), f.getWidth(),
115 super.deiconifyFrame(f);
118 void addIcon(final Container c,
119 final JInternalFrame.JDesktopIcon desktopIcon)
125 * Removes the frame from its parent and adds its desktopIcon to the parent.
128 public void iconifyFrame(final JInternalFrame f)
130 // Same as super except doesn't deactivate it
131 JInternalFrame.JDesktopIcon desktopIcon;
134 desktopIcon = f.getDesktopIcon();
135 // Position depends on *current* position of frame, unlike super which
136 // reuses the first position
137 final Rectangle r = getBoundsForIconOf(f);
138 desktopIcon.setBounds(r.x, r.y, r.width, r.height);
147 addIcon(c, desktopIcon);
148 c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight());
151 // WindowsDesktopManager code
153 public void activateFrame(final JInternalFrame f)
159 super.activateFrame(f);
162 // If this is the first activation, add to child list.
163 if (fChildFrames.indexOf(f) == -1)
165 fChildFrames.addElement(f);
168 if (fCurrentFrame != null && f != fCurrentFrame)
170 if (fCurrentFrame.isSelected())
172 fCurrentFrame.setSelected(false);
176 if (f != null && !f.isSelected())
182 } catch (final PropertyVetoException e)
187 private void switchFrame(final boolean next)
189 if (fCurrentFrame == null)
191 // initialize first frame we find
192 if (fInitialFrame != null)
194 activateFrame(fInitialFrame);
199 final int count = fChildFrames.size();
202 // No other child frames.
206 final int currentIndex = fChildFrames.indexOf(fCurrentFrame);
207 if (currentIndex == -1)
209 // the "current frame" is no longer in the list
210 fCurrentFrame = null;
217 nextIndex = currentIndex + 1;
218 if (nextIndex == count)
225 nextIndex = currentIndex - 1;
228 nextIndex = count - 1;
231 final JInternalFrame f = fChildFrames.elementAt(nextIndex);
237 * Activate the next child JInternalFrame, as determined by the frames'
238 * Z-order. If there is only one child frame, it remains activated. If there
239 * are no child frames, nothing happens.
241 public void activateNextFrame()
247 * same as above but will activate a frame if none have been selected
249 public void activateNextFrame(final JInternalFrame f)
256 * Activate the previous child JInternalFrame, as determined by the frames'
257 * Z-order. If there is only one child frame, it remains activated. If there
258 * are no child frames, nothing happens.
260 public void activatePreviousFrame()