2012-05-10 245 views
4

我不確定這是否可行,但是有沒有辦法安全地讓彈出窗口變得半透明,即使父容器也是半透明的?
半透明窗口內的半透明JPopupMenu - 可選項?

如果不是,什麼是明智的替代使用或擴展替代JPopupMenu

注意:半透明是指不具有背景的組件,類似於setOpaque(false);的效果。謝謝。



從論壇中回答用戶camickr 2009年:

我不知道,如果透明度畫1.6.0_10發生了變化。之前 ,我相信透明度只能在輕量級 組件(即Swing做所有的繪畫)中實現。 JFrame,JWindow和 JDialog不是輕量級的,因爲它們使用OS組件。

如果是彈出式窗口,則在其父框架內完全包含 時是輕量級的。但是一個輕量級的彈出框不能在框架的邊界之外被繪製爲 ,所以JWindow(我相信)被用作 彈出框,它不能透明。

SSCCE:顯示半透明的JWindow在半透明的JFrame

import com.sun.awt.AWTUtilities; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 

public class OpaqueWindowSSCCE { 

    private int countdown = 5; 

    public static void main(String[] args) { 
     new OpaqueWindowSSCCE(); 
    } 

    public OpaqueWindowSSCCE() { 
     final JFrame frame = new JFrame("OpaqueWindowSSCCE"); 
     final JWindow window = new JWindow(); 

     new Timer(1000, new ActionListener(){ 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       if(--countdown == 0){ 
        frame.dispose(); 
        window.dispose(); 
        System.exit(0); 
       } else { 
        frame.repaint(); 
       } 
      } 

     }).start(); 

     frame.setContentPane(new JPanel() { 

      @Override 
      public void paintComponent(Graphics paramGraphics) { 
       super.paintComponent(paramGraphics); 
       Graphics2D g = (Graphics2D) paramGraphics.create(); 
       g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
       g.setColor(new Color(50, 50, 50)); 
       g.fillRoundRect(0, 0, getWidth(), getHeight(), 10, 10); 
       g.setColor(new Color(180, 180, 180)); 
       g.drawString("Closing in " + countdown + " seconds", 20, 25); 
      } 
     }); 

     window.setContentPane(new JPanel() { 

      @Override 
      public void paintComponent(Graphics paramGraphics) { 
       super.paintComponent(paramGraphics); 
       Graphics2D g = (Graphics2D) paramGraphics.create(); 
       g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
       g.setColor(new Color(180, 180, 180)); 
       g.fillRoundRect(0, 0, getWidth(), getHeight(), 10, 10); 
      } 
     }); 

     frame.setUndecorated(true); 

     ((JComponent) frame.getContentPane()).setOpaque(false); 
     ((JComponent) window.getContentPane()).setOpaque(false); 

     AWTUtilities.setWindowOpaque(frame, false); 
     AWTUtilities.setWindowOpaque(window, false); 

     window.setAlwaysOnTop(true); 

     frame.setBounds(200,200,500,500); 
     window.setBounds(600,600,200,200); 
     frame.setVisible(true); 
     window.setVisible(true); 
    } 
} 
+0

我想這是可以實現的,在給定的情況下,您正在使用此功能可按做,用'JWindow' [setOpacity()](HTTP:// docs.oracle.com/javase/7/docs/api/java/awt/Window.html#setOpacity(float))。 –

回答

4

的頂部試試這個代碼的一部分,我用了JWindow雖然

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

public class WindowExample 
{ 
    private JWindow window; 
    private JLabel updateLabel; 
    private int count = 5; 
    private Timer timer; 
    private int x; 
    private int y; 
    private ActionListener timerAction = new ActionListener() 
    { 
     public void actionPerformed(ActionEvent ae) 
     { 
      updateLabel.setText("Closing Window in " + count + " seconds..."); 
      count--; 
      if (count == 0) 
      { 
       timer.stop(); 
       window.setVisible(false); 
       window.dispose(); 
      } 
     } 
    }; 

    private void createAndDisplayGUI() 
    { 
     final JFrame frame = new JFrame("Window Example"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     frame.setUndecorated(true); 
     frame.setOpacity(0.5f); 
     frame.addMouseListener(new MouseAdapter() 
     { 
      public void mouseClicked(MouseEvent me) 
      { 
       x = me.getX(); 
       y = me.getY(); 
       window = new JWindow(); 
       JPanel contentPane = new JPanel(); 
       JLabel positionLabel = new JLabel(
        "X : " + me.getX() + " Y : " + me.getY()); 
       updateLabel = new JLabel("TImer"); 
       contentPane.setLayout(new BorderLayout(5, 5)); 
       contentPane.add(updateLabel, BorderLayout.CENTER); 
       contentPane.add(positionLabel, BorderLayout.PAGE_END); 
       window.setContentPane(contentPane); 
       window.setOpacity(0.5f); 
       window.setSize(200, 100); 
       window.setLocation(x + window.getWidth(), y + window.getHeight()); 
       window.setVisible(true); 
       count = 5; 
       timer = new Timer(1000, timerAction); 
       timer.start(); 
      } 
     }); 

     frame.setSize(500, 500); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String... args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       new WindowExample().createAndDisplayGUI(); 
      } 
     }); 
    } 
} 

這裏是輸出:

TRANSLUCENT

警告我得到

C:\Mine\JAVA\J2SE>javac -d classes src\OpaqueWindowSSCCE.java 
src\OpaqueWindowSSCCE.java:1: warning: AWTUtilities is internal proprietary API and may be removed i 
n a future release 
import com.sun.awt.AWTUtilities; 
       ^
src\OpaqueWindowSSCCE.java:68: warning: AWTUtilities is internal proprietary API and may be removed 
in a future release 
     AWTUtilities.setWindowOpaque(frame, false); 
     ^
src\OpaqueWindowSSCCE.java:69: warning: AWTUtilities is internal proprietary API and may be removed 
in a future release 
     AWTUtilities.setWindowOpaque(window, false); 
     ^
3 warnings 
+1

感謝您的SSCCE!很顯然,'JWindow'能夠正確顯示 - 缺點是我必須實現顯示和隱藏以模仿'JPopupMenu',這不會太難。 – rtheunissen

+0

你是最歡迎和保持微笑:-),是的,這是真的,即使在'JPopUpMenu'我猜你必須點擊其他地方來隱藏以前的:-),只是'JWindow'的優點是我們可以添加任何我們想要添加到它,以顯示給用戶:-) –

+0

是的,但'JPopUpMenu'處理焦點非常好,將不得不確保它運作良好。出於某種原因,我根本沒有想到'JWindow' ......謝謝,我會給它一個機會,然後回到你身邊。 :D – rtheunissen