这是我所拥有的(一个siplified版本)。 (我找到了代码的方式):
class CustomPopup extends JPopupMenu {
public CustomPopup() {}
@Override
public void setVisible(boolean visible)
{
// Case 1:
//if (visible) super.setVisible(visible);
// Case 2:
super.setVisible(visible);
}
}
class CustomPanel extends JPanel {
// .../...
public CustomPanel() {
setSize(200, 200);
addMouseListener( new MouseAdapter(){
@Override
public void mousePressed( MouseEvent e ){
onMousePressed( e );
}
});
}
public void onMousePressed( MouseEvent e )
{
JPopupMenu pop = new JPopupMenu();
pop.add( new AbstractAction( "foo" )
{
@Override
public void actionPerformed( ActionEvent e )
{
// do stuff
System.out.println("this is executed");
}
});
pop.show( e.getComponent(), e.getX(), e.getY() );
}
}
public class TestPopup extends JFrame {
CustomPanel _pp;
CustomPopup _cpop;
public TestPopup () {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(333, 333);
_cpop = new CustomPopup();
_pp = new CustomPanel();
_cpop.add(_pp);
addMouseListener( new MouseAdapter(){
@Override
public void mousePressed( MouseEvent e ){
_cpop.show(e.getComponent(), 0, 0);
}
});
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
(new TestPopup()).setVisible(true);
}
});
}
}
弹出菜单显示自定义面板。与它交互时,它会显示一个带有选项列表的经典弹出菜单。
我的问题是CustomPopup
并没有按照自己的意愿关闭。罪魁祸首显然是setVisible
的覆盖,但是如果我删除覆盖方法(或注释掉条件)我还有另一个问题:actionPerformed
上添加的pop
方法永远不会被调用。
在第一种情况下:
CustomPopup
打开JPopupMenu
打开,CustomPopup
仍然可见 Action
在第二种情况下:
CustomPopup
打开JPopupMenu
打开,隐藏CustomPopup
Action
不已触发我的结论是CustomPopup
必须能够触发动作,即使我不明白为什么。所以我的问题是:如何以不会违反默认CustomPopup
行为的方式保持JPopupMenu
开放,或者如何在隐藏CustomPopup
的情况下正确触发操作?
答案 0 :(得分:2)
它看起来弹出窗口的父母必须是可见的动作触发(对我来说听起来似乎合情合理)。所以除了最后一步之外,你让所有人都能使它工作:自己关闭自定义弹出窗口。这是代码:
class CustomPopup extends JPopupMenu {
public CustomPopup() {}
@Override
public void setVisible(boolean visible)
{
// Case 1:
if (visible) super.setVisible(visible);
// Case 2:
// super.setVisible(visible);
}
public void makeInvisible() {
super.setVisible(false);
}
}
class CustomPanel extends JPanel {
// .../...
public CustomPanel() {
setSize(200, 200);
addMouseListener( new MouseAdapter(){
@Override
public void mousePressed( MouseEvent e ){
onMousePressed( e );
}
});
}
public void onMousePressed( MouseEvent e )
{
JPopupMenu pop = new JPopupMenu();
pop.add( new AbstractAction( "foo" )
{
@Override
public void actionPerformed( ActionEvent e )
{
// do stuff
System.out.println("this is executed");
Component comp = (Component) e.getSource();
if (comp != null && comp.getParent() instanceof JPopupMenu) {
JPopupMenu popupMenu = (JPopupMenu) comp.getParent();
if (popupMenu.getInvoker() instanceof CustomPanel) {
CustomPopup cpop = (CustomPopup) popupMenu.getInvoker().getParent();
cpop.makeInvisible();
}
}
}
});
pop.show( e.getComponent(), e.getX(), e.getY() );
}
}
public class TestPopup extends JFrame {
CustomPanel _pp;
CustomPopup _cpop;
public TestPopup () {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(333, 333);
_cpop = new CustomPopup();
_pp = new CustomPanel();
_cpop.add(_pp);
addMouseListener( new MouseAdapter(){
@Override
public void mousePressed( MouseEvent e ){
_cpop.show(e.getComponent(), e.getX(), e.getY());
}
});
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
(new TestPopup()).setVisible(true);
}
});
}
}