半透明窗口内的半透明JPopupMenu – 另类?

我不确定这是否可行,但有没有办法安全地允许弹出窗口是半透明的,即使父容器也是半透明的?

如果没有, 使用或扩展而不是JPopupMenu明智替代方案是什么?

注意: 半透明是指不具有“背景”的组件,类似于setOpaque(false);的效果setOpaque(false); 。 谢谢。

来自2009年用户camickr的论坛回答:

我不知道透明画在1.6.0_10中是否有所改变。 在此之前,我认为透明度只能在轻量级组件中实现(即Swing完成所有绘画)。 JFrame,JWindow和JDialog不是轻量级的,因为它们使用OS组件。

在弹出窗口的情况下,它完全包含在其父帧中时是轻量级的。 但是一个轻量级的弹出窗口不能在框架的边界外绘制,所以JWindow(我相信)被用作弹出窗口,它不能透明。

SSCCE:在半透明的JFrame顶部显示半透明的JWindow

 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); } } 

尝试这个代码部分,我曾经使用过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(); } }); } } 

这是输出:

半透明

警告我正在接受

 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 na 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