# HG changeset patch # User alexp # Date 1251729581 -14400 # Node ID 906063616ec206f96d243840021c6916ccbb5050 # Parent 5e1b8bc3cb1a726adf02b0f8e15b93aa4e7b45df 6872503: JLayer event handling should be rewritten Reviewed-by: art diff -r 5e1b8bc3cb1a -r 906063616ec2 jdk/src/share/classes/javax/swing/JLayer.java --- a/jdk/src/share/classes/javax/swing/JLayer.java Mon Aug 31 13:56:34 2009 +0400 +++ b/jdk/src/share/classes/javax/swing/JLayer.java Mon Aug 31 18:39:41 2009 +0400 @@ -408,7 +408,10 @@ if (layerEventMask != oldEventMask) { disableEvents(oldEventMask); enableEvents(eventMask); - eventController.updateAWTEventListener(this); + if (isDisplayable()) { + eventController.updateAWTEventListener( + oldEventMask, layerEventMask); + } } } @@ -549,20 +552,30 @@ private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); - if (getUI() != null) { - setUI(getUI()); + if (layerUI != null) { + setUI(layerUI); + } + if (eventMask != 0) { + eventController.updateAWTEventListener(0, eventMask); } - if (getLayerEventMask() != 0) { - eventController.updateAWTEventListener(this); - } + } + + public void addNotify() { + eventController.updateAWTEventListener(0, eventMask); + super.addNotify(); + } + + public void removeNotify() { + eventController.updateAWTEventListener(eventMask, 0); + super.removeNotify(); } /** * static AWTEventListener to be shared with all AbstractLayerUIs */ private static class LayerEventController implements AWTEventListener { - private ArrayList> layerList = - new ArrayList>(); + private ArrayList layerMaskList = + new ArrayList(); private long currentEventMask; @@ -586,37 +599,24 @@ } } - private boolean layerListContains(JLayer l) { - for (WeakReference layerWeakReference : layerList) { - if (layerWeakReference.get() == l) { - return true; - } + private void updateAWTEventListener(long oldEventMask, long newEventMask) { + if (oldEventMask != 0) { + layerMaskList.remove(oldEventMask); } - return false; - } - - private void updateAWTEventListener(JLayer layer) { - if (!layerListContains(layer) && layer.getLayerEventMask() != 0) { - layerList.add(new WeakReference(layer)); + if (newEventMask != 0) { + layerMaskList.add(newEventMask); } long combinedMask = 0; - Iterator> it = layerList.iterator(); - while (it.hasNext()) { - WeakReference weakRef = it.next(); - JLayer currLayer = weakRef.get(); - if (currLayer == null) { - it.remove(); - } else { - combinedMask |= currLayer.getLayerEventMask(); - } + for (Long mask : layerMaskList) { + combinedMask |= mask; } if (combinedMask == 0) { removeAWTEventListener(); - layerList.clear(); } else if (getCurrentEventMask() != combinedMask) { removeAWTEventListener(); addAWTEventListener(combinedMask); } + currentEventMask = combinedMask; } private long getCurrentEventMask() { @@ -631,7 +631,7 @@ return null; } }); - currentEventMask = eventMask; + } private void removeAWTEventListener() { @@ -642,7 +642,6 @@ return null; } }); - currentEventMask = 0; } private boolean isEventEnabled(long eventMask, int id) { diff -r 5e1b8bc3cb1a -r 906063616ec2 jdk/test/javax/swing/JLayer/6872503/bug6872503.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/JLayer/6872503/bug6872503.java Mon Aug 31 18:39:41 2009 +0400 @@ -0,0 +1,135 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + * @bug 6872503 + * @summary Checks that JLayer correctly works with its AWTEventListener + * @author Alexander Potochkin + */ + +import javax.swing.*; +import java.awt.*; +import java.awt.event.AWTEventListener; +import java.awt.event.AWTEventListenerProxy; + +public class bug6872503 { + + static JLayer l1; + static JLayer l2; + + private static void createGui() { + Toolkit toolkit = Toolkit.getDefaultToolkit(); + int length = toolkit.getAWTEventListeners().length; + + l1 = new JLayer(); + l1.setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK); + + l2 = new JLayer(); + l2.setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.KEY_EVENT_MASK); + + if (isLayerEventControllerAdded()) { + throw new RuntimeException("Unexpected AWTEventListener was added"); + } + + JFrame frame = new JFrame(); + frame.setLayout(new FlowLayout()); + frame.add(l1); + frame.add(l2); + + if (isLayerEventControllerAdded()) { + throw new RuntimeException("Unexpected AWTEventListener was added"); + } + + frame.pack(); + + if (!isLayerEventControllerAdded()) { + throw new RuntimeException("AWTEventListener was not added"); + } + + if (!layerEventControllerMaskEquals(l1.getLayerEventMask() | l2.getLayerEventMask())) { + throw new RuntimeException("Wrong mask for AWTEventListener"); + } + + frame.dispose(); + + if (isLayerEventControllerAdded()) { + throw new RuntimeException("Unexpected AWTEventListener was added"); + } + } + + static boolean isLayerEventControllerAdded() { + Toolkit toolkit = Toolkit.getDefaultToolkit(); + AWTEventListener layerEventController = null; + for (AWTEventListener listener : toolkit.getAWTEventListeners()) { + if (listener instanceof AWTEventListenerProxy) { + listener = ((AWTEventListenerProxy)listener).getListener(); + + } + if ("LayerEventController".equals(listener.getClass().getSimpleName())) { + if (layerEventController != null) { + throw new RuntimeException("Duplicated LayerEventController"); + } + layerEventController = listener; + } + } + boolean ret = layerEventController != null; + if (ret) { + System.out.println("LayerEventController found"); + } else { + System.out.println("No LayerEventController"); + } + return ret; + } + + static boolean layerEventControllerMaskEquals(long mask) { + Toolkit toolkit = Toolkit.getDefaultToolkit(); + AWTEventListener layerEventController = null; + for (AWTEventListener listener : toolkit.getAWTEventListeners(mask)) { + if (listener instanceof AWTEventListenerProxy) { + listener = ((AWTEventListenerProxy)listener).getListener(); + + } + if ("LayerEventController".equals(listener.getClass().getSimpleName())) { + if (layerEventController != null) { + throw new RuntimeException("Duplicated LayerEventController"); + } + layerEventController = listener; + } + } + boolean ret = layerEventController != null; + if (ret) { + System.out.println("LayerEventController with the correct mask found"); + } else { + System.out.println("No LayerEventController with the correct mask"); + } + return ret; + } + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + bug6872503.createGui(); + } + }); + } +}