1/*
2 * Copyright (c) 2016, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 8160986 8174845 8176883
27 * @summary Bad rendering of Swing UI controls with Metal L&F on HiDPI display
28 * @run main/manual MetalHiDPIIconsTest
29 */
30import java.awt.Color;
31import java.awt.GridBagConstraints;
32import java.awt.GridBagLayout;
33import java.awt.event.ActionEvent;
34import java.awt.event.ActionListener;
35import java.awt.event.WindowAdapter;
36import java.awt.event.WindowEvent;
37import java.util.concurrent.CountDownLatch;
38import java.util.concurrent.TimeUnit;
39import javax.swing.JButton;
40import javax.swing.JFrame;
41import javax.swing.JPanel;
42import javax.swing.JTextArea;
43import javax.swing.SwingUtilities;
44
45public class MetalHiDPIIconsTest {
46
47    private static volatile boolean testResult = false;
48    private static volatile CountDownLatch countDownLatch;
49    private static final String INSTRUCTIONS = "INSTRUCTIONS:\n"
50            + "Verify that icons are painted smoothly for standard Swing UI controls.\n\n"
51            + "If the display does not support HiDPI mode press PASS.\n\n"
52            + "1. Run the SwingSet2 demo on HiDPI Display.\n"
53            + "2. Select Metal Look and Feel\n"
54            + "3. Check that the icons are painted smoothly on Swing UI controls like:\n"
55            + "  - JRadioButton\n"
56            + "  - JCheckBox\n"
57            + "  - JComboBox\n"
58            + "  - JScrollPane (vertical and horizontal scroll bars)\n"
59            + "  - JRadioButtonMenuItem\n"
60            + "  - JCheckBoxMenuItem\n"
61            + "and others...\n\n"
62            + "If so, press PASS, else press FAIL.\n";
63
64    public static void main(String args[]) throws Exception {
65        countDownLatch = new CountDownLatch(1);
66
67        SwingUtilities.invokeLater(MetalHiDPIIconsTest::createUI);
68        countDownLatch.await(15, TimeUnit.MINUTES);
69
70        if (!testResult) {
71            throw new RuntimeException("Test fails!");
72        }
73    }
74
75    private static void createUI() {
76
77        final JFrame mainFrame = new JFrame("Metal L&F icons test");
78        GridBagLayout layout = new GridBagLayout();
79        JPanel mainControlPanel = new JPanel(layout);
80        JPanel resultButtonPanel = new JPanel(layout);
81
82        GridBagConstraints gbc = new GridBagConstraints();
83
84        JTextArea instructionTextArea = new JTextArea();
85        instructionTextArea.setText(INSTRUCTIONS);
86        instructionTextArea.setEditable(false);
87        instructionTextArea.setBackground(Color.white);
88
89        gbc.gridx = 0;
90        gbc.gridy = 0;
91        gbc.fill = GridBagConstraints.HORIZONTAL;
92        mainControlPanel.add(instructionTextArea, gbc);
93
94        JButton passButton = new JButton("Pass");
95        passButton.setActionCommand("Pass");
96        passButton.addActionListener((ActionEvent e) -> {
97            testResult = true;
98            mainFrame.dispose();
99            countDownLatch.countDown();
100
101        });
102
103        JButton failButton = new JButton("Fail");
104        failButton.setActionCommand("Fail");
105        failButton.addActionListener(new ActionListener() {
106            @Override
107            public void actionPerformed(ActionEvent e) {
108                mainFrame.dispose();
109                countDownLatch.countDown();
110            }
111        });
112
113        gbc.gridx = 0;
114        gbc.gridy = 0;
115        resultButtonPanel.add(passButton, gbc);
116
117        gbc.gridx = 1;
118        gbc.gridy = 0;
119        resultButtonPanel.add(failButton, gbc);
120
121        gbc.gridx = 0;
122        gbc.gridy = 1;
123        mainControlPanel.add(resultButtonPanel, gbc);
124
125        mainFrame.add(mainControlPanel);
126        mainFrame.pack();
127
128        mainFrame.addWindowListener(new WindowAdapter() {
129
130            @Override
131            public void windowClosing(WindowEvent e) {
132                mainFrame.dispose();
133                countDownLatch.countDown();
134            }
135        });
136        mainFrame.setVisible(true);
137    }
138}
139