Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
363 views
in Technique[技术] by (71.8m points)

java - Translucent JPopupMenu inside a Translucent Window - alternative?

I'm not sure if this is possible, but is there a way to safely allow popups to be translucent even when the parent container is also translucent?

If not, what would be wise alternative to use or extend instead of JPopupMenu?

Note: Translucent refers to a component not 'having a background', similar to the effect of setOpaque(false);. Thanks.



From a forum answer by user camickr in 2009:

I don't know if transparency painting has changed in 1.6.0_10. Prior to that I believe transparency can only be achieved in lightweight components (ie. Swing does all the painting). JFrame, JWindow and JDialog are not lightweight because they use OS components.

In the case of a popup, it is lightweight when entirely contained within its parent frame. But a lightweight popup can not be painted outside the bounds of the frame so a JWindow (I believe) is used as the popup, which can't be transparent.

SSCCE: Showing translucent JWindow over the top of translucent 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);
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try this code part, I had used JWindow though

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

And here is the output :

TRANSLUCENT

WARNING I AM GETTING

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...