8031573: [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered in high resolution on Retina
Reviewed-by: serb, pchelko
--- a/jdk/src/macosx/classes/com/apple/laf/AquaImageFactory.java Tue Feb 25 16:12:22 2014 +0400
+++ b/jdk/src/macosx/classes/com/apple/laf/AquaImageFactory.java Tue Feb 25 16:46:52 2014 +0400
@@ -48,6 +48,7 @@
import com.apple.laf.AquaUtils.RecyclableSingleton;
import java.util.Arrays;
import java.util.List;
+import sun.awt.image.MultiResolutionBufferedImage;
import sun.awt.image.MultiResolutionImage;
public class AquaImageFactory {
@@ -230,7 +231,7 @@
@Override
protected Image getInstance() {
- return Toolkit.getDefaultToolkit().getImage("NSImage://" + namedImage);
+ return getNSIcon(namedImage);
}
}
@@ -294,11 +295,27 @@
}
public static Icon getMenuItemCheckIcon() {
- return new InvertableImageIcon(AquaUtils.generateLightenedImage(Toolkit.getDefaultToolkit().getImage("NSImage://NSMenuItemSelection"), 25));
+ return new InvertableImageIcon(AquaUtils.generateLightenedImage(
+ getNSIcon("NSMenuItemSelection"), 25));
}
public static Icon getMenuItemDashIcon() {
- return new InvertableImageIcon(AquaUtils.generateLightenedImage(Toolkit.getDefaultToolkit().getImage("NSImage://NSMenuMixedState"), 25));
+ return new InvertableImageIcon(AquaUtils.generateLightenedImage(
+ getNSIcon("NSMenuMixedState"), 25));
+ }
+
+ private static Image getNSIcon(String imageName) {
+ Image icon = Toolkit.getDefaultToolkit()
+ .getImage("NSImage://" + imageName);
+
+ if (icon instanceof MultiResolutionImage) {
+ return icon;
+ }
+
+ Image icon2x = AquaUtils.getCImageCreator().createImageFromName(
+ imageName, 2 * icon.getWidth(null), 2 * icon.getHeight(null));
+ return new MultiResolutionBufferedImage(
+ BufferedImage.TYPE_INT_ARGB_PRE, 0, icon, icon2x);
}
public static class NineSliceMetrics {
--- a/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java Tue Feb 25 16:12:22 2014 +0400
+++ b/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java Tue Feb 25 16:46:52 2014 +0400
@@ -48,6 +48,7 @@
import sun.swing.SwingUtilities2;
import com.apple.laf.AquaImageFactory.SlicedImageControl;
+import sun.awt.image.MultiResolutionBufferedImage;
final class AquaUtils {
@@ -123,6 +124,13 @@
static Image generateLightenedImage(final Image image, final int percent) {
final GrayFilter filter = new GrayFilter(true, percent);
+ return (image instanceof MultiResolutionBufferedImage)
+ ? ((MultiResolutionBufferedImage) image).map(
+ rv -> generateLightenedImage(rv, filter))
+ : generateLightenedImage(image, filter);
+ }
+
+ static Image generateLightenedImage(Image image, ImageFilter filter) {
final ImageProducer prod = new FilteredImageSource(image.getSource(), filter);
return Toolkit.getDefaultToolkit().createImage(prod);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java Tue Feb 25 16:46:52 2014 +0400
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.awt.image;
+
+import java.awt.Image;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Function;
+
+public class MultiResolutionBufferedImage extends BufferedImage
+ implements MultiResolutionImage {
+
+ Image[] resolutionVariants;
+ int baseIndex;
+
+ public MultiResolutionBufferedImage(int imageType, int baseIndex, Image... images) {
+ super(images[baseIndex].getWidth(null), images[baseIndex].getHeight(null),
+ imageType);
+ this.baseIndex = baseIndex;
+ this.resolutionVariants = images;
+ Graphics g = getGraphics();
+ g.drawImage(images[baseIndex], 0, 0, null);
+ g.dispose();
+ images[baseIndex] = this;
+ }
+
+ @Override
+ public Image getResolutionVariant(int width, int height) {
+ for (Image image : resolutionVariants) {
+ if (width <= image.getWidth(null) && height <= image.getHeight(null)) {
+ return image;
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public List<Image> getResolutionVariants() {
+ return Arrays.asList(resolutionVariants);
+ }
+
+ public MultiResolutionBufferedImage map(Function<Image, Image> mapper) {
+ return new MultiResolutionBufferedImage(getType(), baseIndex,
+ Arrays.stream(resolutionVariants).map(mapper)
+ .toArray(length -> new Image[length]));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JMenuItem/8031573/bug8031573.html Tue Feb 25 16:46:52 2014 +0400
@@ -0,0 +1,40 @@
+<!--
+ Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ or visit www.oracle.com if you need additional information or have any
+ questions.
+-->
+
+<html>
+<body>
+
+Verify that high resolution system icons are used JCheckBoxMenuItem
+on HiDPI displays.
+
+If the display does not support HiDPI mode press PASS.
+
+1. Run the test on HiDPI Display.
+2. Press the Menu in the applet
+3. Check that the icon on the JCheckBoxMenuItem is smooth
+If so, press PASS, else press FAIL.
+
+<applet code="bug8031573.class" width=250 height=250></applet>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JMenuItem/8031573/bug8031573.java Tue Feb 25 16:46:52 2014 +0400
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.awt.FlowLayout;
+import javax.swing.JApplet;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.SwingUtilities;
+
+/* @test
+ * @bug 8031573
+ * @summary [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered
+ * in high resolution on Retina
+ * @author Alexander Scherbatiy
+ * @run applet/manual=yesno bug8031573.html
+ */
+public class bug8031573 extends JApplet {
+
+ @Override
+ public void init() {
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+
+ @Override
+ public void run() {
+ JMenuBar bar = new JMenuBar();
+ JMenu menu = new JMenu("Menu");
+ JCheckBoxMenuItem checkBoxMenuItem
+ = new JCheckBoxMenuItem("JCheckBoxMenuItem");
+ checkBoxMenuItem.setSelected(true);
+ menu.add(checkBoxMenuItem);
+ bar.add(menu);
+ setJMenuBar(bar);
+ }
+ });
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}