JDK-4420110 : Creating a new component under cursor does not fire mouseEntered()
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.3.0
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2001-02-28
  • Updated: 2010-12-30
Related Reports
Relates :  
Relates :  
Description
Name: ssT124754			Date: 02/28/2001



java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

Creating a GUI component under the cursor does not fire the mouseEntered()
trigger on the MouseListeners of this new component directly. The trigger
does fire however, when the mouse is moved. I would understand if the
trigger does not fire at all, but too late is unacceptable.
Below is an example illustrating this problem: click on the label to
produce a new instance of the label. I tried to find this bug in the Sun bug
database, and the nearest hit I could find is bug report 4027025 (Creating a
new component under cursor causes me to lose mouse motion events) with
status "Closed, not reproducable"
The code contains a bonus bug: uncommenting the comment and the text will be
displayed over previous text.

Greetings,

Mark Scheffer.

/* TestMouseMove 1.0 2001/02/21 */

import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;

public class TestMouseMove extends MouseInputAdapter {

    public static void main(java.lang.String[] args) {
	new TestMouseMove();
    }

    JFrame f;
    JPanel p = new JPanel();
    JLabel label;

    public TestMouseMove() {

        f = new JFrame();
        f.setContentPane(p);
        newButton();
        f.pack();
	f.setVisible(true);
    }

    public void newButton() {
        label = new JLabel("Not on label");
        label.addMouseListener(this);
        label.addMouseMotionListener(this);
        p.removeAll();
        p.add(label);
        p.revalidate();
	//f.setContentPane(label);
    }

    public void mousePressed(MouseEvent e) {
        label.setText("New label...");
    }

    public void mouseReleased(MouseEvent e) {
        newButton();
    }

    public void mouseEntered(MouseEvent e) {
        System.out.println("ENTER");
        label.setText("On label");
    }
 
    public void mouseExited(MouseEvent e) {
        System.out.println("EXIT");
        label.setText("Not on label");
    }
    
    public void mouseDragged(MouseEvent e) { }
    public void mouseMoved(MouseEvent e) { }
}
/* end */
(Review ID: 117431) 
======================================================================

Comments
EVALUATION Contribution forum : https://jdk-collaboration.dev.java.net/servlets/ProjectForumMessageView?forumID=1463&messageID=13389
08-06-2006

EVALUATION It's possible to track the event that the component is newly appeared under the mouse using circumstantial evidences via analyzing COMPONENT_RESIZED/COMPONENT_MOVED event in shared code (not sure that it's a good idea, but another way is to go into sun/awt/ pachage for that event). Another point is the location of new component: it's impossible to keep actual component position using getLocationOnScreen as it's only appliable on visible components but calling it from inside Container.dispatchEvent will lead to exception. Abtaining mouse locations is trivial but there is an extra algorithm is needed for component location via ascendant containers.
19-08-2005

EVALUATION Actually the problem affect all platforms but not Win32 only. Cause of the problem seems in how new Component(JLabel) appears on the screen. 1) when we remove an old-label and then create a new-label on the same place we may observe that nothing happens with old-label listener despite all this occur over it. 2) when move mouse over new-label we obtain MouseEntered event. a)We may try to rely on HierarchyEvent.SHOWING_CHANGED event on each Comp.show() call but seem it's not applicable for lightweight components. b) Component.processEvent() which already has switch for HierarchyEvent doesn't work in lightweight case too. Looking into shared part of awt can't say for sure that it's obvious how to trigger ENTERED event syntetically there.
18-08-2005

EVALUATION As there is a lightweight component used in the test then we may not expect any kind of native event to come. Component.show() might be modified to check if HIERARCHY_EVENT occured at the correct time, i.e. when there is a mouse pointer under the new Component.
17-08-2005

EVALUATION MouseEvents report changes in the state of the mouse, not to changes in the Component hierarchy. Thus, MOUSE_ENTERED events are only generated when the mouse is moved or dragged over a new Component. Just as you would not expect to receive MOUSE_MOVED events if a Component is moved under the mouse, or MOUSE_DRAGGED events if a Component is moved while a mouse button is pressed, MOUSE_ENTERED events are not generated when a Component is added under the mouse. This has always been the behavior of the JDK. If it is very important to know if the mouse cursor is at the location where a new Component will be added, a MouseMotionListener can be added to the Component's parent to keep track of the mouse cursor's location. If the cursor falls within the bounds of the Component when it is shown, the appropriate code (presumably that same as for a MOUSE_ENTERED) can be executed. ###@###.### 2001-12-10 It seems to be the default behavior on Linux for heavyweights, but not for lightweights and not on other platforms. It seems to be reasonable behavior, a customer needs it, the bug has 3 votes and Swing requires it. Let's implement generation of MOUSE_ENTERED when component is shown. ###@###.### 2005-04-08 16:35:21 GMT I could see extra MouseMoved event after showing new Component under mouse cursor on Windows2000. This happens on JDK started from 1.3 but I haven't checked earlier. It also looks like a some kind of old bug-fix so far. Moreover, pure-AWT(see comments) test shows different result against Swing-based one. (working with current Mustang) ------------------------------------------- Win32: awt : MouseEntered event comes to listener on time but synthetic MouseMoved event have been generating. There is no MouseEntered event comes to listener. Swing: MouseEntered event comes to listener not after adding a component but after mouse movement. There is no MouseEntered event comes to listener (not a real problem?). Linux XAWT: awt : MouseEntered event occur always once Component newly appear and MouseExited event occur after components' elimination. So this bug is not reproducible on Linux XAWT. Swing: completely same as on Win32. Linux Motif: awt : exactly the same as Linux XAWT. Swing: the same as Linux XAWT. ------------------------------------------------- Hence we should affect Win32 in order to force MouseEntered event for lightweight components and supress consequent MouseEntered that occur normally after first mouse motion. ###@###.### 2005-06-16 15:18:55 GMT
16-06-2005

WORK AROUND Add a MouseMotionListener to the Component's parent to track the mouse cursor's location. You can then determine if the mouse cursor is within the bounds of your Component when it is shown. ###@###.### 2001-12-10
10-12-2001