这是我所拥有的(简体版)。 (我以这种方式找到了代码):

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的情况下正确触发操作?

    最佳答案

    看起来,弹出窗口的父级对于操作触发必须是可见的(听起来对我来说似乎很合理)。因此,除了最后一步之外,您已做好一切工作:自行关闭自定义弹出窗口。这是代码:

    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);
                }
            });
        }
    }
    

    09-30 17:53