1 /* 2 * Copyright (c) 2011, 2014, 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.apple.laf; 27 28 import java.awt.*; 29 import java.awt.event.*; 30 import java.beans.PropertyVetoException; 31 32 import javax.swing.*; 33 import javax.swing.border.Border; 34 import javax.swing.plaf.*; 35 import javax.swing.plaf.basic.BasicDesktopPaneUI; 36 37 public class AquaInternalFramePaneUI extends BasicDesktopPaneUI implements MouseListener { 38 39 JComponent fDock; 40 DockLayoutManager fLayoutMgr; 41 42 public static ComponentUI createUI(final JComponent c) { 43 return new AquaInternalFramePaneUI(); 44 } 45 46 public void update(final Graphics g, final JComponent c) { 47 if (c.isOpaque()) { 48 super.update(g, c); 49 return; 50 } 51 paint(g, c); 52 } 53 54 public void installUI(final JComponent c) { 55 super.installUI(c); 56 fLayoutMgr = new DockLayoutManager(); 57 c.setLayout(fLayoutMgr); 58 59 c.addMouseListener(this); 60 } 61 62 public void uninstallUI(final JComponent c) { 63 c.removeMouseListener(this); 64 65 if (fDock != null) { 66 c.remove(fDock); 67 fDock = null; 68 } 69 if (fLayoutMgr != null) { 70 c.setLayout(null); 71 fLayoutMgr = null; 72 } 73 super.uninstallUI(c); 74 } 75 76 // Our superclass hardcodes DefaultDesktopManager - how rude! 77 protected void installDesktopManager() { 78 if (desktop.getDesktopManager() == null) { 79 desktopManager = new AquaDockingDesktopManager(); 80 desktop.setDesktopManager(desktopManager); 81 } 82 } 83 84 protected void uninstallDesktopManager() { 85 final DesktopManager manager = desktop.getDesktopManager(); 86 if (manager instanceof AquaDockingDesktopManager) { 87 desktop.setDesktopManager(null); 88 } 89 } 90 91 JComponent getDock() { 92 if (fDock == null) { 93 fDock = new Dock(desktop); 94 desktop.add(fDock, new Integer(399)); // Just below the DRAG_LAYER 95 } 96 return fDock; 97 } 98 99 class DockLayoutManager implements LayoutManager { 100 public void addLayoutComponent(final String name, final Component comp) { 101 } 102 103 public void removeLayoutComponent(final Component comp) { 104 } 105 106 public Dimension preferredLayoutSize(final Container parent) { 107 return parent.getSize(); 108 } 109 110 public Dimension minimumLayoutSize(final Container parent) { 111 return parent.getSize(); 112 } 113 114 public void layoutContainer(final Container parent) { 115 if (fDock != null) ((Dock)fDock).updateSize(); 116 } 117 } 118 119 @SuppressWarnings("serial") // Superclass is not serializable across versions 120 class Dock extends JComponent implements Border { 121 static final int DOCK_EDGE_SLACK = 8; 122 123 Dock(final JComponent parent) { 124 setBorder(this); 125 setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0)); 126 setVisible(false); 127 } 128 129 public void removeNotify() { 130 fDock = null; 131 super.removeNotify(); 132 } 133 134 void updateSize() { 135 final Dimension d = getPreferredSize(); 136 setBounds((getParent().getWidth() - d.width) / 2, getParent().getHeight() - d.height, d.width, d.height); 137 } 138 139 public Component add(final Component c) { 140 super.add(c); 141 if (!isVisible()) { 142 setVisible(true); 143 } 144 145 updateSize(); 146 validate(); 147 return c; 148 } 149 150 public void remove(final Component c) { 151 super.remove(c); 152 if (getComponentCount() == 0) { 153 setVisible(false); 154 } else { 155 updateSize(); 156 validate(); 157 } 158 } 159 160 public Insets getBorderInsets(final Component c) { 161 return new Insets(DOCK_EDGE_SLACK / 4, DOCK_EDGE_SLACK, 0, DOCK_EDGE_SLACK); 162 } 163 164 public boolean isBorderOpaque() { 165 return false; 166 } 167 168 public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int w, final int h) { 169 if (!(g instanceof Graphics2D)) return; 170 final Graphics2D g2d = (Graphics2D)g; 171 172 final int height = getHeight(); 173 final int width = getWidth(); 174 175 final Object priorAA = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING); 176 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 177 178 g2d.setColor(UIManager.getColor("DesktopIcon.borderColor")); 179 g2d.fillRoundRect(4, 4, width - 9, height + DOCK_EDGE_SLACK, DOCK_EDGE_SLACK, DOCK_EDGE_SLACK); 180 181 g2d.setColor(UIManager.getColor("DesktopIcon.borderRimColor")); 182 g2d.setStroke(new BasicStroke(2.0f)); 183 g2d.drawRoundRect(4, 4, width - 9, height + DOCK_EDGE_SLACK, DOCK_EDGE_SLACK, DOCK_EDGE_SLACK); 184 185 if (priorAA != null) g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, priorAA); 186 } 187 } 188 189 @SuppressWarnings("serial") // JDK implementation class 190 class AquaDockingDesktopManager extends AquaInternalFrameManager { 191 public void openFrame(final JInternalFrame f) { 192 final JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon(); 193 final Container dock = desktopIcon.getParent(); 194 if (dock == null) return; 195 196 if (dock.getParent() != null) dock.getParent().add(f); 197 removeIconFor(f); 198 } 199 200 public void deiconifyFrame(final JInternalFrame f) { 201 final JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon(); 202 final Container dock = desktopIcon.getParent(); 203 if (dock == null) return; 204 205 if (dock.getParent() != null) dock.getParent().add(f); 206 removeIconFor(f); 207 // <rdar://problem/3712485> removed f.show(). show() is now deprecated and 208 // it wasn't sending our frame to front nor selecting it. Now, we move it 209 // to front and select it manualy. (vm) 210 f.moveToFront(); 211 try { 212 f.setSelected(true); 213 } catch(final PropertyVetoException pve) { /* do nothing */ } 214 } 215 216 public void iconifyFrame(final JInternalFrame f) { 217 final JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon(); 218 // paint the frame onto the icon before hiding the frame, else the contents won't show 219 ((AquaInternalFrameDockIconUI)desktopIcon.getUI()).updateIcon(); 220 super.iconifyFrame(f); 221 } 222 223 void addIcon(final Container c, final JInternalFrame.JDesktopIcon desktopIcon) { 224 final DesktopPaneUI ui = ((JDesktopPane)c).getUI(); 225 ((AquaInternalFramePaneUI)ui).getDock().add(desktopIcon); 226 } 227 } 228 229 public void mousePressed(final MouseEvent e) { 230 JInternalFrame selectedFrame = desktop.getSelectedFrame(); 231 if (selectedFrame != null) { 232 try { 233 selectedFrame.setSelected(false); 234 } catch (PropertyVetoException ex) {} 235 desktop.getDesktopManager().deactivateFrame(selectedFrame); 236 } 237 } 238 239 public void mouseReleased(final MouseEvent e) { } 240 public void mouseClicked(final MouseEvent e) { } 241 public void mouseEntered(final MouseEvent e) { } 242 public void mouseExited(final MouseEvent e) { } 243 }