JPopupPanel
单击按钮时,我会出现。
这JPopupPanel
有一个JPopupMenu
通过鼠标右键单击显示的,显示不同的选项。当按下左键在 PopupMenu 中选择此选项之一时,PopupPanel 会关闭,PopupMenu 会自行关闭片刻,当释放按钮时,PopupMenu 也会消失(如预期的那样),但在PopupPanel 因为它已经关闭了。
选择 JPopupMenu 的选项之一时,如何避免 JPopupPanel 关闭?
谢谢
JPopupPanel
单击按钮时,我会出现。
这JPopupPanel
有一个JPopupMenu
通过鼠标右键单击显示的,显示不同的选项。当按下左键在 PopupMenu 中选择此选项之一时,PopupPanel 会关闭,PopupMenu 会自行关闭片刻,当释放按钮时,PopupMenu 也会消失(如预期的那样),但在PopupPanel 因为它已经关闭了。
选择 JPopupMenu 的选项之一时,如何避免 JPopupPanel 关闭?
谢谢
抱歉,我没有使用 JPopupPanel 的经验。因此,我只能提供一个简单的hack。
我怀疑您可以执行与我的示例(如下)类似的操作,其中我“忽略”在选项选择上隐藏弹出菜单。
我的方法是在选项选择上重新显示弹出菜单。因此,也许您可以尝试在面板隐藏时重新显示它。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
public class JPopupMenuIgnoreOptionCloseOnClick extends JPanel
{
private static final long serialVersionUID = 1L;
private JPopupMenu popup = new JPopupMenu("Oi I am popup");
private MouseListener mL = new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent e)
{
System.out.println("mL mousePressed e.isP="+e.isPopupTrigger());
super.mousePressed(e);
showPopup(e);
}
@Override
public void mouseReleased(MouseEvent e)
{
System.out.println("mL mouseReleased e.isP="+e.isPopupTrigger());
super.mouseReleased(e);
showPopup(e);
}
private void showPopup(MouseEvent e)
{
if(e.isPopupTrigger())
{
prevLocation = e.getPoint();
popup.show(e.getComponent(), e.getX(), e.getY());
}
}
};
private Point prevLocation = null;
private MouseListener optionML = new MouseAdapter()
{
@Override
public void mouseReleased(MouseEvent e)
{
System.out.println("optionML mouseReleased prevLocation="+prevLocation);
e.consume();
popup.show(JPopupMenuIgnoreOptionCloseOnClick.this, prevLocation.x,prevLocation.y);
}
};
public JPopupMenuIgnoreOptionCloseOnClick()
{
addMouseListener(mL);
JMenuItem opt1 =new JMenuItem("Option 1");
opt1.addMouseListener(optionML);
popup.add(opt1);
JMenuItem opt2 =new JMenuItem("Option 2");
opt2.addMouseListener(optionML);
popup.add(opt2);
JMenuItem opt3 =new JMenuItem("Option 3");
opt3.addMouseListener(optionML);
popup.add(opt3);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
JPopupMenuIgnoreOptionCloseOnClick p = new JPopupMenuIgnoreOptionCloseOnClick();
p.setPreferredSize(new Dimension(400, 400));
JPanel contentPane = new JPanel();
contentPane.setBackground(Color.CYAN);
contentPane.add(p);
JFrame f = new JFrame();
f.setContentPane(contentPane);
f.setSize(800, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
});
}
}
在 JCommandButton 上安装自定义 JPopupMenu 时,我自己也遇到了这个问题。对于您的 JCommandButton,我发现这有助于防止过早处理父弹出窗口:
this.putClientProperty(BasicCommandButtonUI.DONT_DISPOSE_POPUPS, true);
如果您正在寻找的是在进行 JPopupMenu JMenuItem 选择时,父弹出面板将保持打开状态,您有几个选项。问题源于 JPopupMenu 在祖先容器链中的断开链接,UI 依赖于该链接。您需要返回 getInvoker(),而不是 getParent()。
1:
修改BasicPopupPanelUI.WindowTracker.eventDispatched()中的库源。将SwingUtilities .getAncestorOfClass() 调用更改为使用SwingXUtilities .getAncestorOfClass() 来解决这种特殊情况。或者自己实现逻辑。
if(parent instanceof JPopupMenu) parent = ((JPopupMenu)parent).getInvoker()
2:
将此代码添加到小部件(CustomButton?)
final JPopupMenu popper = new JPopupMenu(){ //hack
@Override public Container getParent(){
StackTraceElement ste = Thread.currentThread().getStackTrace()[2];
if(ste.getClassName().equals(SwingUtilities.class.getName()))
return CustomButton.this.getParent();
return super.getParent();
}
};
我选择了 #2,因为我在修改 3rd 方库时遇到了问题。