1 /*
2  * Copyright (c) 2017, 2020, 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 import java.awt.Dimension;
25 import java.awt.EventQueue;
26 import java.awt.FlowLayout;
27 import java.awt.Font;
28 import java.awt.Robot;
29 import java.awt.Toolkit;
30 import java.lang.reflect.Method;
31 
32 import javax.swing.JButton;
33 import javax.swing.JFrame;
34 import javax.swing.UIManager;
35 import javax.swing.plaf.FontUIResource;
36 
37 /**
38  * @test
39  * @key headful
40  * @bug 8075255
41  * @summary tests if the desktop property changes this will force the UIs to
42  *          update all known Frames
43  * @requires (os.family == "windows")
44  * @modules java.desktop/java.awt:open java.desktop/sun.awt
45  */
46 public final class RevalidateOnPropertyChange {
47 
48     private static JFrame frame;
49     private static JButton button;
50     private static volatile Dimension sizeAfter;
51     private static volatile Dimension sizeBefore;
52     private static volatile boolean flag;
53 
main(String[] args)54     public static void main(String[] args) throws Exception {
55         System.setProperty("swing.useSystemFontSettings", "true");
56         UIManager.put("Application.useSystemFontSettings", true);
57 
58         // this functionality is supported on windows in "Windows and Metal L&F"
59         test("com.sun.java.swing.plaf.windows.WindowsLookAndFeel",
60              "win.defaultGUI.font",
61              new Font(Font.DIALOG, FontUIResource.BOLD, 40));
62         test("javax.swing.plaf.metal.MetalLookAndFeel",
63              "win.ansiVar.font.height", 70);
64     }
65 
66     /**
67      * Emulates the property change via reflection.
68      */
test(String laf, String prop, Object value)69     static void test(String laf, String prop, Object value) throws Exception {
70         Class cls = Toolkit.class;
71         Method setDesktopProperty =
72                 cls.getDeclaredMethod("setDesktopProperty", String.class,
73                                       Object.class);
74         setDesktopProperty.setAccessible(true);
75 
76         UIManager.setLookAndFeel(laf);
77         EventQueue.invokeAndWait(RevalidateOnPropertyChange::createGUI);
78 
79         Robot r = new Robot();
80         r.waitForIdle();
81 
82         EventQueue.invokeAndWait(() -> {
83             sizeBefore = button.getSize();
84         });
85 
86         Toolkit toolkit = Toolkit.getDefaultToolkit();
87         toolkit.addPropertyChangeListener(prop, evt -> flag = true);
88         setDesktopProperty.invoke(toolkit, prop, value);
89         r.waitForIdle();
90 
91         EventQueue.invokeAndWait(() -> {
92             sizeAfter = button.getSize();
93             frame.dispose();
94         });
95 
96         if (!flag) {
97             throw new RuntimeException("The listener was not notified");
98         }
99         if (sizeAfter.equals(sizeBefore)) {
100             throw new RuntimeException("Size was not changed :" + sizeAfter);
101         }
102     }
103 
createGUI()104     private static void createGUI() {
105         frame = new JFrame();
106         button = new JButton(UIManager.getLookAndFeel().getName());
107         frame.setLayout(new FlowLayout());
108         frame.getContentPane().add(button);
109         frame.setSize(400, 400);
110         frame.setLocationRelativeTo(null);
111         frame.setVisible(true);
112     }
113 }
114