【问题标题】:Java mouseExited event is firing when frame.setLocation() is called调用 frame.setLocation() 时触发 Java mouseExited 事件
【发布时间】:2014-01-31 00:36:49
【问题描述】:

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

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

  1. 将鼠标移入窗口并触发 mouseEntered 事件
  2. 单击鼠标并触发 mousePressed 事件。
  3. 拖动鼠标并触发 mouseDragged 事件,并调用 setLocation。
  4. mouseExited 事件被触发,即使鼠标仍在窗口中!
  5. 此时将鼠标移出窗口不会触发 mouseExited。
  6. 将鼠标移出和移入将重置回第 1 步。

除了手动测试鼠标在屏幕上的位置之外,我该如何解决这个问题?

编辑:这是代码的精简版

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

【问题讨论】:

  • 如需尽快获得更好的帮助,请发布MCVE 以显示问题。
  • @AndrewThompson 完成。
  • Error: Main method not found in class DragNDropper, please define the main method as: public static void main(String[] args).. 一个 MCVE 包括一个 main。
  • @SuperDisk :这不符合 MCVE 文档。提供的课程中的JFrame 在哪里?如何按原样运行?同样,此新编辑不符合 MCVE 文档。简单来说,应该能够简单地复制和粘贴并运行代码。在这种情况下,必须首先从一个类中删除 public 并删除多余的 import 语句才能使其运行。
  • @AndrewThompson 好的,我将它包含在一个主函数中。

标签: java swing jframe mouseevent mouseenter


【解决方案1】:

使用此代码一切正常。请停止使用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");
    }
}

【讨论】:

  • 耐人​​寻味;除了合并类和使用 EventQueue.invokeLater 之外,似乎没有太大区别。无论如何谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-25
  • 1970-01-01
  • 2018-03-17
  • 1970-01-01
  • 2020-03-04
  • 2011-03-21
  • 1970-01-01
相关资源
最近更新 更多