【问题标题】:How to make a JFrame Modal in Swing java如何在 Swing java 中制作 JFrame 模态
【发布时间】:2010-12-01 16:06:13
【问题描述】:

我创建了一个使用 JFrame 的 GUI。我应该如何使它成为模态的?

【问题讨论】:

标签: java swing modal-dialog jframe


【解决方案1】:

唯一对我有用的代码:

childFrame.setAlwaysOnTop(true);

在使子/模态框架可见之前,应在主/父框架上调用此代码。您的子/模态框架也应该有这个代码:

parentFrame.setFocusableWindowState(false);
this.mainFrame.setEnabled(false);

【讨论】:

    【解决方案2】:

    正如其他人提到的,您可以使用 JDialog。如果您无权访问父框架,或者您想冻结洞应用程序,只需将 null 作为父框架传递:

    final JDialog frame = new JDialog((JFrame)null, frameTitle, true); frame.setModal(true);
    frame.getContentPane().add(panel);
    frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);

    【讨论】:

      【解决方案3】:

      您可以创建一个类,该类传递对父 JFrame 的引用并将其保存在 JFrame 变量中。然后您可以锁定创建新框架的框架。

      parentFrame.disable();
      
      //Some actions
      
      parentFrame.enable();
      

      【讨论】:

      • 很好,让我想到了在框架 isVisible() 时循环“暂停”(睡眠)应用程序,谢谢!
      • 卡米尔,Imgonzalves,你能帮我澄清一下吗?您是说应该在 JDialog、JFrame 或创建 OP 主题 JFrame 的任何内容中创建新类?
      【解决方案4】:

      最简单的方法是在可视化 JFrame 对象之前使用 pack() 方法。这是一个例子:

      myFrame frm = new myFrame();
      frm.pack();
      frm.setVisible(true);
      

      【讨论】:

      • 这有什么关系?
      【解决方案5】:

      此静态实用程序方法也通过秘密打开模态 JDialog 来显示模态 JFrame。我在 Windows 7、8 和 10-with-multiple-desktops 上成功地使用了它并且行为正确。

      这是local类很少使用的特性的一个很好的例子。

      import javax.swing.*;
      import java.awt.Dialog;
      import java.awt.Dimension;
      import java.awt.Frame;
      import java.awt.event.WindowAdapter;
      import java.awt.event.WindowEvent;
      
      // ... (class declaration)
      
      /**
       * Shows an already existing JFrame as if it were a modal JDialog. JFrames have the upside that they can be
       * maximized.
       * <p>
       * A hidden modal JDialog is "shown" to effect the modality.
       * <p>
       * When the JFrame is closed, this method's listener will pick up on that, close the modal JDialog, and remove the
       * listener.
       *
       * made by dreamspace-president.com
       *
       * @param window the JFrame to be shown
       * @param owner  the owner window (can be null)
       * @throws IllegalArgumentException if argument "window" is null
       */
      public static void showModalJFrame(final JFrame window, final Frame owner) {
      
          if (window == null) {
              throw new IllegalArgumentException();
          }
          window.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
          window.setVisible(true);
          window.setAlwaysOnTop(true);
      
          final JDialog hiddenDialogForModality = new JDialog(owner, true);
          final class MyWindowCloseListener extends WindowAdapter {
              @Override
              public void windowClosed(final WindowEvent e) {
                  window.dispose();
                  hiddenDialogForModality.dispose();
              }
          }
      
          final MyWindowCloseListener myWindowCloseListener = new MyWindowCloseListener();
          window.addWindowListener(myWindowCloseListener);
      
          final Dimension smallSize = new Dimension(80, 80);
          hiddenDialogForModality.setMinimumSize(smallSize);
          hiddenDialogForModality.setSize(smallSize);
          hiddenDialogForModality.setMaximumSize(smallSize);
          hiddenDialogForModality.setLocation(-smallSize.width * 2, -smallSize.height * 2);
          hiddenDialogForModality.setVisible(true);
          window.removeWindowListener(myWindowCloseListener);
      }
      

      【讨论】:

        【解决方案6】:

        如果要使窗口模态化,最好的办法是使用 JDialog 而不是 JFrame。查看details on the introduction of the Modality API in Java 6 获取信息。还有a tutorial。

        这里是一些示例代码,它将在JDialog 中显示JPanel panel,这是Frame parentFrame 的模态。除了构造函数之外,这遵循与打开JFrame 相同的模式。

        final JDialog frame = new JDialog(parentFrame, frameTitle, true);
        frame.getContentPane().add(panel);
        frame.pack();
        frame.setVisible(true);
        

        编辑:更新了 Modality API 链接并添加了教程链接(向@spork 表示感谢)。

        【讨论】:

        • 恐怕这似乎是唯一的解决方案。我正在用一些继承的代码来解决同样的问题。我有一个真正需要模态的 JFrame。将其全部转换为 JDialog 的工作真的很难看... :-(
        • 你能破解它吗?创建一个不可见的模态 JDialog,使其实例化 JFrame,并在 JFrame 关闭时,根据需要捕获值,然后关闭 JDialog
        • 链接已损坏 :( 3 年后仍有人试图从中学习!在 2013 年试试这个:docs.oracle.com/javase/tutorial/uiswing/misc/modality.html
        • 更新了原始文章的链接并添加了 sporks 教程链接 - 谢谢。
        • 我根本没有发现改用 JDialog 很难看。这是一个简单的改变。
        【解决方案7】:

        据我所知,JFrame 不能做 Modal 模式。改用 JDialog 并调用 setModalityType(Dialog.ModalityType type) 将其设置为模态(或非模态)。

        【讨论】:

          【解决方案8】:

          只需在课堂上将JFrame 替换为JDialog

          public class MyDialog extends JFrame // delete JFrame and write JDialog
          

          然后在构造函数中写入setModal(true);

          之后,您将能够在 netbeans 中构建您的表单 表格变成模态的

          【讨论】:

          • 不知道setModal(true);.. 这很棒
          • 需要说明这在 netbeans 下不起作用,因为他的表单编辑器设置了关闭对话框的关闭操作,这在 jdialog 中是不允许的
          【解决方案9】:

          在这种情况下我所做的是,在我想要保持可见的主 jframe(例如,菜单框架)中,我在属性窗口中取消选择选项focusableWindowState,所以它将是FALSE .一旦完成,我调用的 jframe 在我关闭它们之前不会失去焦点。

          【讨论】:

            【解决方案10】:

            如果您准备使用 JDialog 而不是 JFrame,则可以将 ModalityType 设置为 APPLICATION_MODAL。

            这提供了与典型 JOptionPane 相同的行为:

            import java.awt.event.ActionEvent;
            import javax.swing.*;
            import java.awt.*;
            import java.awt.event.ActionListener;
            
            public class MyDialog extends JFrame {
            
            public MyDialog() {
                setBounds(300, 300, 300, 300);
                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                setVisible(true);
                setLayout(new FlowLayout());
                JButton btn = new JButton("TEST");
                add(btn);
                btn.addActionListener(new ActionListener() 
                {
            
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        showDialog();
                    }
                });
            }
            
            private void showDialog() 
            {
            
                JDialog dialog = new JDialog(this, Dialog.ModalityType.APPLICATION_MODAL);
                //OR, you can do the following...
                //JDialog dialog = new JDialog();
                //dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
            
                dialog.setBounds(350, 350, 200, 200);
                dialog.setVisible(true);
            }
            
            public static void main(String[] args) 
            {
                new MyDialog();
            }
            }
            

            【讨论】:

              【解决方案11】:
              1. 创建一个新的 JPanel 表单
              2. 向其中添加所需的组件和代码

              YourJPanelForm stuff = new YourJPanelForm();
              JOptionPane.showMessageDialog(null,stuff,"Your title here bro",JOptionPane.PLAIN_MESSAGE);
              


              您的模态对话框正在等待...

              【讨论】:

              • 哦,但是有一个确定按钮,我不想要。
              • 等等什么?您可以像这样将 JPanel 添加到 JDialog 中吗?
              • 这与 jFrame 无关
              【解决方案12】:

              有一些代码可能会有所帮助:

              import java.awt.Component;
              import java.awt.event.ActionEvent;
              import java.awt.event.ActionListener;
              import java.awt.event.WindowAdapter;
              import java.awt.event.WindowEvent;
              
              import javax.swing.JFrame;
              import javax.swing.JMenu;
              import javax.swing.JMenuBar;
              import javax.swing.JMenuItem;
              
              public class ModalJFrame extends JFrame {
              
                  Object currentWindow = this;
              
                  public ModalJFrame() 
                  {
                      super();
                      super.setTitle("Main JFrame");
                      super.setSize(500, 500);
                      super.setResizable(true);
                      super.setLocationRelativeTo(null);
              
                      JMenuBar menuBar = new JMenuBar();
                      super.setJMenuBar(menuBar);
              
                      JMenu fileMenu = new JMenu("File");
                      JMenu editMenu = new JMenu("Edit");
              
                      menuBar.add(fileMenu);
                      menuBar.add(editMenu);
              
                      JMenuItem newAction = new JMenuItem("New");
                      JMenuItem openAction = new JMenuItem("Open");
                      JMenuItem exitAction = new JMenuItem("Exit");
                      JMenuItem cutAction = new JMenuItem("Cut");
                      JMenuItem copyAction = new JMenuItem("Copy");
                      JMenuItem pasteAction= new JMenuItem("Paste");
              
                      fileMenu.add(newAction);
                      fileMenu.add(openAction);
                      fileMenu.addSeparator();
                      fileMenu.add(exitAction);
              
                      editMenu.add(cutAction);
                      editMenu.add(copyAction);
                      editMenu.addSeparator();
                      editMenu.add(pasteAction);
              
                      newAction.addActionListener(new ActionListener()
                      {
                          public void actionPerformed(ActionEvent arg0)
                          {
              
                              JFrame popupJFrame = new JFrame();
              
                              popupJFrame.addWindowListener(new WindowAdapter()
                              {
                                    public void windowClosing(WindowEvent e) 
                                    {
                                        ((Component) currentWindow).setEnabled(true);                     }
                                    });
              
                              ((Component) currentWindow).setEnabled(false);
                              popupJFrame.setTitle("Pop up JFrame");
                              popupJFrame.setSize(400, 500);
                              popupJFrame.setAlwaysOnTop(true);
                              popupJFrame.setResizable(false);
                              popupJFrame.setLocationRelativeTo(getRootPane());
                              popupJFrame.setVisible(true);
                              popupJFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
                          }
                      });
              
                      exitAction.addActionListener(new ActionListener()
                      {
                          public void actionPerformed(ActionEvent arg0)
                          {
                              System.exit(0);
                          }
                      });
                  }
                  public static void main(String[] args) {
              
                      ModalJFrame myWindow = new ModalJFrame();
                      myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                      myWindow.setVisible(true);
                  }
              }
              

              【讨论】:

                【解决方案13】:

                不确定你的JFrame的内容,如果你询问用户的一些输入,你可以使用JOptionPane,这也可以将JFrame设置为模态

                            JFrame frame = new JFrame();
                            String bigList[] = new String[30];
                
                            for (int i = 0; i < bigList.length; i++) {
                              bigList[i] = Integer.toString(i);
                            }
                
                            JOptionPane.showInputDialog(
                                    frame, 
                                    "Select a item", 
                                    "The List", 
                                    JOptionPane.PLAIN_MESSAGE,
                                    null,
                                    bigList,
                                    "none");
                            }
                

                【讨论】:

                  猜你喜欢
                  • 2015-05-22
                  • 2022-01-10
                  • 2012-01-29
                  • 2011-05-25
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多