1/*
2 * Copyright (c) 2007, 2014, 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
24import java.awt.*;
25import java.awt.image.BufferedImage;
26import java.beans.PropertyChangeEvent;
27import java.beans.PropertyChangeListener;
28
29/*
30 * @test
31 * @summary Check if custom property change listener added
32 *          to system tray works correctly
33 * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com)
34 * @run main PropertyChangeListenerTest
35 */
36
37public class PropertyChangeListenerTest implements PropertyChangeListener {
38
39    Object property;
40    Object lock = new Object();
41    boolean propertyChanged = false;
42
43    public static void main(String[] args) throws Exception {
44        if (! SystemTray.isSupported()) {
45            System.out.println("SystemTray not supported on the platform under test. " +
46                    "Marking the test passed");
47        } else {
48            new PropertyChangeListenerTest().doTest();
49        }
50    }
51
52    public void propertyChange(PropertyChangeEvent event) {
53        if (! "trayIcons".equals(event.getPropertyName()))
54            throw new RuntimeException("ERROR: PropertyName not matching. Event " +
55                    "triggered for a different property\n"+
56                    "Property: " + event.getPropertyName());
57        property = event.getNewValue();
58        propertyChanged = true;
59        synchronized (lock) {
60            try {
61                lock.notifyAll();
62            } catch (Exception e) {
63            }
64        }
65    }
66
67    void doTest() throws Exception {
68        propertyChanged = false;
69        SystemTray tray = SystemTray.getSystemTray();
70
71        tray.addPropertyChangeListener(null, null);
72        tray.addPropertyChangeListener("trayIcons", null);
73        tray.addPropertyChangeListener("trayIcons", this);
74
75        BufferedImage img = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB);
76        Graphics g = img.createGraphics();
77        g.setColor(Color.WHITE);
78        g.fillRect(0, 0, 32, 32);
79        g.setColor(Color.RED);
80        g.fillRect(6, 6, 20, 20);
81        g.dispose();
82
83        TrayIcon icon = new TrayIcon(img);
84        if (propertyChanged)
85            throw new RuntimeException("FAIL: spurious property events triggered");
86
87        propertyChanged = false;
88        tray.add(icon);
89
90        if (! propertyChanged) {
91            synchronized (lock) {
92                try {
93                    lock.wait(3000);
94                } catch (Exception e) {
95                }
96            }
97        }
98        if (! propertyChanged) {
99            throw new RuntimeException("FAIL: property event did not get triggered when tray icon added");
100        } else {
101            if (! (property instanceof TrayIcon[])) {
102                throw new RuntimeException("FAIL: property is not TrayIcon[]. TrayIcon added.");
103            } else {
104                TrayIcon[] icons = (TrayIcon[]) property;
105                if (icons.length != 1 || ! icon.equals(icons[0])) {
106                    throw new RuntimeException("FAIL: TrayIcon[] returned by the " +
107                            "PropertyChangeEvent is incorrect. TrayIcon added.\n"+
108                            "icon[] length: " + icons.length);
109                }
110            }
111        }
112
113        propertyChanged = false;
114        tray.remove(icon);
115
116        if (! propertyChanged) {
117            synchronized (lock) {
118                try {
119                    lock.wait(3000);
120                } catch (Exception e) {
121                }
122            }
123        }
124        if (! propertyChanged) {
125            throw new RuntimeException("FAIL: property event did not get triggered when tray icon removed");
126        } else {
127            if (! (property instanceof TrayIcon[])) {
128                throw new RuntimeException("FAIL: property is not TrayIcon[]. TrayIcon removed.");
129            } else {
130                TrayIcon[] icons = (TrayIcon[]) property;
131                if (icons.length != 0) {
132                    throw new RuntimeException("FAIL: TrayIcon[] returned by the " +
133                            "PropertyChangeEvent is incorrect. TrayIcon removed.\n"+
134                            "icon[] length: " + icons.length);
135                }
136            }
137        }
138
139        tray.removePropertyChangeListener("trayIcons", null);
140        tray.removePropertyChangeListener("trayIcons", this);
141
142        propertyChanged = false;
143        tray.add(icon);
144
145        Thread.sleep(3000);
146        if (propertyChanged)
147            throw new RuntimeException("FAIL: property listener notified even after " +
148                    "removing the listener from SystemTray. TrayIcon added.");
149
150        propertyChanged = false;
151        tray.remove(icon);
152
153        Thread.sleep(3000);
154        if (propertyChanged)
155            throw new RuntimeException("FAIL: property listener notified even after " +
156                    "removing the listener from SystemTray. TrayIcon removed.");
157
158        tray.addPropertyChangeListener("someName", this);
159
160        propertyChanged = false;
161        tray.add(icon);
162
163        Thread.sleep(3000);
164        if (propertyChanged)
165            throw new RuntimeException("FAIL: property listener notified when " +
166                    "listener added for a different property. TrayIcon added.");
167
168        propertyChanged = false;
169        tray.remove(icon);
170
171        Thread.sleep(3000);
172        if (propertyChanged)
173            throw new RuntimeException("FAIL: property listener notified when " +
174                    "listener added for a different property. TrayIcon removed.");
175
176        tray.addPropertyChangeListener("trayIcons", this);
177        tray.addPropertyChangeListener("trayIcons", this);
178        PropertyChangeListener listener = event -> { };
179        tray.addPropertyChangeListener("trayIcons", listener);
180        tray.addPropertyChangeListener("sampleProp", event -> {});
181
182        if (tray.getPropertyChangeListeners("trayIcons").length != 3) {
183            throw new RuntimeException("FAIL: getPropertyChangeListeners did not return the " +
184                    "correct value for trayIcons property. Expected: 3, " +
185                    "Actual: " + tray.getPropertyChangeListeners("trayIcons").length);
186        } else if (! this.equals(tray.getPropertyChangeListeners("trayIcons")[0]) ||
187                   ! this.equals(tray.getPropertyChangeListeners("trayIcons")[1]) ||
188                   ! listener.equals(tray.getPropertyChangeListeners("trayIcons")[2])) {
189            throw new RuntimeException("FAIL: getPropertyChangeListeners did not return the " +
190                    "expected listeners\n" +
191                    "tray.getPropertyChangeListeners('trayIcons')[0] " + tray.getPropertyChangeListeners("trayIcons")[0]+"\n"+
192                    "tray.getPropertyChangeListeners('trayIcons')[1] " + tray.getPropertyChangeListeners("trayIcons")[1]+"\n"+
193                    "tray.getPropertyChangeListeners('trayIcons')[2] " + tray.getPropertyChangeListeners("trayIcons")[2]);
194        }
195
196        if (tray.getPropertyChangeListeners("sampleProp").length != 1)
197            throw new RuntimeException("FAIL: getPropertyChangeListeners did not return the " +
198                    "expected listener for 'sampleProp'");
199
200    }
201}
202