Question

My question is similar to this, but I think has a simpler example.

Basically by calling AWTUtilities.setWindowOpaque(window, false) to make the background of the JFrame transparent, my JPopupMenu sometimes show up as blank.

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

}

Here's an image of what's happening:

enter image description here enter image description here

What's interesting is that this happens whenever I click on the right side of the JFrame. Not sure why. Keep in mind I'm not 100% sure that AWTUtilities.setWindowOpaque(window, false) is indeed the cause of this problem, however whenever I delete that line everything seems to be going fine.

EDIT: As stated by camickr, looks like this happens when the popup menu is not fully contained in the bounds of the parent window.

Was it helpful?

Solution

Background: I'm not sure why using transparent / semi-transparent backgrounds causes problems with heavyweight popups and how they paint, but it does -- regarless of whether or not you use AWTUtilities.setWindowOpaque(window, false) or frame.setBackground(new Color(0, 0, 0, 0)).

The HeavyWeightPopups get created when a popup can't fit all the way inside the target Window. So +User2280704 your problem also presents if you click at the very bottom of your window. LightWeightPopups do not have this problem -- hence, menus work in the middle of your window.

Also, interesting to note, typically the menu will render fine the first time, just not the following times.

Answer: I've come up with a workaround that invokes a repaint after any popups display. Simply invoke the following code when you launch your application.

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

OTHER TIPS

this happens whenever I click on the right side of the JFrame

Looks like this happens when the popup menu is not fully contained in the bounds of the parent window. No idea how to fix this.

In Java 7 you can use:

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

for transparency.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top