我有一个JPopupMenu,当用户右键单击窗口时出现(按照常用弹出窗口)。当你在屏幕中间出现时,从来没有问题,但是当你面对屏幕的右侧或底部时,菜单就不会出现问题。在全屏模式下显示。
奇怪的是,如果你进行随后的左键单击 - 假装菜单在那里(因为它确实存在) - 它仍然会选择正确的值,就像菜单的垂直和/或水平位置一样调整以补偿屏幕边缘。
更奇怪的是,这只发生在某些机器上,原因我无法理解。例如,我在这里有两台PC,都运行Win7;其中一个展示失败,另一个展示失败。在 出现故障的计算机上,我所拥有的Win7 VM也可以,但Ubuntu VM没有。现在,我注意到的一件事是,在出现渲染问题的机器上,一旦进入全屏模式,JFrame的标题栏就会消失,而其他的则没有(即它们仍显示关闭和最小化按钮,使其成为现实看起来像这些机器上的全屏独占模式只不过是最大化了。)
这是一个功能齐全的问题示例(假设您的机器对它非常敏感)(进入全屏查看问题)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.xml.ws.Holder;
public class ExclusiveModePopup {
public static void main(String[] args) {
final JFrame frame = new JFrame("Exclusive Popup test");
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final Holder<Boolean> isInFullScreen = new Holder<Boolean>(false);
final Holder<String> lastSelected = new Holder<String>("");
final JPanel pane = new JPanel(new BorderLayout());
pane.add(new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
FontMetrics fm = g.getFontMetrics();
int fontHeight = fm.getMaxAscent();
g.setColor(Color.green);
g.drawOval(5, 5, 20, 20);
g.drawString("Right click here to see normal", 5, 25 + fontHeight);
if(!isInFullScreen.value){
g.drawOval(5, this.getHeight() - 30, 20, 20);
g.drawString("Right click here to see vertical adjustment",
5, this.getHeight() - 35);
g.drawOval(this.getWidth() - 30, 5, 20, 20);
String alongRight = "Right click here to see horizontal adjustment";
int strWidth = fm.charsWidth(alongRight.toCharArray(), 0, alongRight.length());
g.drawString(alongRight, this.getWidth() - 5 - strWidth, 25 + fontHeight);
g.drawOval(this.getWidth() - 30, this.getHeight() - 30, 20, 20);
alongRight = "Right click here to see both values adjusted";
strWidth = fm.charsWidth(alongRight.toCharArray(), 0, alongRight.length());
g.drawString(alongRight, this.getWidth() - 5 - strWidth, this.getHeight() - 35);
} else {
g.setColor(Color.red);
g.drawOval(5, this.getHeight() - 30, 20, 20);
g.drawString("Right click here to see failure",
5, this.getHeight() - 35);
g.drawOval(this.getWidth() - 30, 5, 20, 20);
String alongRight = "Right click here to see more failure";
int strWidth = fm.charsWidth(alongRight.toCharArray(), 0, alongRight.length());
g.drawString(alongRight, this.getWidth() - 5 - strWidth, 25 + fontHeight);
g.drawOval(this.getWidth() - 30, this.getHeight() - 30, 20, 20);
alongRight = "Right click here to see yet some moar failure";
strWidth = fm.charsWidth(alongRight.toCharArray(), 0, alongRight.length());
g.drawString(alongRight, this.getWidth() - 5 - strWidth, this.getHeight() - 35);
}
g.setColor(Color.white);
String lastSel = "Last selected value: " + lastSelected.value;
int strWidth = fm.charsWidth(lastSel.toCharArray(), 0, lastSel.length());
g.drawString(lastSel, this.getWidth() / 2 - strWidth / 2, this.getHeight() / 2);
}
}, BorderLayout.CENTER);
final JPopupMenu popup = new JPopupMenu();
for (int i = 0; i < 10; i++) {
final int j = i;
popup.add(new JMenuItem(new AbstractAction("Long name item number " + i){
@Override
public void actionPerformed(ActionEvent arg0) {
lastSelected.value = "Item #" + j;
pane.repaint();
}
}));
}
pane.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if ((e.getModifiers() & MouseEvent.BUTTON3_MASK) == MouseEvent.BUTTON3_MASK) {
popup.show((Component) e.getSource(), e.getX(), e.getY());
}
}
});
final GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
pane.add(new JButton(new AbstractAction("Toggle Fullscreen") {
@Override
public void actionPerformed(ActionEvent arg0) {
if (gd.isFullScreenSupported()) {
if (!isInFullScreen.value) {
gd.setFullScreenWindow(frame);
isInFullScreen.value = true;
} else {
gd.setFullScreenWindow(null);
isInFullScreen.value = false;
}
}
}
}), BorderLayout.SOUTH);
frame.setContentPane(pane);
Rectangle screenBounds = gd.getDefaultConfiguration().getBounds();
frame.setSize(800, 600);
Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gd.getDefaultConfiguration());
frame.setLocation(screenBounds.width - frame.getWidth() - screenInsets.right,
screenBounds.height - frame.getHeight() - screenInsets.bottom);
frame.setVisible(true);
}
}
思考?提前谢谢。