【问题标题】:How to make JDialog onTop only for his parent?如何只为他的父母制作 JDialog onTop?
【发布时间】:2013-02-14 13:47:29
【问题描述】:

比方说,我们有几个JFrame 窗口同时可见,每个窗口JDialog 都会出现。当我们的窗口处于级联模式并且对话框setAlwaysOnToptrue 时,所有对话框都将在最后一个窗口上可见。

我只想将一个 Dialog 组件与其所有者相关联,这样当您在 Frames 之间切换时,您只会在顶部看到一个对话框,并且在单击一个框架时不会丢失此对话框。

对话框有这样的构造函数:

setAlwaysOnTop(true);
setModal(false);

提前致谢!

【问题讨论】:

    标签: java swing modal-dialog jdialog


    【解决方案1】:
    How to make JDialog onTop only for his parent?
    
    • setParent in the constructor properly

    • 必须使用setModalityType f.e. ModalityType.DOCUMENT_MODAL ModalityType.APPLICATION_MODAL 而不是 setModal

    • setModalintialized/is parent for这个JDialog的容器有效

    • 不要使用多个JFrame,而是使用JDialog,将此容器重复用于其他操作

    例如

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class SuperConstructor extends JFrame {
    
        private static final long serialVersionUID = 1L;
    
        public SuperConstructor() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setPreferredSize(new Dimension(300, 300));
            setTitle("Super constructor");
            Container cp = getContentPane();
            JButton b = new JButton("Show dialog");
            b.addActionListener(new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent evt) {
                    FirstDialog firstDialog = new FirstDialog(SuperConstructor.this);
                }
            });
            cp.add(b, BorderLayout.SOUTH);
            JButton bClose = new JButton("Close");
            bClose.addActionListener(new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent evt) {
                    System.exit(0);
                }
            });
            add(bClose, BorderLayout.NORTH);
            pack();
            setVisible(true);
        }
    
        public static void main(String args[]) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    SuperConstructor superConstructor = new SuperConstructor();
                }
            });
        }
    
        private class FirstDialog extends JDialog {
    
            private static final long serialVersionUID = 1L;
    
            FirstDialog(final Frame parent) {
                super(parent, "FirstDialog");
                setPreferredSize(new Dimension(200, 200));
                setLocationRelativeTo(parent);
                setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
                JButton bNext = new JButton("Show next dialog");
                bNext.addActionListener(new ActionListener() {
    
                    @Override
                    public void actionPerformed(ActionEvent evt) {
                        SecondDialog secondDialog = new SecondDialog(parent, false);
                    }
                });
                add(bNext, BorderLayout.NORTH);
                JButton bClose = new JButton("Close");
                bClose.addActionListener(new ActionListener() {
    
                    @Override
                    public void actionPerformed(ActionEvent evt) {
                        setVisible(false);
                    }
                });
                add(bClose, BorderLayout.SOUTH);
                pack();
                setVisible(true);
            }
        }
        private int i;
    
        private class SecondDialog extends JDialog {
    
            private static final long serialVersionUID = 1L;
    
            SecondDialog(final Frame parent, boolean modal) {
                //super(parent); // Makes this dialog unfocusable as long as FirstDialog is visible
                setPreferredSize(new Dimension(200, 200));
                setLocation(300, 50);
                setModal(modal);
                setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                setTitle("SecondDialog " + (i++));
                setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
                JButton bClose = new JButton("Close");
                bClose.addActionListener(new ActionListener() {
    
                    @Override
                    public void actionPerformed(ActionEvent evt) {
                        setVisible(false);
                    }
                });
                add(bClose, BorderLayout.SOUTH);
                pack();
                setVisible(true);
            }
        }
    }
    

    【讨论】:

    • 在我的情况下,我需要 Dialog 的窗口始终是非模态的,并且在顶部 only 用于他的 parent。为JDialog 设置父级没有意义,因为onTopJDialog 使其在整个应用程序中处于首位。因此,如果我们有两个JFrame 和两个JDialog,我们就看不到哪个对话框与哪个窗口相关。
    【解决方案2】:

    API 中,JDialog 构造函数之一是JDialog(Dialog owner, boolean modal),这意味着您可以创建一个对话框并指定父容器以及模态。在 modal 部分,设置为 true 意味着这个对话框将是模态的,当对话框显示时你不能访问父窗口。

    但同样,您可以使用setModal() 方法来完成相同的操作。

    【讨论】:

    • JDialog 设置所有者不影响onTop 功能。 onTop(true)JDialog 设置为整个应用程序的顶部。
    【解决方案3】:

    只需将Model 设置为true,只需设置Relativelocation(parent);,不要将setontop(true) 用于JDialog。

    然后如果你在那个时候重新打开,你每次都会得到对话框。但是当你拖动父框架时会有所不同。

    【讨论】:

      【解决方案4】:

      我设法解决了这个问题,构建了一个可以完成这项工作的焦点侦听器。然后,您可以将此侦听器设置为您希望对话框在关闭之前始终可见的窗口。这对我有用:

      public class WindowFocusListenerDialogFocus implements WindowFocusListener {
          private JFrame _dialogFrame;
      
      
          public WindowFocusListenerDialogFocus(JFrame dialogFrame) {
              _dialogFrame = dialogFrame;
          }
      
      
          @Override
          public void windowLostFocus(WindowEvent e) {
              System.out.println("Focus lost!");
          }
      
      
          @Override
          public void windowGainedFocus(WindowEvent e) {
              System.out.println("Focus gained!");
              _dialogFrame.toFront();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-04
        • 1970-01-01
        • 2020-05-26
        • 2014-02-09
        • 2015-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多