JDK-8061636 : Fix for JDK-7079254 changes behavior of MouseListener, MouseMotionListener
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 8,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: x86_64
  • Submitted: 2014-10-21
  • Updated: 2015-10-28
  • Resolved: 2015-01-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u60Fixed 9 b52Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
CentOS 6.5 64-bit
Windows 7 64-bit

A DESCRIPTION OF THE PROBLEM :
I have a program that removes a swing component from a panel during a mouse drag event, and reattaches that component to a higher-layer in a JLayeredPane.  

In Java 7 and earlier, MouseListeners and MouseMotionListeners attached to the component continue receiving mouse events after the component is removed and reattached.  This allows the component to be dragged on the screen.

In Java 8, MouseListeners and MouseMotionListeners attached to the component do not receiving mouse events after the component is removed and reattached, so dragging is broken.

I have done some experiments with my own build of openjdk8.  If I remove the contents of java.awt.Container.removeReferences, my problem is fixed.  So I believe this bug is introducted by the fix for JDK-7079254, specifically this commit: http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/7a8a8e31a126

Unfortunately Container.removeReferences and Container.clearLightweightDispatcherOnRemove are package-private so there is no easy way to work around this.

REGRESSION.  Last worked in version 7u72

ADDITIONAL REGRESSION INFORMATION: 
java version "1.7.0_72"
Java(TM) SE Runtime Environment (build 1.7.0_72-b14)
Java HotSpot(TM) 64-Bit Server VM (build 24.72-b04, mixed mode)


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile test program
2. Run test program
3. Click on "Test" button and drag it. 

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
 In java 7 the button moves when dragged.
ACTUAL -
 In java 8 the button does not move when dragged.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;

public class Java8Test extends JFrame {

        private static final long serialVersionUID = 1L;

        private final JLayeredPane desktopPane;

        private boolean dragging = false;

        private Point lastDragPointOnScreen = null;

        public Java8Test() {
                setSize(600, 600);
                setVisible(true);
                desktopPane = new JLayeredPane();
                setContentPane(desktopPane);
                final JPanel buttonParentPanel = new JPanel();
                buttonParentPanel.setBorder(new LineBorder(Color.BLACK, 2));
                final JButton button = new JButton("Test");
                buttonParentPanel.add(button);
                desktopPane.add(buttonParentPanel, JLayeredPane.DEFAULT_LAYER + 1);
                buttonParentPanel.setBounds(20, 20, 100, 100);
                button.addMouseListener(new MouseAdapter() {
                        @Override
                        public void mousePressed(MouseEvent e) {
                                System.out.println("mousePressed");
                        }

                        @Override
                        public void mouseReleased(MouseEvent e) {
                                System.out.println("mouseReleased");
                                if (dragging) {
                                        buttonParentPanel.add(button);
                                        buttonParentPanel.revalidate();
                                        buttonParentPanel.repaint();
                                        dragging = false;
                                        lastDragPointOnScreen = null;
                                        desktopPane.revalidate();
                                        desktopPane.repaint();
                                }
                        }
                });
                button.addMouseMotionListener(new MouseMotionAdapter() {
                        @Override
                        public void mouseDragged(MouseEvent e) {
                                System.out.println("mouseDragged");
                                try {
                                        if (!dragging) {
                                                final Point pointInDesktopPane = SwingUtilities.convertPoint(
                                                                buttonParentPanel, button.getLocation(), desktopPane);
                                                buttonParentPanel.remove(button);
                                                desktopPane.add(button, Integer.valueOf(JLayeredPane.DEFAULT_LAYER + 2));
                                                button.setLocation(pointInDesktopPane);
                                                lastDragPointOnScreen = e.getLocationOnScreen();
                                                button.revalidate();
                                                button.repaint();
                                                dragging = true;
                                        } else {
                                                final int deltaX = e.getLocationOnScreen().x - lastDragPointOnScreen.x;
                                                final int deltaY = e.getLocationOnScreen().y - lastDragPointOnScreen.y;
                                                button.setLocation(button.getX() + deltaX, button.getY() + deltaY);
                                                lastDragPointOnScreen = e.getLocationOnScreen();
                                        }
                                } catch (final Throwable t) {
                                        t.printStackTrace();
                                }
                        }
                });
                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }

        public static void main(String[] args) {
                SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                                new Java8Test();
                        }
                });
        }

}

---------- END SOURCE ----------


Comments
Added label: escape-old, since this bug affects 8.
03-04-2015

Please evaluate and investigate to fix in 8u also
28-10-2014

Pending Dev consideration. Possible regression.
21-10-2014