2014-01-12 20 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之外,似乎沒有太大區別。無論如何謝謝! –

相關問題