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:
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.
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 HeavyWeightPopup
s 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. LightWeightPopup
s 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;
}
});