1 /* 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. 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 class Dock extends JComponent implements Border { 120 static final int DOCK_EDGE_SLACK = 8; 121 122 Dock(final JComponent parent) { 123 setBorder(this); 124 setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0)); 125 setVisible(false); 126 } 127 128 public void removeNotify() { 129 fDock = null; 130 super.removeNotify(); 131 } 132 133 void updateSize() { 134 final Dimension d = getPreferredSize(); 135 setBounds((getParent().getWidth() - d.width) / 2, getParent().getHeight() - d.height, d.width, d.height); 136 } 137 138 public Component add(final Component c) { 139 super.add(c); 140 if (!isVisible()) { 141 setVisible(true); 142 } 143 144 updateSize(); 145 validate(); 146 return c; 147 } 148 149 public void remove(final Component c) { 150 super.remove(c); 151 if (getComponentCount() == 0) { 152 setVisible(false); 153 } else { 154 updateSize(); 155 validate(); 156 } 157 } 158 159 public Insets getBorderInsets(final Component c) { 160 return new Insets(DOCK_EDGE_SLACK / 4, DOCK_EDGE_SLACK, 0, DOCK_EDGE_SLACK); 161 } 162 163 public boolean isBorderOpaque() { 164 return false; 165 } 166 167 public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int w, final int h) { 168 if (!(g instanceof Graphics2D)) return; 169 final Graphics2D g2d = (Graphics2D)g; 170 171 final int height = getHeight(); 172 final int width = getWidth(); 173 174 final Object priorAA = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING); 175 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 176 177 g2d.setColor(UIManager.getColor("DesktopIcon.borderColor")); 178 g2d.fillRoundRect(4, 4, width - 9, height + DOCK_EDGE_SLACK, DOCK_EDGE_SLACK, DOCK_EDGE_SLACK); 179 180 g2d.setColor(UIManager.getColor("DesktopIcon.borderRimColor")); 181 g2d.setStroke(new BasicStroke(2.0f)); 182 g2d.drawRoundRect(4, 4, width - 9, height + DOCK_EDGE_SLACK, DOCK_EDGE_SLACK, DOCK_EDGE_SLACK); 183 184 if (priorAA != null) g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, priorAA); 185 } 186 } 187 188 class AquaDockingDesktopManager extends AquaInternalFrameManager { 189 public void openFrame(final JInternalFrame f) { 190 final JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon(); 191 final Container dock = desktopIcon.getParent(); 192 if (dock == null) return; 193 194 if (dock.getParent() != null) dock.getParent().add(f); 195 removeIconFor(f); 196 } 197 198 public void deiconifyFrame(final JInternalFrame f) { 199 final JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon(); 200 final Container dock = desktopIcon.getParent(); 201 if (dock == null) return; 202 203 if (dock.getParent() != null) dock.getParent().add(f); 204 removeIconFor(f); 205 // <rdar://problem/3712485> removed f.show(). show() is now deprecated and 206 // it wasn't sending our frame to front nor selecting it. Now, we move it 207 // to front and select it manualy. (vm) 208 f.moveToFront(); 209 try { 210 f.setSelected(true); 211 } catch(final PropertyVetoException pve) { /* do nothing */ } 212 } 213 214 public void iconifyFrame(final JInternalFrame f) { 215 final JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon(); 216 // paint the frame onto the icon before hiding the frame, else the contents won't show 217 ((AquaInternalFrameDockIconUI)desktopIcon.getUI()).updateIcon(); 218 super.iconifyFrame(f); 219 } 220 221 void addIcon(final Container c, final JInternalFrame.JDesktopIcon desktopIcon) { 222 final DesktopPaneUI ui = ((JDesktopPane)c).getUI(); 223 ((AquaInternalFramePaneUI)ui).getDock().add(desktopIcon); 224 } 225 } 226 227 public void mousePressed(final MouseEvent e) { 228 JInternalFrame selectedFrame = desktop.getSelectedFrame(); 229 if (selectedFrame != null) { 230 try { 231 selectedFrame.setSelected(false); 232 } catch (PropertyVetoException ex) {} 233 desktop.getDesktopManager().deactivateFrame(selectedFrame); 234 } 235 } 236 237 public void mouseReleased(final MouseEvent e) { } 238 public void mouseClicked(final MouseEvent e) { } 239 public void mouseEntered(final MouseEvent e) { } 240 public void mouseExited(final MouseEvent e) { } 241 }