3

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.

Community
  • 1
  • 1
kir
  • 581
  • 1
  • 6
  • 22
  • Oddly...Java 6 & Windows 7, no issues, Java 7 & Windows 7, no issues... – MadProgrammer Aug 16 '13 at 03:30
  • @MadProgrammer: Really? I'm on Java 7 & Windows 7, hmmm. – kir Aug 16 '13 at 03:31
  • JPopupMenus by default are lightweight when they are fully contained within the window. The problem presents when any part of the popup has to appear outside of the window -- it then creates a new heavy Window for the popup. The problem only presents in that heavy Window. – Lunchbox Aug 22 '13 at 16:02

2 Answers2

2

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.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • What's the difference between `frame.setBackground(new Color(0, 0, 0, 0));` and `AWTUtilities.setWindowOpaque(window, false);`? Sadly, this did not fix the issue also. – kir Aug 16 '13 at 03:01
  • Yes I just tested it. I found that the popup displays as empty on the right side, but if you move the mouse in the white area the text appears. Still have no idea why. The difference is that in JDK7 transparency is part of the API, you don't need to use a utility class which is not supported. So presumably the code is better implemented, (although this problem would indicate otherwise). – camickr Aug 16 '13 at 03:04
  • there are important changes, everything goes to ***, container must be undecorated, L&F must be SystemL&F, [important is code ordering](http://stackoverflow.com/a/16699136/714968), in this moment I'd suggest to don't use [AWTUtilities in Java7](http://stackoverflow.com/a/16415928/714968) without special reasons or accepting i*d*i*o*t*i*c restrictions, interesting is fact that you can to change everything for 2nd. container, in the case that leaving 1st. as untouched – mKorbel Aug 16 '13 at 06:26
2

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;
    }
});
Lunchbox
  • 1,603
  • 11
  • 14
  • I'm still new to Java, so I don't really know what you meant by "invoke the following code when you launch your application." Care to elaborate some more? I'm sorry for the trouble. – kir Aug 23 '13 at 05:38
  • No problem, just paste that code somewhere, and make sure it executes before your first popup appears. You only need to call it once. So, simplest case, you could put it anywhere in your main method. – Lunchbox Aug 23 '13 at 16:14