Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/classes/com/apple/laf/AquaInternalFrameDockIconUI.java
38831 views
/*1* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.apple.laf;2627import java.awt.*;28import java.awt.event.*;29import java.awt.geom.Rectangle2D;30import java.awt.image.BufferedImage;31import java.beans.PropertyVetoException;3233import javax.swing.*;34import javax.swing.plaf.*;3536import sun.swing.SwingUtilities2;3738/**39* From MacDockIconUI40*41* A JRSUI L&F implementation of JInternalFrame.JDesktopIcon42* @author43* @version44*/45public class AquaInternalFrameDockIconUI extends DesktopIconUI implements MouseListener, MouseMotionListener, ComponentListener {46private static final String CACHED_FRAME_ICON_KEY = "apple.laf.internal.frameIcon";4748protected JInternalFrame.JDesktopIcon fDesktopIcon;49protected JInternalFrame fFrame;50protected ScaledImageLabel fIconPane;51protected DockLabel fDockLabel;52protected boolean fTrackingIcon = false;5354public static ComponentUI createUI(final JComponent c) {55return new AquaInternalFrameDockIconUI();56}5758public void installUI(final JComponent c) {59fDesktopIcon = (JInternalFrame.JDesktopIcon)c;60installComponents();61installListeners();62}6364public void uninstallUI(final JComponent c) {65uninstallComponents();66uninstallListeners();67fDesktopIcon = null;68fFrame = null;69}7071protected void installComponents() {72fFrame = fDesktopIcon.getInternalFrame();73fIconPane = new ScaledImageLabel();74fDesktopIcon.setLayout(new BorderLayout());75fDesktopIcon.add(fIconPane, BorderLayout.CENTER);76}7778protected void uninstallComponents() {79fDesktopIcon.setLayout(null);80fDesktopIcon.remove(fIconPane);81}8283protected void installListeners() {84fDesktopIcon.addMouseListener(this);85fDesktopIcon.addMouseMotionListener(this);86fFrame.addComponentListener(this);87}8889protected void uninstallListeners() {90fFrame.removeComponentListener(this);91fDesktopIcon.removeMouseMotionListener(this);92fDesktopIcon.removeMouseListener(this);93}9495public Dimension getMinimumSize(final JComponent c) {96return new Dimension(32, 32);97}9899public Dimension getMaximumSize(final JComponent c) {100return new Dimension(128, 128);101}102103public Dimension getPreferredSize(final JComponent c) {104return new Dimension(64, 64); //$ Dock preferred size105}106107public Insets getInsets(final JComponent c) {108return new Insets(0, 0, 0, 0);109}110111void updateIcon() {112fIconPane.updateIcon();113}114115public void mousePressed(final MouseEvent e) {116fTrackingIcon = fIconPane.mouseInIcon(e);117if (fTrackingIcon) fIconPane.repaint();118}119120public void mouseReleased(final MouseEvent e) {// only when it's actually in the image121if (fFrame.isIconifiable() && fFrame.isIcon()) {122if (fTrackingIcon) {123fTrackingIcon = false;124if (fIconPane.mouseInIcon(e)) {125if (fDockLabel != null) fDockLabel.hide();126try {127fFrame.setIcon(false);128} catch(final PropertyVetoException e2) {}129} else {130fIconPane.repaint();131}132}133}134135// if the mouse was completely outside fIconPane, hide the label136if (fDockLabel != null && !fIconPane.getBounds().contains(e.getX(), e.getY())) fDockLabel.hide();137}138139public void mouseEntered(final MouseEvent e) {140if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) return;141String title = fFrame.getTitle();142if (title == null || title.equals("")) title = "Untitled";143fDockLabel = new DockLabel(title);144fDockLabel.show(fDesktopIcon);145}146147public void mouseExited(final MouseEvent e) {148if (fDockLabel != null && (e.getModifiers() & InputEvent.BUTTON1_MASK) == 0) fDockLabel.hide();149}150151public void mouseClicked(final MouseEvent e) { }152153public void mouseDragged(final MouseEvent e) { }154155public void mouseMoved(final MouseEvent e) { }156157public void componentHidden(final ComponentEvent e) { }158159public void componentMoved(final ComponentEvent e) { }160161public void componentResized(final ComponentEvent e) {162fFrame.putClientProperty(CACHED_FRAME_ICON_KEY, null);163}164165public void componentShown(final ComponentEvent e) {166fFrame.putClientProperty(CACHED_FRAME_ICON_KEY, null);167}168169class ScaledImageLabel extends JLabel {170ScaledImageLabel() {171super(null, null, CENTER);172}173174void updateIcon() {175final Object priorIcon = fFrame.getClientProperty(CACHED_FRAME_ICON_KEY);176if (priorIcon instanceof ImageIcon) {177setIcon((ImageIcon)priorIcon);178return;179}180181int width = fFrame.getWidth();182int height = fFrame.getHeight();183184// Protect us from unsized frames, like in JCK test DefaultDesktopManager2008185if (width <= 0 || height <= 0) {186width = 128;187height = 128;188}189190final Image fImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);191final Graphics g = fImage.getGraphics();192fFrame.paint(g);193g.dispose();194195final float scale = (float)fDesktopIcon.getWidth() / (float)Math.max(width, height) * 0.89f;196// Sending in -1 for width xor height causes it to maintain aspect ratio197final ImageIcon icon = new ImageIcon(fImage.getScaledInstance((int)(width * scale), -1, Image.SCALE_SMOOTH));198fFrame.putClientProperty(CACHED_FRAME_ICON_KEY, icon);199setIcon(icon);200}201202public void paint(final Graphics g) {203if (getIcon() == null) updateIcon();204205g.translate(0, 2);206207if (!fTrackingIcon) {208super.paint(g);209return;210}211212final ImageIcon prev = (ImageIcon)getIcon();213final ImageIcon pressedIcon = new ImageIcon(AquaUtils.generateSelectedDarkImage(prev.getImage()));214setIcon(pressedIcon);215super.paint(g);216setIcon(prev);217}218219boolean mouseInIcon(final MouseEvent e) {220return getBounds().contains(e.getX(), e.getY());221}222223public Dimension getPreferredSize() {224return new Dimension(64, 64); //$ Dock preferred size225}226}227228class DockLabel extends JLabel {229final static int NUB_HEIGHT = 7;230final static int ROUND_ADDITIONAL_HEIGHT = 8;231final static int ROUND_ADDITIONAL_WIDTH = 12;232233DockLabel(final String text) {234super(text);235setBorder(null);236setOpaque(false);237setFont(AquaFonts.getDockIconFont());238239final FontMetrics metrics = getFontMetrics(getFont());240setSize(SwingUtilities.computeStringWidth(metrics, getText()) + ROUND_ADDITIONAL_WIDTH * 2, metrics.getAscent() + NUB_HEIGHT + ROUND_ADDITIONAL_HEIGHT);241}242243public void paint(final Graphics g) {244final int width = getWidth();245final int height = getHeight();246247final Font font = getFont();248final FontMetrics metrics = getFontMetrics(font);249g.setFont(font);250251final String text = getText().trim();252final int ascent = metrics.getAscent();253254final Rectangle2D stringBounds = metrics.getStringBounds(text, g);255final int halfway = width / 2;256257final int x = (halfway - (int)stringBounds.getWidth() / 2);258259final Graphics2D g2d = g instanceof Graphics2D ? (Graphics2D)g : null;260if (g2d != null) {261g.setColor(UIManager.getColor("DesktopIcon.labelBackground"));262final Object origAA = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);263g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);264265final int roundHeight = height - ROUND_ADDITIONAL_HEIGHT + 1;266g.fillRoundRect(0, 0, width, roundHeight, roundHeight, roundHeight);267268final int[] xpts = { halfway, halfway + NUB_HEIGHT, halfway - NUB_HEIGHT };269final int[] ypts = { height, height - NUB_HEIGHT, height - NUB_HEIGHT };270g.fillPolygon(xpts, ypts, 3);271272g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, origAA);273}274275g.setColor(Color.black);276SwingUtilities2.drawString(this, g, text, x, 2 + ascent);277g.setColor(Color.white);278SwingUtilities2.drawString(this, g, text, x, 1 + ascent);279}280281public void show(final Component invoker) {282final int desiredLocationX = (invoker.getWidth() - getWidth()) / 2;283final int desiredLocationY = -(getHeight() + 6);284285Container parent = invoker.getParent();286287for (Container p = parent; p != null; p = p.getParent()) {288if (p instanceof JRootPane) {289if (p.getParent() instanceof JInternalFrame) continue;290parent = ((JRootPane)p).getLayeredPane();291for (p = parent.getParent(); p != null && (!(p instanceof java.awt.Window)); p = p.getParent());292break;293}294}295296final Point p = SwingUtilities.convertPoint(invoker, desiredLocationX, desiredLocationY, parent);297setLocation(p.x, p.y);298if (parent instanceof JLayeredPane) {299((JLayeredPane)parent).add(this, JLayeredPane.POPUP_LAYER, 0);300}301}302303public void hide() {304final Container parent = getParent();305final Rectangle r = this.getBounds();306if (parent == null) return;307parent.remove(this);308parent.repaint(r.x, r.y, r.width, r.height);309}310}311}312313314