2013-06-28 23 views
2

我一直在嘗試實現鼠標移動事件調度,但我繼續得到一個堆棧溢出錯誤。它適用於mouseMoved(MouseEvent e)方法,但不適用於mouseDragged(MouseEvent e)。有人知道爲什麼嗎?有沒有解決方案?嘗試分派MouseEvents時出現Stackoverflow錯誤。 mouseMoved的作品,但mouseDragged不

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class Test extends JFrame { 

public Test() { 
    setLayout(null); 
    setSize(500,500); 
    setVisible(true); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    addMouseMotionListener(new MouseMotionListener() { 
     public void mouseMoved(MouseEvent e) { 
      System.err.println("moved outside"); 
     } 
     public void mouseDragged(MouseEvent e) { 
      System.err.println("dragged outside"); 
     } 
    }); 

    JPanel inside = new JPanel(); 
    inside.setLocation(0, 0); 
    inside.setSize(100, 100); 
    inside.setBackground(Color.RED); 

    inside.addMouseMotionListener(new MouseMotionListener() { 
     public void mouseDragged(MouseEvent e) { 
      System.out.println("dragged inside"); 

      //The error occurs here when I begin dragging 
      //here and continue dragging to any other location. 

      Test.this.dispatchEvent(e); 
     } 
     public void mouseMoved(MouseEvent e) { 
      System.out.println("moved inside"); 
      Test.this.dispatchEvent(e); 
     } 
    }); 
    add(inside); 
} 

public static void main(String[] args) { 
    Test client = new Test(); 
} 
} 

我的實際項目使用了許多內部元件和我的目標是讓每個部件實現自己的按下鼠標/點擊/釋放動作,並具有框架手柄鼠標移動和拖動影響所有的組件。

這是一個類似的代碼,可以同時適用於鼠標移動方法。

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class Test2 { 

public static void main(String... args) { 
    SwingUtilities.invokeLater(new Runnable() { 

     public void run() { 
      final JComponent outside = new JPanel(); 
      JComponent inside = new JPanel(); 
      inside.setBackground(Color.red); 
      inside.setPreferredSize(new Dimension(200, 200)); 
      inside.addMouseMotionListener(new MouseAdapter() { 
       public void mouseDragged(MouseEvent e) { 
        System.out.println("dragged inside"); 
        outside.dispatchEvent(e); 
       } 
       public void mouseMoved(MouseEvent e) { 
        System.out.println("moved inside"); 
        outside.dispatchEvent(e); 
       } 
      }); 

      outside.add(inside); 
      outside.setPreferredSize(new Dimension(300, 300)); 
      outside.addMouseMotionListener(new MouseAdapter() { 
       public void mouseMoved(MouseEvent e) { 
        System.err.println("moved outside"); 
       } 
       public void mouseDragged(MouseEvent e) { 
        System.err.println("dragged outside"); 
       } 
      }); 

      JFrame frame = new JFrame(); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.add(outside); 
      frame.pack(); 
      frame.setVisible(true); 
     } 
    }); 
} 
} 

幫助表示讚賞。

回答

1

您的MouseMotionListenerinside正在生成新事件。這個事件會被同樣的MouseMotionListener再次捕獲,造成無限循環。由於您在創建事件時仍然未完成上一個事件,因此它們會堆疊起來,直到StackOverflowError爆炸您的應用程序。

你的第二個代碼沒有這個問題,因爲inside代表outside,它在那裏結束。

+0

在第一個代碼中,爲什麼調用的是同一個MouseMotionListener?在Test.this.dispatchevent(e)中使用Test.this;問題?我很困惑,爲什麼它與mouseMoved一起使用。我注意到,在使用mouseMoved時,與第二個代碼相比,「移入內部」比「移出外部」彈出更多。 – Klungo

+0

第一個代碼中有兩個'MouseMotionListener'。鼠標移動到「內部」面板上。由於鼠標在面板和窗口上移動,兩個聽衆都會觸發。 「內部」偵聽器創建一個新事件並將其發佈到Swing,Swing將它傳遞給兩個偵聽器。 「內部」偵聽器創建一個新事件並將其發佈到Swing,Swing將它傳遞給兩個偵聽器。 「內部」偵聽器創建一個新事件並將其發佈到Swing,Swing將它傳遞給兩個偵聽器。 'inside'監聽器創建一個新事件並將其發佈到Swing,它將它傳遞給兩個監聽器...... BOOM! –

+0

現在,這是質量! – Klungo

相關問題