2012-03-21 32 views
2

我有一個不同的問題,第一個,所以我發了這個帖子: Java JPanel mouse listener doesn't work over its componentsJava的玻璃疼痛(這不是一個錯字)

的回答使我在一個Java玻璃面板到達。我看到了關於此的其他帖子,他們都指向這篇文章: http://weblogs.java.net/blog/alexfromsun/archive/2006/09/a_wellbehaved_g.html

我使用的物品(FinalGlassPane.java)的例子,準確地將它設置爲測試程序:

GlassPane glass = new GlassPane(this); 
getRootPane().setGlassPane(glass); 
GestureListener gl = new GestureListener(); 
glass.addMouseMotionListener(gl); 
glass.addMouseListener(gl); 
glass.setVisible(true); 
if (glass instanceof AWTEventListener) { 
    AWTEventListener al = (AWTEventListener) glass; 
    Toolkit.getDefaultToolkit().addAWTEventListener(al, 
      AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK); 
} 

但我仍然有同樣的問題,玻璃阻止我能點擊它下面的任何按鈕(JButton)。

如果您已經足夠閱讀我最初的SO問題,並認爲glassPane不適合我,請寄給我一個替代解決方案,否則請告訴我爲什麼這不起作用。

在此先感謝。

編輯:IT工作,但停止工作時添加自己的MouseListener

請注意,在我的代碼,我將我自己的GestureListener,我不能添加自己的MouseListener此實現 - 這是什麼使得它不行。我將這些線路關閉,現在玻璃窗格正常工作。

在代碼(FinalGlassPane.java)中有關於MouseListener的我不太瞭解的通知,所以我的新問題是如何將我自己的MouseListener添加到此玻璃窗格中?

/** 
* If someone adds a mouseListener to the GlassPane or set a new cursor 
* we expect that he knows what he is doing 
* and return the super.contains(x, y) 
* otherwise we return false to respect the cursors 
* for the underneath components 
*/ 
@Override 
public boolean contains(int x, int y) { 
    if (getMouseListeners().length == 0 && getMouseMotionListeners().length == 0 
      && getMouseWheelListeners().length == 0 
      && getCursor() == Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)) { 
     return false; 
    } 
    return super.contains(x, y); 
} 

附加信息:

如果我總是返回在contains(int, int)方法的按鈕總是工作假的,但我對玻璃面板的MouseListener沒有。如果我總是返回「super.contains(x,y)」,則會發生相反情況:GlassPane上的MouseListener可以正常工作,但我無法單擊下面的任何組件。

最後編輯 所以,我得出的結論,我不能(或沒有),有一種方法(與Java 6)讓我的應用程序有2層,可接收的MouseListener事件(的mousePressed, mouseReleased)在同一時間。最後,我在原始問題上使用瞭解決方案,即創建一個自定義JButton,並將MouseListener添加到每個實例。

+0

能你放棄玻璃(痛苦)的想法添加一個主監聽器到所有的按鈕?你的應用程序會遇到這種情況嗎? – Java42 2012-03-22 00:31:26

+0

實際上,在我的應用程序中,因爲按鈕(按鈕的網格)是從XML文件生成的,或者有時是從用戶對象生成的。將監聽器添加到每個按鈕都是一個很大的麻煩,而且我甚至不確定我的監聽器能否正常工作。 – Ozzy 2012-03-22 00:35:05

+0

@ChuckFricano有什麼建議嗎? – Ozzy 2012-03-22 00:49:52

回答

2

不清楚從你的這兩個問題,如果你真的需要convertXxx或GetXXX方法從SwingUtilities

1)你可以把JLabel(調度鼠標事件)的GlassPane,這JLabel可以放在/覆蓋整個可用RectangleJFrame,或者只需要Bounds

2)你可以把JLabel(調度鼠標事件)的JViewport,這JLabel可以放在/覆蓋整個可用Rectangle來回米JScrollPane/JViewport,或者只需要Bounds

3)你可以使用JLayeredPane(最多6層)

4)可以使用JLayer基於JXLayer(Java7)(爲的Java6,也許更好的選擇)

+0

因此,我可以只使用JLayeredPane而不是JPanel作爲我的GlassPane,並且可以完成這項工作? @mKorbel – Ozzy 2012-03-22 01:35:51

+0

我不知道你真的需要什麼,真正你的工作是什麼:-),請不要攻擊你的人--->我讀了很多廣泛的問題,沒有基於[SSCCE](http ://sscce.org/),其中reall的答案離問題太遠,我的另一個問題是,你想要e#consume()鼠標事件(GlassPane不能防範KeyEvent),或者你可以re_distribute event,或者? ?? – mKorbel 2012-03-22 01:47:23

+0

我試圖做一些觸摸屏PC系統,但像android/iphone,所以它具有手勢功能。我做了我的GestureListener(你可以在我的答案中看到它:http://stackoverflow.com/questions/6000408/java-swing-element-transitions/9811602#9811602)所以我想要一個方法來做一個手勢 - 層放在我的應用程序框架之上,但允許我像往常一樣使用所有的JButton和其他組件。無論什麼方式都是最好的,我不知道,我仍然是一個新手。感謝您的幫助順便說一句。我認爲我已經在重新分配事件(使用來自太陽隊的亞歷克斯) – Ozzy 2012-03-22 01:54:13

0

請參閱Java教程中的「如何使用根窗格」,搜索單詞'redispatches'(關於下一頁),這裏有一個類似於您試圖用複選框實現的示例:

http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html

總之你需要使用SwingUtilities.getDeepestComponentAt(..)Component.dispatchEvent(..)在翻譯的鼠標光標的位置。

+0

感謝您的回答。該方法的問題是組件需要傳遞到玻璃窗格中(通過構造函數) - 我無法做到這一點。更糟糕的是,玻璃窗格會爲該組件添加一個特殊的偵聽器。如果我想添加單個聽衆,我會在沒有玻璃窗的情況下完成它。 @ChrisWhite – Ozzy 2012-03-22 00:48:17

+0

好的,這篇文章並沒有完全解決你的問題,但它是我在pastebin上爲你擴展的基礎:http://pastebin.com/YWHFX1qi – 2012-03-22 10:44:21

+0

哦,那真是太好了, 謝謝。實際上,添加一個MouseMotionListener對於玻璃板不是問題;問題是當我添加我自己的MouseListener來獲取mousePressed和mouseReleased事件。如果你看到我添加到這個問題中的'附加信息',那麼它包含(x,y)方法。我可以將它設置爲聽下面的組件,或者我可以將它設置爲通過更改返回值來收聽glassPane。這就是爲什麼我最終決定在我的原始問題中回答 - 一個自定義的JButton,它將Listener自動添加到每個實例。 – Ozzy 2012-03-22 15:15:01