2014-01-12 3 views
1

У меня есть JFrame без украшений (без заголовка, кнопки закрытия и т. Д.), Которые можно перетаскивать по экрану с помощью setLocation() и положения мыши.Java mouseExited событие запускается, когда frame.setLocation() называется

К сожалению, событие mouseExited вызывается при первом движении окна ...

  1. Перемещение мыши в окно и mouseEntered событие обжигают
  2. Нажмите кнопку мыши и mousePressed событие.
  3. Перетаскивание мышью и мышью. Опущено событие, и вызывается setLocation.
  4. событие mouseExited уволено, хотя мышка все еще находится в окне!
  5. Перемещение мыши из окна в этом месте не будет срабатывать mouseExited.
  6. Перемещение мыши туда и обратно в сбросит обратно к шагу 1.

Как исправить эту проблему, кроме как раз вручную тестирования положение мыши на экране?

Edit: Вот дистиллированная версия кода

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 включает в себя основной. –

ответ

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. Спасибо, в любом случае! –