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

MouseEventTarget is removed after control is removed from its parent

XMLWordPrintable

    • x86_64
    • windows_7

      FULL PRODUCT VERSION :
      java version "1.8.0_05"
      Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
      Java HotSpot(TM) Client VM (build 25.5-b02, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      In jdk 8, the MouseEventTarget of the component is set to null after the component is removed from its parent.
      As a result, if a control is moved from Component A to Component B within the control's MousePressed event handler, the control's MouseReleased event will not appear.


      Looking at the JLayeredPane, this problem is avoided by JLayeredPane calling "removeDelicately()" which avoid calling "removeNotify()" and other related methods. If "removeDelicately()" is accessible from outside jdk, this problem is solved.

      REGRESSION. Last worked in version 7u60

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Create 3 JComponents: A ,B and C
      2. Add C to A
      3. Add mousePressed event handler to C to change its parent from A to B and print out "mouse pressed"
      4. Add mouseReleased event handler to C to print out "mouse released"
      5. run the program with jdk8
      6. click on C

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      both "mouse pressed" and "mouse released" are printed out in console
      ACTUAL -
      only "mouse pressed" is printed out

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.awt.BorderLayout;
      import javax.swing.JComponent;
      import javax.swing.JFrame;


      public class Program {

      static JComponent parent1;
      static JComponent parent2;
      public static void main(String[] args) {
              //Create and set up the window.
              JFrame frame = new JFrame("IconDisplayer");
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

              //Create and set up the content pane.
              Panel panel = new Panel();
              Panel p1 = new Panel();
              p1.setSize(200, 200);
              panel.add(p1);
              p1.setLocation(20, 20);
              Panel p2 = new Panel();
              p2.setSize(200, 200);
              panel.add(p2);
              p2.setLocation(120, 120);
              frame.getContentPane().add(panel);
              
              Button jb = new Button();
              jb.setLocation(100, 100);
              p1.add(jb, BorderLayout.CENTER);


              //Display the window.
              frame.setVisible(true);
              
              parent1 = p1;
              parent2 = p2;
      }


      public static void changeParent(JComponent compo)
      {
      if (compo.getParent() == parent1)
      {
      parent2.add(compo);
      parent1.remove(compo);
      }
      else if (compo.getParent() == parent2)
      {

      parent1.add(compo, BorderLayout.CENTER);
      parent2.remove(compo);
      }
      compo.setLocation(100, 100);
      parent1.revalidate();
      parent2.revalidate();
      parent1.repaint();
      parent2.repaint();
      }

      }




      import java.awt.Color;
      import java.awt.event.MouseEvent;
      import java.awt.event.MouseListener;

      import javax.swing.BorderFactory;
      import javax.swing.JComponent;


      public class Button extends JComponent implements MouseListener {

      public Button()
      {
      setForeground(Color.RED);
      setSize(40, 20);
      setBorder(BorderFactory.createLineBorder(Color.BLUE, 3, true));
      addMouseListener(this);
      }
      @Override
      public void mouseClicked(MouseEvent e) {
      // TODO Auto-generated method stub

      }

      @Override
      public void mousePressed(MouseEvent e) {

      Program.changeParent(this);
      System.out.println("pressed");
      }

      @Override
      public void mouseReleased(MouseEvent e) {
      // TODO Auto-generated method stub
      System.out.println("released");
      }

      @Override
      public void mouseEntered(MouseEvent e) {
      // TODO Auto-generated method stub

      }

      @Override
      public void mouseExited(MouseEvent e) {
      // TODO Auto-generated method stub

      }

      }





      import java.awt.Color;
      import java.awt.Graphics;
      import java.awt.event.MouseEvent;
      import java.awt.event.MouseListener;

      import javax.swing.BorderFactory;
      import javax.swing.JComponent;
      import javax.swing.JPanel;


      public class Panel extends JComponent implements MouseListener {


      public Panel()
      {
      setForeground(Color.BLACK);
      setBorder(BorderFactory.createTitledBorder("window"));
      }

      @Override
      protected void paintComponent(Graphics g) {
      // TODO Auto-generated method stub
      super.paintComponent(g);
      }

      @Override
      public void mouseClicked(MouseEvent e) {
      // TODO Auto-generated method stub

      }

      @Override
      public void mousePressed(MouseEvent e) {
      // TODO Auto-generated method stub

      }

      @Override
      public void mouseReleased(MouseEvent e) {
      // TODO Auto-generated method stub

      }

      @Override
      public void mouseEntered(MouseEvent e) {
      // TODO Auto-generated method stub

      }

      @Override
      public void mouseExited(MouseEvent e) {
      // TODO Auto-generated method stub

      }

      }



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

      SUPPORT :
      YES

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

              Created:
              Updated:
              Resolved: