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