-
Bug
-
Resolution: Unresolved
-
P3
-
8, 11, 17, 18, 19, 20
-
x86_64
-
windows_10
A DESCRIPTION OF THE PROBLEM :
JPopupMenu miscalculates popup location because of sun.awt.SunToolkit.canPopupOverlapTaskBar() always return true in Windows 10, but the popup may not always overlap the Windows taskbar.
Even the popup can overlap Windows 10 taskbar right after startup, but after clicking on the taskbar and popup again, the popup will always be behind the taskbar.
I've tested from jdk8+, all have this issue.
JDK-8231047 is precisely the same issue, and it's not "Cannot Reproduce". The example there has to test by moving the frame just above the windows taskbar. Example code in this task helps to calculate the location so you don't have to move the frame for testing.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Start the Test frame, and click the "Click to test popup" button. If the popup is on top of the taskbar, mouse-click on your Windows taskbar, and then try to click the "Click to test popup" again.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
the popup appears above (or overlap) the taskbar
ACTUAL -
the popup appears behind the taskbar
---------- BEGIN SOURCE ----------
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
public class Test extends JFrame
{
public Test()
{
JButton lvTestPopupButton = new JButton("Click to test popup");
lvTestPopupButton.setBounds(20, 20, 150, 60);
lvTestPopupButton.addActionListener(e ->
{
JPopupMenu menu = new JPopupMenu();
JPanel lvJPanel = new JPanel(null);
JButton lvButton = new JButton("OK");
lvButton.addActionListener(a -> menu.setVisible(false));
lvButton.setBounds(100, 100, 60, 22);
lvJPanel.add(lvButton);
lvJPanel.setPreferredSize(new Dimension(160, 122));
menu.add(lvJPanel);
menu.show(Test.this, 100, 100);
});
getContentPane().setLayout(null);
getContentPane().add(lvTestPopupButton);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(new Dimension(220, 200));
setLocation(calculateLocationForTest());
}
private Point calculateLocationForTest()
{
Toolkit toolkit = Toolkit.getDefaultToolkit();
GraphicsConfiguration gc = getGraphicsConfiguration();
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice lvDefaultScreen = ge.getDefaultScreenDevice();
if (lvDefaultScreen.getType() == GraphicsDevice.TYPE_RASTER_SCREEN)
{
gc = lvDefaultScreen.getDefaultConfiguration();
}
else
{
for (GraphicsDevice gd : ge.getScreenDevices())
{
if (gd.getType() == GraphicsDevice.TYPE_RASTER_SCREEN)
{
gc = gd.getDefaultConfiguration();
break;
}
}
}
if (gc != null)
{
Rectangle screenBounds = gc.getBounds();
// take screen insets (e.g. taskbar) into account
Insets screenInsets = toolkit.getScreenInsets(gc);
screenBounds.width -= screenInsets.right;
screenBounds.height -= screenInsets.bottom;
return new Point(screenBounds.width - 220, screenBounds.height - 200);
}
throw new RuntimeException("Please test in an OS with GUI (better just test in Windows)");
}
public static void main(String args[])
{
java.awt.EventQueue.invokeLater(() -> new Test().setVisible(true));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
If the JPopupMenu is created manually, set the location by manually calculating the screen bounds with insets.
(But somehow I get this issue in JMenu, which the popup location is uncontrollable, so there's no workaround. The test case is not JMenu because the issue of JMenu is not always reproducible)
FREQUENCY : always
JPopupMenu miscalculates popup location because of sun.awt.SunToolkit.canPopupOverlapTaskBar() always return true in Windows 10, but the popup may not always overlap the Windows taskbar.
Even the popup can overlap Windows 10 taskbar right after startup, but after clicking on the taskbar and popup again, the popup will always be behind the taskbar.
I've tested from jdk8+, all have this issue.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Start the Test frame, and click the "Click to test popup" button. If the popup is on top of the taskbar, mouse-click on your Windows taskbar, and then try to click the "Click to test popup" again.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
the popup appears above (or overlap) the taskbar
ACTUAL -
the popup appears behind the taskbar
---------- BEGIN SOURCE ----------
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
public class Test extends JFrame
{
public Test()
{
JButton lvTestPopupButton = new JButton("Click to test popup");
lvTestPopupButton.setBounds(20, 20, 150, 60);
lvTestPopupButton.addActionListener(e ->
{
JPopupMenu menu = new JPopupMenu();
JPanel lvJPanel = new JPanel(null);
JButton lvButton = new JButton("OK");
lvButton.addActionListener(a -> menu.setVisible(false));
lvButton.setBounds(100, 100, 60, 22);
lvJPanel.add(lvButton);
lvJPanel.setPreferredSize(new Dimension(160, 122));
menu.add(lvJPanel);
menu.show(Test.this, 100, 100);
});
getContentPane().setLayout(null);
getContentPane().add(lvTestPopupButton);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(new Dimension(220, 200));
setLocation(calculateLocationForTest());
}
private Point calculateLocationForTest()
{
Toolkit toolkit = Toolkit.getDefaultToolkit();
GraphicsConfiguration gc = getGraphicsConfiguration();
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice lvDefaultScreen = ge.getDefaultScreenDevice();
if (lvDefaultScreen.getType() == GraphicsDevice.TYPE_RASTER_SCREEN)
{
gc = lvDefaultScreen.getDefaultConfiguration();
}
else
{
for (GraphicsDevice gd : ge.getScreenDevices())
{
if (gd.getType() == GraphicsDevice.TYPE_RASTER_SCREEN)
{
gc = gd.getDefaultConfiguration();
break;
}
}
}
if (gc != null)
{
Rectangle screenBounds = gc.getBounds();
// take screen insets (e.g. taskbar) into account
Insets screenInsets = toolkit.getScreenInsets(gc);
screenBounds.width -= screenInsets.right;
screenBounds.height -= screenInsets.bottom;
return new Point(screenBounds.width - 220, screenBounds.height - 200);
}
throw new RuntimeException("Please test in an OS with GUI (better just test in Windows)");
}
public static void main(String args[])
{
java.awt.EventQueue.invokeLater(() -> new Test().setVisible(true));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
If the JPopupMenu is created manually, set the location by manually calculating the screen bounds with insets.
(But somehow I get this issue in JMenu, which the popup location is uncontrollable, so there's no workaround. The test case is not JMenu because the issue of JMenu is not always reproducible)
FREQUENCY : always
- relates to
-
JDK-8231047 JPopupMenu is hidden by Windows Task Bar
-
- Closed
-