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