JDK-6806830 : Bogus MouseDragged events when using a FileDialog
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6u10
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2009-02-18
  • Updated: 2011-04-28
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_11"
Java(TM) SE Runtime Environment (build 1.6.0_11-b03)
Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
In an AWT application with a canvas and FileDialog when the FileDialog is positioned over the canvas and the user double-click on a file to open it a MOUSE_DRAGGED event is generated on the canvas.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Start application, select load from the File menu, position dialog so its over the white canvas. Double-click on a file which is over the canvas.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No MOUSE_DRAGGED/MOUSE_RELEASED events generated.
ACTUAL -
1233773918625	Load
1233773923843	C:\eclipse\workspace\wallpaper\simpleImages\/verticleLine.png
1233773923937	Load finished
1233773923843	java.awt.event.MouseEvent[MOUSE_ENTERED,(111,125),absolute(361,172),button=0,modifiers=Button1,extModifiers=Button1,clickCount=0] on canvas0
1233773923843	java.awt.event.MouseEvent[MOUSE_DRAGGED,(111,125),absolute(361,172),button=0,modifiers=Button1,extModifiers=Button1,clickCount=0] on canvas0
1233773923906	java.awt.event.MouseEvent[MOUSE_RELEASED,(111,125),absolute(361,172),button=1,modifiers=Button1,clickCount=0] on canvas0


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.Canvas;
import java.awt.Color;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

public class MouseDraggedBug extends Panel implements ActionListener, MouseMotionListener, MouseListener {
    private static final long serialVersionUID = 1L;
    Frame frame;
    
    public MouseDraggedBug(Frame frame) {
        this.frame = frame;
    }

    public static void main(String progargs[]) {
        Frame mainFrame = new Frame("Wallpaper patterns");
        int w=800,h=600;
        mainFrame.setBounds(0, 0, w, h);
        MouseDraggedBug app = new MouseDraggedBug(mainFrame);
        mainFrame.add(app);
        mainFrame.setMenuBar(app.buildMenu());
        app.init();
        mainFrame.setVisible(true);
    }

    public MenuBar buildMenu() {
        MenuBar mb = new MenuBar();

        Menu fileMenu = new Menu("File");

        MenuItem loadMI = new MenuItem("Load");
        loadMI.addActionListener(this);
        fileMenu.add(loadMI);
        mb.add(fileMenu);
        return mb;
    }

    
    public void init() {
         this.setBackground(Color.DARK_GRAY);
         Canvas c = new Canvas();
         c.setSize(300, 300);
         c.setBackground(Color.WHITE);
         c.addMouseMotionListener(this);
         c.addMouseListener(this);
         this.add(c);
         this.validate();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println(""+System.currentTimeMillis()+"\tLoad");
        FileDialog fd = new FileDialog(frame, "Load image",
                FileDialog.LOAD);
        fd.setVisible(true);
        String dir = fd.getDirectory();
        String filename = fd.getFile();
        System.out.println(""+System.currentTimeMillis()+"\t"+dir+"/"+filename);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        System.out.println(""+System.currentTimeMillis()+"\tLoad finished");
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        System.out.println(""+e.getWhen()+"\t"+e);
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        System.out.println(""+e.getWhen()+"\t"+e);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println(""+e.getWhen()+"\t"+e);
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        System.out.println(""+e.getWhen()+"\t"+e);
    }

    @Override
    public void mouseExited(MouseEvent e) {
        System.out.println(""+e.getWhen()+"\t"+e);
    }

    @Override
    public void mousePressed(MouseEvent e) {
        System.out.println(""+e.getWhen()+"\t"+e);
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        System.out.println(""+e.getWhen()+"\t"+e);
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Maintain a private boolean flag recording MousePressed/MouseReleased status.
Disregard MouseDragged events unless proceeded by a MousePressed.

Comments
EVALUATION On hiding the toplevel the underlaying component (a canvas in this case) takes the MouseReleased and consider it has some diff with previous mouseevent. That's because the origin of the coordinate system has changed to we consider it as a drag movement.
01-09-2010