Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8061636

Fix for JDK-7079254 changes behavior of MouseListener, MouseMotionListener

XMLWordPrintable

    • b52
    • x86_64
    • generic

        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 ----------

              azvegint Alexander Zvegintsev
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated:
                Resolved: