سؤال

I've got a JFrame with no decoration (no title bar, close button, etc) that I can drag around the screen using setLocation() and mouse position.

Unfortunately, the mouseExited event is called upon first move of the window...

  1. Move mouse into window and mouseEntered event is fired
  2. Click mouse and mousePressed event is fired.
  3. Drag mouse and mouseDragged event is fired, and setLocation is called.
  4. mouseExited event is fired, even though the mouse is still in the window!
  5. Moving mouse out of the window at this point will not fire mouseExited.
  6. Moving mouse out and back in will reset back to step 1.

How do I fix this problem, other than just manually testing mouse position on screen?

Edit: Here's a distilled version of the code

import java.awt.*;
import javax.swing.*;
import java.awt.Event;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JComponent;
import javax.swing.JFrame;

class DragNDropper implements MouseMotionListener, MouseListener
{
    private int x, y;
    private int dx, dy;

    private boolean clicked;

    private JFrame frame;

    public DragNDropper(JFrame frame)
    {
    dx = dy = 0;
    this.frame = frame;
    }

    public void mouseDragged(MouseEvent e)
    {
    x = e.getXOnScreen();
    y = e.getYOnScreen();

    frame.setLocation(x-dx, y-dy);
    }

    public void mouseMoved(MouseEvent e)
    {
    x = e.getXOnScreen();
    y = e.getYOnScreen();
    }

    public void mouseClicked(MouseEvent e)
    {

    }

    public void mousePressed(MouseEvent e)
    {
    clicked = true;
    dx = e.getX();
    dy = e.getY();
    }

    public void mouseReleased(MouseEvent e)
    {
    clicked = false;
    }

    public void mouseEntered(MouseEvent e)
    {
    System.out.println("Mouse entered");
    }


    public void mouseExited(MouseEvent e)
    {
    System.out.println("Mouse exited");
    }
}


public class Program
{
public static void main(String[] argv)
{
JFrame jf = new JFrame();
DragNDropper dnd = new DragNDropper(jf);

jf.setSize(new Dimension(512, 512));
jf.addMouseListener(dnd);
jf.addMouseMotionListener(dnd);

jf.show();
}
}
هل كانت مفيدة؟

المحلول

Everything is working fine, with this code. Please stop using frame.show(), from where you come to know of this being used to show the JFrame, use frame.setVisible(true) instead. Please explain a bit more about the problem. Please have a look at this modification of the code :

import java.awt.*;
import java.awt.Event;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.*;

public class DragNDropper implements MouseMotionListener, MouseListener {

    private int x, y;
    private int dx, dy; 
    private boolean clicked;    
    private JFrame jf;

    public static void main(String[] argv) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new DragNDropper().displayGUI();
            }
        });
    }

    private void displayGUI() {
        dx = dy = 0;
        jf = new JFrame();
        jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        jf.setUndecorated(true);

        jf.setSize(new Dimension(512, 512));
        jf.addMouseListener(this);
        jf.addMouseMotionListener(this);

        jf.setVisible(true);
    }

    public void mouseDragged(MouseEvent e) {
        x = e.getXOnScreen();
        y = e.getYOnScreen();
        jf.setLocation(x-dx, y-dy);
    }

    public void mouseMoved(MouseEvent e) {
        x = e.getXOnScreen();
        y = e.getYOnScreen();
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
        clicked = true;
        dx = e.getX();
        dy = e.getY();
    }

    public void mouseReleased(MouseEvent e) {
        clicked = false;
    }

    public void mouseEntered(MouseEvent e) {
        System.out.println("Mouse entered");
    }

    public void mouseExited(MouseEvent e) {
        System.out.println("Mouse exited");
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top