2013-08-16 61 views
3

我的問題類似於this,但我認爲有一個更簡單的例子。設置JFrame背景透明製作PopupMenu爲空

基本上通過調用AWTUtilities.setWindowOpaque(window, false)來使JFrame的背景透明,我的JPopupMenu有時顯示爲空白。

public class JavaApplication8 { 

    JPopupMenu popup; 
    JMenuItem open; 
    JLabel bgLabel = new JLabel("testing"); 

    public static void main(String[] args) { 
     // TODO code application logic here 

     JFrame window = new JFrame("test"); 

     URL bgURL = JavaApplication8.class.getResource("images/bg.jpg"); 
     ImageIcon bg = new ImageIcon(bgURL); 

     JavaApplication8 test = new JavaApplication8(); 
     test.setPopupMenu(); 
     test.bgLabel.setIcon(bg); 

     window.add(test.bgLabel, BorderLayout.CENTER); 

     window.setUndecorated(true); 
     AWTUtilities.setWindowOpaque(window, false);   
     //window.pack(); 
     window.setSize(200, 200); 
     window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     window.setLocationRelativeTo(null); 
     window.setVisible(true); 

    } 

    public void setPopupMenu(){ 
     popup = new JPopupMenu(); 
     open = new JMenuItem("Test"); 

     popup.add(open); 
     this.bgLabel.setComponentPopupMenu(popup);  
    } 

} 

這裏是發生了什麼事的形象:

enter image description hereenter image description here

有趣的是,出現這種情況時,我點擊JFrame的右側。不知道爲什麼。請記住,我並不是100%確定AWTUtilities.setWindowOpaque(window, false)確實是這個問題的原因,但是無論何時我刪除該行時,一切似乎都很順利。

編輯:正如camickr指出,looks like this happens when the popup menu is not fully contained in the bounds of the parent window.

+0

奇怪...的Java 6和Windows 7操作系統,沒有任何問題,Java 7的和Windows 7,沒有問題... – MadProgrammer

+0

@MadProgrammer:真的嗎?我在Java 7和Windows 7上,嗯。 – kir

+0

默認情況下JPopupMenus在完全包含在窗口內時是輕量級的。問題出現在彈出窗口的任何部分必須出現在窗口之外 - 然後爲彈出窗口創建一個新的重窗口。這個問題只在那個沉重的窗口中出現。 – Lunchbox

回答

2

背景: 我不知道爲什麼用透明/半透明的背景導致與重量級彈出窗口,以及他們如何畫畫的問題,但它 - 你是否使用AWTUtilities.setWindowOpaque(window, false)frame.setBackground(new Color(0, 0, 0, 0)) regarless。

HeavyWeightPopup當彈出窗口不能完全適合目標窗口時,會創建該窗口。所以+ User2280704如果你點擊窗口的最底部,你的問題也會出現。 LightWeightPopup s沒有這個問題 - 因此,菜單在窗口中間工作。

另外,值得注意的是,通常第一次菜單會呈現罰款,而不是以下時間。

回答: 我想出了一個解決方法,在任何彈出窗口顯示後調用重新繪製。啓動應用程序時,只需調用以下代碼即可。

PopupFactory.setSharedInstance(new PopupFactory() 
{ 
    @Override 
    public Popup getPopup(Component owner, final Component contents, int x, int y) throws IllegalArgumentException 
    { 
     Popup popup = super.getPopup(owner, contents, x, y); 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       contents.repaint(); 
      } 
     }); 
     return popup; 
    } 
}); 
+0

我還是Java新手,所以我不確定你的意思,「在啓動你的應用程序時調用下面的代碼。」仔細闡述一些?我爲這個麻煩感到抱歉。 – kir

+0

沒問題,只需將該代碼粘貼到某處,並確保它在第一個彈出窗口出現之前執行。你只需要調用一次。所以,最簡單的情況下,你可以把它放在你的主要方法的任何地方。 – Lunchbox

2

發生這種情況時,我點擊的JFrame的

右側看起來像發生這種情況時,在彈出菜單中沒有完全包含在父窗口的邊界。不知道如何解決這個問題。

在Java 7,您可以使用:

frame.setBackground(new Color(0, 0, 0, 0)); 

透明度。

+0

'frame.setBackground(new Color(0,0,0,0));'''AWTUtilities.setWindowOpaque(window,false);'?可悲的是,這並沒有解決這個問題。 – kir

+0

是的,我剛剛測試過它。我發現彈出窗口在右側顯示爲空,但如果將鼠標移動到白色區域,則會顯示文本。仍然不知道爲什麼。不同的是,在JDK7中透明是API的一部分,您不需要使用不受支持的實用程序類。所以推測代碼可以更好地實現(儘管這個問題會另有說明)。 – camickr

+0

有重要的改變,一切都到了***,容器必須是未修飾的,L&F必須是SystemL&F,[重要的是代碼排序](http://stackoverflow.com/a/16699136/714968),在這一刻, d建議不要使用[AWTUtilities in Java7](http://stackoverflow.com/a/16415928/714968)沒有特殊原因或接受我* d * i * o * t * i * c限制,有趣的是事實你可以改變一切爲第二。容器,在離開第一個的情況下。原封不動 – mKorbel