提交 42f2bff1 编写于 作者: A azvegint

8061636: Fix for JDK-7079254 changes behavior of MouseListener, MouseMotionListener

Reviewed-by: alexsch, serb
上级 598b02e4
/*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2015, Oracle and/or its affiliates. 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
......@@ -1669,15 +1669,6 @@ public abstract class Component implements ImageObserver, MenuContainer,
/* do nothing */
}
/*
* Delete references from LightweithDispatcher of a heavyweight parent
*/
void clearLightweightDispatcherOnRemove(Component removedComponent) {
if (parent != null) {
parent.clearLightweightDispatcherOnRemove(removedComponent);
}
}
/**
* @deprecated As of JDK version 1.1,
* replaced by <code>setVisible(boolean)</code>.
......@@ -6180,7 +6171,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
/**
* Indicates whether a class or its superclasses override coalesceEvents.
* Must be called with lock on coalesceMap and privileged.
* @see checkCoalsecing
* @see checkCoalescing
*/
private static boolean isCoalesceEventsOverriden(Class<?> clazz) {
assert Thread.holdsLock(coalesceMap);
......@@ -6986,8 +6977,6 @@ public abstract class Component implements ImageObserver, MenuContainer,
}
synchronized (getTreeLock()) {
clearLightweightDispatcherOnRemove(this);
if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabledFor(this)) {
transferFocus(true);
}
......
/*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2015, Oracle and/or its affiliates. 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
......@@ -41,6 +41,7 @@ import java.io.ObjectStreamField;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.util.EventListener;
......@@ -3310,16 +3311,6 @@ public class Container extends Component {
}
}
@Override
void clearLightweightDispatcherOnRemove(Component removedComponent) {
if (dispatcher != null) {
dispatcher.removeReferences(removedComponent);
} else {
//It is a Lightweight Container, should clear parent`s Dispatcher
super.clearLightweightDispatcherOnRemove(removedComponent);
}
}
final Container getTraversalRoot() {
if (isFocusCycleRoot()) {
return findTraversalRoot();
......@@ -4413,7 +4404,9 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener {
LightweightDispatcher(Container nativeContainer) {
this.nativeContainer = nativeContainer;
mouseEventTarget = null;
mouseEventTarget = new WeakReference<>(null);
targetLastEntered = new WeakReference<>(null);
targetLastEnteredDT = new WeakReference<>(null);
eventMask = 0;
}
......@@ -4424,9 +4417,9 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener {
void dispose() {
//System.out.println("Disposing lw dispatcher");
stopListeningForOtherDrags();
mouseEventTarget = null;
targetLastEntered = null;
targetLastEnteredDT = null;
mouseEventTarget.clear();
targetLastEntered.clear();
targetLastEnteredDT.clear();
}
/**
......@@ -4513,65 +4506,62 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener {
trackMouseEnterExit(mouseOver, e);
// 4508327 : MOUSE_CLICKED should only go to the recipient of
// the accompanying MOUSE_PRESSED, so don't reset mouseEventTarget on a
// MOUSE_CLICKED.
if (!isMouseGrab(e) && id != MouseEvent.MOUSE_CLICKED) {
mouseEventTarget = (mouseOver != nativeContainer) ? mouseOver: null;
isCleaned = false;
Component met = mouseEventTarget.get();
// 4508327 : MOUSE_CLICKED should only go to the recipient of
// the accompanying MOUSE_PRESSED, so don't reset mouseEventTarget on a
// MOUSE_CLICKED.
if (!isMouseGrab(e) && id != MouseEvent.MOUSE_CLICKED) {
met = (mouseOver != nativeContainer) ? mouseOver : null;
mouseEventTarget = new WeakReference<>(met);
}
if (mouseEventTarget != null) {
if (met != null) {
switch (id) {
case MouseEvent.MOUSE_ENTERED:
case MouseEvent.MOUSE_EXITED:
break;
case MouseEvent.MOUSE_PRESSED:
retargetMouseEvent(mouseEventTarget, id, e);
break;
case MouseEvent.MOUSE_RELEASED:
retargetMouseEvent(mouseEventTarget, id, e);
break;
case MouseEvent.MOUSE_CLICKED:
// 4508327: MOUSE_CLICKED should never be dispatched to a Component
// other than that which received the MOUSE_PRESSED event. If the
// mouse is now over a different Component, don't dispatch the event.
// The previous fix for a similar problem was associated with bug
// 4155217.
if (mouseOver == mouseEventTarget) {
retargetMouseEvent(mouseOver, id, e);
}
break;
case MouseEvent.MOUSE_MOVED:
retargetMouseEvent(mouseEventTarget, id, e);
break;
case MouseEvent.MOUSE_DRAGGED:
if (isMouseGrab(e)) {
retargetMouseEvent(mouseEventTarget, id, e);
}
break;
case MouseEvent.MOUSE_WHEEL:
// This may send it somewhere that doesn't have MouseWheelEvents
// enabled. In this case, Component.dispatchEventImpl() will
// retarget the event to a parent that DOES have the events enabled.
if (eventLog.isLoggable(PlatformLogger.Level.FINEST) && (mouseOver != null)) {
eventLog.finest("retargeting mouse wheel to " +
case MouseEvent.MOUSE_ENTERED:
case MouseEvent.MOUSE_EXITED:
break;
case MouseEvent.MOUSE_PRESSED:
retargetMouseEvent(met, id, e);
break;
case MouseEvent.MOUSE_RELEASED:
retargetMouseEvent(met, id, e);
break;
case MouseEvent.MOUSE_CLICKED:
// 4508327: MOUSE_CLICKED should never be dispatched to a Component
// other than that which received the MOUSE_PRESSED event. If the
// mouse is now over a different Component, don't dispatch the event.
// The previous fix for a similar problem was associated with bug
// 4155217.
if (mouseOver == met) {
retargetMouseEvent(mouseOver, id, e);
}
break;
case MouseEvent.MOUSE_MOVED:
retargetMouseEvent(met, id, e);
break;
case MouseEvent.MOUSE_DRAGGED:
if (isMouseGrab(e)) {
retargetMouseEvent(met, id, e);
}
break;
case MouseEvent.MOUSE_WHEEL:
// This may send it somewhere that doesn't have MouseWheelEvents
// enabled. In this case, Component.dispatchEventImpl() will
// retarget the event to a parent that DOES have the events enabled.
if (eventLog.isLoggable(PlatformLogger.Level.FINEST) && (mouseOver != null)) {
eventLog.finest("retargeting mouse wheel to " +
mouseOver.getName() + ", " +
mouseOver.getClass());
}
retargetMouseEvent(mouseOver, id, e);
break;
}
retargetMouseEvent(mouseOver, id, e);
break;
//Consuming of wheel events is implemented in "retargetMouseEvent".
if (id != MouseEvent.MOUSE_WHEEL) {
e.consume();
}
//Consuming of wheel events is implemented in "retargetMouseEvent".
if (id != MouseEvent.MOUSE_WHEEL) {
e.consume();
}
} else if (isCleaned && id != MouseEvent.MOUSE_WHEEL) {
//After mouseEventTarget was removed and cleaned should consume all events
//until new mouseEventTarget is found
e.consume();
}
return e.isConsumed();
return e.isConsumed();
}
private boolean processDropTargetEvent(SunDropTargetEvent e) {
......@@ -4634,9 +4624,10 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener {
} else if (id == MouseEvent.MOUSE_EXITED) {
isMouseDTInNativeContainer = false;
}
targetLastEnteredDT = retargetMouseEnterExit(targetOver, e,
targetLastEnteredDT,
Component tle = retargetMouseEnterExit(targetOver, e,
targetLastEnteredDT.get(),
isMouseDTInNativeContainer);
targetLastEnteredDT = new WeakReference<>(tle);
}
/*
......@@ -4662,9 +4653,10 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener {
isMouseInNativeContainer = false;
stopListeningForOtherDrags();
}
targetLastEntered = retargetMouseEnterExit(targetOver, e,
targetLastEntered,
Component tle = retargetMouseEnterExit(targetOver, e,
targetLastEntered.get(),
isMouseInNativeContainer);
targetLastEntered = new WeakReference<>(tle);
}
private Component retargetMouseEnterExit(Component targetOver, MouseEvent e,
......@@ -4926,22 +4918,17 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener {
* is null, there are currently no events being forwarded to
* a subcomponent.
*/
private transient Component mouseEventTarget;
private transient WeakReference<Component> mouseEventTarget;
/**
* The last component entered by the {@code MouseEvent}.
*/
private transient Component targetLastEntered;
private transient WeakReference<Component> targetLastEntered;
/**
* The last component entered by the {@code SunDropTargetEvent}.
*/
private transient Component targetLastEnteredDT;
/**
* Indicates whether {@code mouseEventTarget} was removed and nulled
*/
private transient boolean isCleaned;
private transient WeakReference<Component> targetLastEnteredDT;
/**
* Is the mouse over the native container.
......@@ -4982,17 +4969,4 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener {
AWTEvent.MOUSE_EVENT_MASK |
AWTEvent.MOUSE_MOTION_EVENT_MASK |
AWTEvent.MOUSE_WHEEL_EVENT_MASK;
void removeReferences(Component removedComponent) {
if (mouseEventTarget == removedComponent) {
isCleaned = true;
mouseEventTarget = null;
}
if (targetLastEntered == removedComponent) {
targetLastEntered = null;
}
if (targetLastEnteredDT == removedComponent) {
targetLastEnteredDT = null;
}
}
}
/*
* Copyright (c) 2015, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8061636
* @summary fix for 7079254 changes behavior of MouseListener, MouseMotionListener
* @library ../../regtesthelpers
* @build Util
* @author Alexander Zvegintsev
* @run main RemovedComponentMouseListener
*/
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
import test.java.awt.regtesthelpers.Util;
public class RemovedComponentMouseListener extends JFrame {
static boolean mouseReleasedReceived;
static JButton button;
public RemovedComponentMouseListener() {
JPanel panel = new JPanel();
JPanel buttonPanel = new JPanel();
button = new JButton("Button");
setSize(300, 300);
buttonPanel.add(button);
panel.add(buttonPanel);
setContentPane(panel);
button.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
buttonPanel.remove(button);
panel.add(button);
button.revalidate();
button.repaint();
}
@Override
public void mouseReleased(MouseEvent e) {
mouseReleasedReceived = true;
}
});
setVisible(true);
}
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(() -> {
new RemovedComponentMouseListener();
});
Robot r = Util.createRobot();
r.setAutoDelay(100);
r.waitForIdle();
Util.pointOnComp(button, r);
r.waitForIdle();
r.mousePress(InputEvent.BUTTON1_MASK);
r.waitForIdle();
r.mouseRelease(InputEvent.BUTTON1_MASK);
r.waitForIdle();
if (!mouseReleasedReceived) {
throw new RuntimeException("mouseReleased event was not received");
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册