java - 未触发 JPopupMenu 操作

标签 java swing popupmenu

这是我所拥有的(简化版)。 (我是这样找到代码的):

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 的覆盖,但是如果我删除覆盖方法(或注释掉条件),我会遇到另一个问题:actionPerformedpop 上添加的方法永远不会被调用。

第一种情况:

  1. CustomPopup打开
  2. 我点击里面的东西
  3. JPopupMenu打开CustomPopup保持可见
  4. 我点击新菜单的一个项目
  5. Action被触发

第二种情况:

  1. CustomPopup打开
  2. 我点击里面的东西
  3. JPopupMenu打开CustomPopup是隐藏的
  4. 我点击新菜单的一个项目
  5. 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);
            }
        });
    }
}

关于java - 未触发 JPopupMenu 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36861153/

相关文章:

Java Swing 用鼠标移动 JFrame

c - GtkTextView 中的自动完成/建议弹出菜单

java - 弹出菜单中的复选框

java - "debuggable false"足以阻止调试我的应用程序吗?

java - URLConnection 类 java.net.ConnectException : Connection refused: connect

java - 需要知道每个字段是否已更改,我应该如何在 Hibernate 中对其进行建模

java - Android Studio - PopupMenu.OnMenuItemClickListener 问题

java - 关于事务和事件监听器

java - 使用 Combobox.removeAllItems() 时遇到问题;方法

java - Jbutton setTooltip() 作为 ImageIcon?