我的弹出菜单中有这个奇怪的错误。它很少发生,看似随机。问题是当我在我的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);
}
}
答案 0 :(得分:2)
感谢我的一位用户,我发现了一个问题。
万一有人用摇摆比他们应该做的更多 - 这就是发生的事情:在我的程序的一部分中,我在JProgressBar上显示一个弹出消息,显示当用户移动进度条的拇指时的位置。为此,我使用Popup
创建PopupFactory
。然后,使用鼠标监听器,我显示并隐藏弹出窗口。在我调用hide()
之后,我没有将弹出对象设置为null
,这可能导致调用hide()
两次,或者保持弹出窗口与gc - 不完全确切。但显然这搞砸了JPopupMenu的弹出机制。
来自Popup.hide()
的引用JavaDoc更好地解释了它:
隐藏和处置Popup。一旦弹出Popup,你就不应该再调用它了。可以回收处理的弹出窗口,然后根据PopupFactory使用。因此,如果在已释放的弹出窗口上调用方法,将导致不确定的行为。
答案 1 :(得分:0)
我不确定它是否会对您的问题有所帮助,但通常应该以这样的方式添加弹出菜单:
table.setComponentPopupMenu(popup);