【问题标题】:Prevent JPopupMenu from Closing on click防止 JPopupMenu 在单击时关闭
【发布时间】:2021-04-12 13:54:39
【问题描述】:

我有一个弹出菜单,但是当我点击某些东西时它会关闭。

这在大多数情况下都可以,但有时要求它不会在点击时关闭!

这是我正在处理的一段代码,它可以帮助您重现我所拥有的:

import javax.swing.*;
import javax.swing.event.*;

import java.awt.*;
import java.awt.event.*;

public class Try{
    public static void main(String[] args) {
        JFrame frame = new JFrame("Trial");
        JPopupMenu menu = new JPopupMenu();
        JLabel label = new JLabel("This is a popup menu!");
        menu.add(label);
        frame.setSize(900, 500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        menu.show(frame, 450, 250);
    }
}

如果我点击框架,我想要它菜单不会关闭!

【问题讨论】:

    标签: java swing user-interface jpopupmenu


    【解决方案1】:

    适合工作的适合工具。
    考虑一个非模态、未修饰的dialog(而不是JPopupMenu)。

    这是你需要的那种东西吗?

    import java.awt.Color;
    
    import javax.swing.*;
    
    public class Try{
        public static void main(String[] args) {
            JFrame frame = new JFrame("Trial");
            JLabel label = new JLabel("This is a popup menu!");
            label.setBorder(BorderFactory.createLineBorder(Color.red, 2));
            frame.setSize(900, 500);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
            JDialog dlg = new JDialog(frame);
            dlg.add(label);
            dlg.setUndecorated(true);
            dlg.pack();
            dlg.setLocationRelativeTo(frame);
            dlg.setVisible(true);
        }
    }
    

    这就是它在我电脑上的样子。

    如果您点击JFrame,对话框仍然可见。

    【讨论】:

      【解决方案2】:

      所以这可以通过 JPopupMenu 本身实现,并且不需要 JDialog。

      我必须重写 setVisible 方法并允许仅在调用 close 方法后关闭弹出窗口!

      这是弹出菜单仅在 5000 毫秒后关闭而不是单击时关闭的代码!

      import javax.swing.*;
      import javax.swing.event.*;
      
      import java.awt.*;
      import java.awt.event.*;
      
      public class Try{
          public static void main(String[] args) {
              JFrame frame = new JFrame("Trial");
              MyPopupMenu menu = new MyPopupMenu();
              JLabel label = new JLabel("This is a popup menu!");
              menu.add(label);
              frame.setSize(900, 500);
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.setLocationRelativeTo(null);
              frame.setVisible(true);
              menu.show(frame, 450, 250);
              Timer timer = new Timer(5000, new ActionListener() {
                   public void actionPerformed(ActionEvent evt) {
                       menu.closePopup();         
                       ((Timer)evt.getSource()).stop();
                   }
               });
               timer.start();
          }
      }
      
      class MyPopupMenu extends JPopupMenu{
          private boolean isHideAllowed;
      
          public MyPopupMenu(){
              super();
              this.isHideAllowed = false;
          }
      
          @Override
          public void setVisible(boolean visibility){
              if(isHideAllowed && !visibility)
                  super.setVisible(false);
              else if(!isHideAllowed && visibility)
                  super.setVisible(true);
          }
      
          public void closePopup(){
              this.isHideAllowed = true;
              this.setVisible(false);
          }
      }
      

      【讨论】:

        【解决方案3】:

        你需要设置正确的defaultCloseOperation-

        import javax.swing.*;
        import javax.swing.event.*;
        
        import java.awt.*;
        import java.awt.event.*;
        
        public class Try{
            public static void main(String[] args) {
                JFrame frame = new JFrame("Trial");
                JPopupMenu menu = new JPopupMenu();
                JLabel label = new JLabel("This is a popup menu!");
                menu.add(label);
                frame.setSize(900, 500);
                frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                frame.addWindowsListener(new WindowAdapter(){
                   //Determine whether you should call frame.dispose or hide.
                 });
                menu.show(frame, 450, 250);
            }
        }
        

        另见How to programmatically close a JFrame

        【讨论】:

        • 好吧,我误解了你关于 JPopupMenu 的问题,并认为它是关于 Jframe 的。美好的。现在,请重新阅读我对最后一部分的回答。
        • 最后一部分是什么
        • 您应该确定是否需要处理框架或隐藏它。我曾假设您使用框架作为弹出窗口。我已经阅读了 JPopup 的源代码。我可以看到实现此行为的唯一方法是重写 SetVisibile 方法,但我认为这是一个糟糕的解决方案,因为原始实现引用了许多私有变量。你最好按照@Abra 的建议去做。
        • 请查看我的答案一次
        猜你喜欢
        • 2016-02-10
        • 2017-02-27
        • 2012-11-24
        • 2018-02-20
        • 2012-04-04
        • 1970-01-01
        • 1970-01-01
        • 2011-10-13
        • 1970-01-01
        相关资源
        最近更新 更多