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 
  24 import java.awt.*;
  25 import java.awt.image.BufferedImage;
  26 import java.beans.PropertyChangeEvent;
  27 import 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 
  37 public 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 }