/* * Copyright (c) 2016, 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. */ /* * @test * @bug 8150724 8151303 * @author a.stepanov * @summary Check that correct resolution variants are chosen for icons * when multiresolution image is used for their construction. * * @requires (os.family != "mac") * * @library ../../../../lib/testlibrary/ * @build ExtendedRobot * @run main/othervm/timeout=240 -Dsun.java2d.uiScale=1 MultiresolutionIconTest * @run main/othervm/timeout=240 -Dsun.java2d.uiScale=2 MultiresolutionIconTest */ // TODO: please remove the "@requires" tag after 8151303 fix import java.awt.*; import java.awt.event.InputEvent; import java.awt.geom.AffineTransform; import java.awt.image.BaseMultiResolutionImage; import java.awt.image.BufferedImage; import javax.swing.*; public class MultiresolutionIconTest extends JFrame { private final static int SZ = 100; private final static int N = 5; // number of components private final static String SCALE = "sun.java2d.uiScale"; private final static Color C1X = Color.RED; private final static Color C2X = Color.BLUE; private JLabel lbl; private JTabbedPane tabbedPane; private final ExtendedRobot r; private static BufferedImage generateImage(int sz, Color c) { BufferedImage img = new BufferedImage(sz, sz, BufferedImage.TYPE_INT_RGB); Graphics g = img.getGraphics(); g.setColor(c); g.fillRect(0, 0, sz, sz); return img; } public MultiresolutionIconTest(UIManager.LookAndFeelInfo lf) throws Exception { UIManager.setLookAndFeel(lf.getClassName()); r = new ExtendedRobot(); SwingUtilities.invokeAndWait(this::UI); } private void UI() { setUndecorated(true); BufferedImage img1x = generateImage(SZ / 2, C1X); BufferedImage img2x = generateImage(SZ, C2X); BaseMultiResolutionImage mri = new BaseMultiResolutionImage( new BufferedImage[]{img1x, img2x}); Icon icon = new ImageIcon(mri); // hardcoded icon size for OS X (Mac OS X L&F) - see JDK-8151060 BufferedImage tab1x = generateImage(16, C1X); BufferedImage tab2x = generateImage(32, C2X); BaseMultiResolutionImage tabMRI = new BaseMultiResolutionImage( new BufferedImage[]{tab1x, tab2x}); Icon tabIcon = new ImageIcon(tabMRI); setSize((N + 1) * SZ, SZ); setLocation(50, 50); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); getContentPane().setLayout(new GridLayout(1, 1)); JPanel p = new JPanel(); p.setLayout(new GridLayout(1, N)); JButton btn = new JButton(icon); p.add(btn); JToggleButton tbn = new JToggleButton(icon); p.add(tbn); JRadioButton rbn = new JRadioButton(icon); rbn.setHorizontalAlignment(SwingConstants.CENTER); p.add(rbn); JCheckBox cbx = new JCheckBox(icon); cbx.setHorizontalAlignment(SwingConstants.CENTER); p.add(cbx); lbl = new JLabel(icon); p.add(lbl); tabbedPane = new JTabbedPane(JTabbedPane.LEFT); tabbedPane.addTab("", tabIcon, p); getContentPane().add(tabbedPane); setResizable(false); setVisible(true); } private static boolean is2x() { AffineTransform tr = GraphicsEnvironment.getLocalGraphicsEnvironment(). getDefaultScreenDevice().getDefaultConfiguration(). getDefaultTransform(); return (Math.min(tr.getScaleX(), tr.getScaleY()) > 1.001); } private boolean checkPressedColor(int x, int y, Color ok) { r.mouseMove(x, y); r.waitForIdle(); r.mousePress(InputEvent.BUTTON1_DOWN_MASK); r.waitForIdle(100); Color c = r.getPixelColor(x, y); r.waitForIdle(100); r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); r.waitForIdle(100); if (!c.equals(ok)) { return false; } // check the icon's color hasn't changed // after the mouse was released c = r.getPixelColor(x, y); return c.equals(ok); } private boolean checkTabIcon( int xStart, int xEnd, int yStart, int yEnd, Color ok, Color nok) { for (int y = yStart; y < yEnd; y += 2) { for (int x = xStart; x < xEnd; x += 2) { Color c = r.getPixelColor(x, y); if (c.equals(nok)) { return false; } else if (c.equals(ok)) { // shift a bit to avoid the selection effects return checkPressedColor(x + 5, y + 5, ok); } } } return false; // didn't find the icon } private void doTest() { r.waitForIdle(2000); String scale = System.getProperty(SCALE); System.out.println("scale = " + scale); Color expected = is2x() ? C2X : C1X, unexpected = is2x() ? C1X : C2X; Point p = lbl.getLocationOnScreen(); int x = p.x + lbl.getWidth() / 2; int y = p.y + lbl.getHeight() / 2; int w = lbl.getWidth(); boolean ok = true, curr; Color c; String components[] = new String[]{ "JLabel", "JCheckBox", "JRadioButton", "JToggleButton", "JButton"}; for (int i = 0; i < N; i++) { curr = true; int t = x - i * w; // check icon color c = r.getPixelColor(t, y); System.out.print(components[i] + " icon: "); if (!c.equals(expected)) { curr = false; } else { // check icon color when mouse button pressed - see JDK-8151303 curr = checkPressedColor(t, y, expected); } System.out.println(curr ? "ok" : "nok"); ok = ok && curr; r.waitForIdle(); } int x0 = tabbedPane.getLocationOnScreen().x; int x1 = x - ((N - 1) * w + w / 2); int y0 = getLocationOnScreen().y; int y1 = y0 + getHeight(); curr = checkTabIcon(x0, x1, y0, y1, expected, unexpected); System.out.println("JTabbedPane icon: " + (curr ? "ok" : "nok")); ok = ok && curr; if (!ok) { throw new RuntimeException("test failed"); } r.waitForIdle(); dispose(); } public static void main(String[] args) throws Exception { // TODO: remove is2x() check after JDK-8150844 fix if (is2x() != "2".equals(System.getProperty(SCALE))) { return; } for (UIManager.LookAndFeelInfo LF: UIManager.getInstalledLookAndFeels()) { System.out.println("\nL&F: " + LF.getName()); (new MultiresolutionIconTest(LF)).doTest(); } } }