2014-01-12 14 views
1

我有一个没有装饰(没有标题栏,关闭按钮等)的JFrame,我可以使用setLocation()和鼠标位置在屏幕上拖动。Java的mouseExited事件触发frame.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(); 
} 
} 
+1

为了更好的帮助,请发布[MCVE](http://stackoverflow.com/help/mcve)来显示问题。 –

+0

@AndrewThompson完成。 –

+0

错误:在类DragNDropper中找不到主要方法,请定义主要方法为: public static void main(String [] args)'..一个MCVE包含一个main。 –

回答

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

有趣;除了合并类和使用EventQueue.invokeLater之外,似乎没有太大区别。无论如何谢谢! –

相关问题