2009-12-11 51 views
3

我正在尋找一種方法將鼠標事件傳遞給其他組件所覆蓋的組件。爲了說明我的意思,下面是一個示例代碼。它包含兩個JLabel s,其中一個小兩倍,並且完全覆蓋一個更大的標籤。如果將鼠標懸停在標籤上,只有較大的一個觸發mouseEntered事件。在底層組件上觸發鼠標事件

import java.awt.Color; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.WindowConstants; 
import javax.swing.border.LineBorder; 

public class MouseEvtTest extends JFrame { 

    public MouseEvtTest() { 
     setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     setLayout(null); 
     setSize(250, 250); 

     MouseAdapter listener = new MouseAdapter() { 
      @Override 
      public void mouseEntered(MouseEvent e) { 
       System.out.printf("Mouse entered %s label%n", e.getComponent().getName()); 
      } 
     }; 
     LineBorder border = new LineBorder(Color.BLACK); 

     JLabel smallLabel = new JLabel(); 
     smallLabel.setName("small"); 
     smallLabel.setSize(100, 100); 
     smallLabel.setBorder(border); 
     smallLabel.addMouseListener(listener); 
     add(smallLabel); 

     JLabel bigLabel = new JLabel(); 
     bigLabel.setName("big"); 
     bigLabel.setBorder(border); 
     bigLabel.setSize(200, 200); 
     bigLabel.addMouseListener(listener); 
     add(bigLabel, 0); //Add to the front 
    } 

    public static void main(String[] args) { 
     new MouseEvtTest().setVisible(true); 
    } 
} 

當光標移動到它上面的座標時,在較小的標籤上觸發鼠標輸入事件的最佳方法是什麼?如果多個組件堆疊在一起,它將如何工作?剩下的鼠標事件如mouseClicked,mousePressed,mouseReleased等?

+0

我很抱歉,但我必須要問亞歷山大Potochkin的博客文章 - 爲什麼你要這麼做?這似乎不是一個非常直觀的事情,通常意味着維護問題。 – Nemi 2009-12-11 18:42:35

+0

這只是一個示例代碼。真正的交易在其他組件的集合上具有隱形面板。頂部的面板根據不同的條件執行各種任務。例如,如果移位被保持,那麼您可以抓取並移動具有下面組件的整個組件。由於解釋現實生活場景的所有細節是困難的(也是無關緊要的),我認爲這很好地說明了這個問題。另外,這可能不是最好的方法,但我沒有可能重寫組件(主要是因爲時間)。 – 2009-12-14 11:06:54

回答

2
+0

謝謝,這幫助我解決了遊標問題,我使用JLayeredPane驗證覆蓋層! – Nemi 2009-12-11 18:54:58

+0

該文章提出了非常好的解決方案。 – 2012-01-23 12:52:33

2

在你的聽衆:

bigLabel.dispatchEvent(mouseEvent); 

當然,你必須定義bigLabelfinal

+0

謝謝!迄今爲止更好的答案! – Bitterblue 2013-04-15 10:18:17

0

好明白髮生了什麼,你需要了解如何Z排序作品。作爲快速概述,最後添加的組件是首先繪製的。所以在你的情況下,你想在大組件之前添加小組件。

// add(bigLabel, 0); //Add to the front 
add(bigLabel); // add to the end so it is painted first 

OverlayLayout可能有助於解釋這更好的,給你另一種選擇。

+0

這樣做的代碼示例可能看起來很愚蠢,但它非常接近地複製了我的真實場景。我特意將大標籤添加到頂部,以便完全覆蓋小標籤。 – 2009-12-14 09:37:42

+0

然後你將負責編寫你自己的命中檢測代碼,這意味着當你在大標籤上收到一個鼠標事件時,你需要遍歷面板中的所有其他組件,並使用contains(...)方法查看鼠標點是否在組件的邊界內。如果是這樣,那麼您需要創建一個新的MouseEvent並將其分派到該組件,如上所述。 – camickr 2009-12-14 15:50:01