显示子菜单时的 JPopupMenu bug/glitch(?)
我的弹出菜单有这个奇怪的错误。这种情况很少发生,而且看起来是随机的。问题是当我的 JPopupMenu 中有一个子菜单时 - 当我选择子菜单时,主菜单消失并且子菜单绘制不正确(就像主菜单的缓冲区绘制在子菜单上一样)。我仍然可以使用键盘进行导航。
以下是一些屏幕截图: 它应该是这样的
这就是错误出现时的样子:
所以第二张图片上的故障就是子菜单应该在的位置。
什么可能导致这种情况?没有抛出异常,它似乎与平台无关,所以我不知道如何缩小范围。请帮忙。
编辑下面是重现该问题的 sscce:
import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class Test {
private static Popup popup;
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
showMenu(e);
}
@Override
public void mouseReleased(MouseEvent e) {
showMenu(e);
}
private void showMenu(final MouseEvent e) {
if (e.isPopupTrigger()) {
JPopupMenu menu = new JPopupMenu();
JMenu subMenu = new JMenu("SubMenu");
menu.add(subMenu);
subMenu.add("Item 1");
subMenu.add("Item 2").addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
hidePopup();
// this is where I call the hide twice, in my case it was
// caused by some action or mouse listener calling it twice
hidePopup();
showPopup(e, frame);
}
});
subMenu.add("Item 3");
menu.show(frame.getContentPane(), e.getX(), e.getY());
}
}
private void showPopup(MouseEvent e, JFrame frame) {
PopupFactory popupFactory = PopupFactory.getSharedInstance();
JToolTip toolTip = new JToolTip();
toolTip.setTipText("wfkwdlpfhd ");
popup = popupFactory.getPopup(frame, toolTip, e.getXOnScreen(), e.getYOnScreen());
popup.show();
}
private void hidePopup() {
if (popup != null)
popup.hide();
}
});
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
I have this strange bug with my popup menu. It happens rarely and seemingly randomly. The problem is when I have a submenu in my JPopupMenu - when I select the submenu, main menu disappears and the submenu is painted incorrectly (it's like the buffer of main menu is painted over the submenu). I can still navigate it using keyboard.
Here are some screenshots:
This is how it should look like
And this is what it looks like when the bug appears:
So that glitch on the second picture is where the submenu should've been.
What could cause this? There are no exceptions thrown, it doesn't seem platform-related, so I have no idea how to narrow this down. Please help.
EDIT Below is a sscce that reproduces the problem:
import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class Test {
private static Popup popup;
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
showMenu(e);
}
@Override
public void mouseReleased(MouseEvent e) {
showMenu(e);
}
private void showMenu(final MouseEvent e) {
if (e.isPopupTrigger()) {
JPopupMenu menu = new JPopupMenu();
JMenu subMenu = new JMenu("SubMenu");
menu.add(subMenu);
subMenu.add("Item 1");
subMenu.add("Item 2").addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
hidePopup();
// this is where I call the hide twice, in my case it was
// caused by some action or mouse listener calling it twice
hidePopup();
showPopup(e, frame);
}
});
subMenu.add("Item 3");
menu.show(frame.getContentPane(), e.getX(), e.getY());
}
}
private void showPopup(MouseEvent e, JFrame frame) {
PopupFactory popupFactory = PopupFactory.getSharedInstance();
JToolTip toolTip = new JToolTip();
toolTip.setTipText("wfkwdlpfhd ");
popup = popupFactory.getPopup(frame, toolTip, e.getXOnScreen(), e.getYOnScreen());
popup.show();
}
private void hidePopup() {
if (popup != null)
popup.hide();
}
});
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
感谢我的一位用户,我发现了一个问题。
以防万一有人使用 swing 的次数超过了他们应该做的 - 这就是发生的事情:在我的程序的一部分中,我在 JProgressBar 上显示一条弹出消息,显示当用户移动进度条的拇指时的位置。为此,我使用
PopupFactory
创建一个Popup
。然后,使用鼠标侦听器显示和隐藏弹出窗口。在调用hide()
后,我没有将弹出对象设置为null
,这可能会导致调用hide()
两次,或者保持gc 的弹出窗口 - 不太清楚。但显然这搞乱了 JPopupMenu 的弹出机制。引用
Popup.hide()
JavaDoc 对此进行了更好的解释:Thanks to one of my users, I've found a problem.
Just in case someone is hacking with swing more than they should do - this is what happened: in one part of my program I show a popup message on a JProgressBar showing position when the user is moving the thumb of the progress bar. To do this, I create a
Popup
using aPopupFactory
. Then, using mouse listeners, I show and hide the popup. After I callhide()
I didn't set the popup object tonull
which may led to calling thehide()
twice, or keeping the popup from gc - don't know exactly. But apparently this messed up JPopupMenu's popup mechanism.Quote from
Popup.hide()
JavaDoc explains it better:我不确定它是否有助于解决您的问题,但通常应该以这种方式添加弹出菜单:
I'm not sure if it's going to help with your issue but normally the popup menu should be added that way: