调用frame.setLocation()时会触发Java mouseExited事件

时间:2014-01-12 04:43:15

标签: java swing jframe mouseevent mouseenter

我有一个没有装饰的JFrame(没有标题栏,关闭按钮等),我可以使用setLocation()和鼠标位置在屏幕上拖动。

不幸的是,在第一次移动窗口时调用mouseExited事件......

  1. 将鼠标移动到窗口并触发mouseEntered事件
  2. 点击鼠标并触发mousePressed事件。
  3. 拖动鼠标和mouseDragged事件,并调用setLocation。
  4. 即使鼠标仍在窗口中,也会触发mouseExited事件!
  5. 此时将鼠标移出窗口不会触发mouseExited。
  6. 将鼠标移出并重新进入将重置回第1步。
  7. 除了在屏幕上手动测试鼠标位置外,我该如何解决这个问题?

    编辑:这是代码的提炼版本

    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();
    }
    }
    

1 个答案:

答案 0 :(得分:2)

使用此代码,一切正常。请停止使用frame.show(),您可以从中了解用于显示JFrame的信息,然后使用frame.setVisible(true)。请解释一下这个问题。请看一下这段代码的修改:

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");
    }
}