Java Jframe中2个Jdialogs的setModal问题

Java Jframe中2个Jdialogs的setModal问题,java,swing,modal-dialog,jframe,jdialog,Java,Swing,Modal Dialog,Jframe,Jdialog,当我将第一个JDialog设置为模态,第二个设置为非模态时,我面临着一些问题 这是我正在尝试实现的功能: 单击“测试对话框!”按钮,将出现一个名为自定义对话框的JDialog 主管道将打开 如果单击自定义对话框主菜单中的“是”选项,则另一个 JDialog命名自定义对话框搜索将打开 如果在自定义对话框搜索中单击“是”选项,则 自定义主对话框应该放在前面 我应该能够选择任何JDialog。例如,如果我选择 自定义对话框搜索,另一个对话框应转到 反之亦然 我面临的问题是,当我在自定义对话框主对话框中

当我将第一个
JDialog
设置为模态,第二个设置为非模态时,我面临着一些问题

这是我正在尝试实现的功能:

  • 单击“测试对话框!”按钮,将出现一个名为自定义对话框的
    JDialog
    主管道将打开
  • 如果单击自定义对话框主菜单中的“是”选项,则另一个
    JDialog
    命名自定义对话框搜索将打开
  • 如果在自定义对话框搜索中单击“是”选项,则 自定义主对话框应该放在前面
  • 我应该能够选择任何
    JDialog
    。例如,如果我选择 自定义对话框搜索,另一个对话框应转到 反之亦然
  • 我面临的问题是,当我在自定义对话框主对话框中单击“是”时,自定义对话框搜索将显示在主对话框后面

    这是因为我将自定义对话框搜索设置为非模态。 如果我选择此对话框模式,它会正确显示,但单击“是”后,自定义对话框主界面不会出现

    我甚至尝试将CustomDialogSearch的父对象设置为CustomDialog,但行为仍然不正确

    下面是我正在测试的示例代码

    import java.awt.event.ActionListener;  
    import javax.swing.JFrame;  
    import javax.swing.JButton;  
    import java.awt.event.WindowAdapter;  
    import java.awt.event.WindowEvent;  
    import java.awt.event.ActionEvent;  
    import java.awt.Dimension;   
    
    public class TestTheDialog implements ActionListener {  
        JFrame mainFrame = null;  
        JButton myButton = null;  
    
        public TestTheDialog() {  
            mainFrame = new JFrame("TestTheDialog Tester");  
            mainFrame.addWindowListener(new WindowAdapter() {  
                    public void windowClosing(WindowEvent e) {System.exit(0);}  
                });  
            myButton = new JButton("Test the dialog!");  
            myButton.addActionListener(this);  
            mainFrame.setLocationRelativeTo(null);  
            mainFrame.getContentPane().add(myButton);  
            mainFrame.pack();  
            mainFrame.setVisible(true);  
        }  
    
        public void actionPerformed(ActionEvent e) {  
            if(myButton == e.getSource()) {  
                System.err.println("Opening dialog.");  
                CustomDialog myDialog = new CustomDialog(mainFrame, true, "Custom Dialog Main?");  
                System.err.println("After opening dialog.");  
                if(myDialog.getAnswer()) {  
                    System.err.println("The answer stored in CustomDialog is 'true' (i.e. user clicked yes button.)");  
                }  
                else {  
                    System.err.println("The answer stored in CustomDialog is 'false' (i.e. user clicked no button.)");  
                }  
            }  
        }  
    
        public static void main(String argv[]) {  
    
            TestTheDialog tester = new TestTheDialog();  
        }  
    }  
    
    import javax.swing.JDialog;   
    import java.awt.event.ActionListener;  
    import javax.swing.JPanel;  
    import javax.swing.JFrame;  
    import javax.swing.JLabel;  
    import javax.swing.JButton;  
    import java.awt.event.ActionEvent;  
    
    public class CustomDialog extends JDialog implements ActionListener {  
        private JPanel myPanel = null;  
        private JButton yesButton = null;  
        private JButton noButton = null;  
        private boolean answer = false;  
        private JFrame parentFrame;  
        public boolean getAnswer() { return answer; }  
    
        public CustomDialog(JFrame frame, boolean modal, String myMessage) {  
            super(frame, modal);  
            parentFrame = frame;  
            myPanel = new JPanel();  
            getContentPane().add(myPanel);  
            myPanel.add(new JLabel(myMessage));  
            yesButton = new JButton("Yes");  
            yesButton.addActionListener(this);  
            myPanel.add(yesButton);   
            noButton = new JButton("No");  
            noButton.addActionListener(this);  
            myPanel.add(noButton);    
            pack();  
            setLocationRelativeTo(frame);  
            setVisible(true);  
        }  
    
        public void actionPerformed(ActionEvent e) {  
            if(yesButton == e.getSource()) {  
                CustomDialogSearch myDialog = new CustomDialogSearch(parentFrame, false, "CustomDialog Search?");  
                System.err.println("User chose yes.");  
                answer = true;  
                myDialog.getAnswer();  
                System.out.println("myDialog.getAnswer()="+myDialog.getAnswer());  
                myDialog.show();  
    
                if(myDialog.getAnswer()==true)  
                {  
                    System.out.println("tofront");  
                    this.toFront();  
                }  
                //setVisible(false);  
            }  
            else if(noButton == e.getSource()) {  
                System.err.println("User chose no.");  
                answer = false;  
                setVisible(false);  
            }  
        }  
    
    }
    
    import javax.swing.JDialog;   
    import java.awt.event.ActionListener;  
    import javax.swing.JPanel;  
    import javax.swing.JFrame;  
    import javax.swing.JLabel;  
    import javax.swing.JButton;  
    import java.awt.event.ActionEvent;  
    
    public class CustomDialogSearch extends JDialog implements ActionListener {  
        private JPanel myPanel = null;  
        private JButton yesButton = null;  
        private JButton noButton = null;  
        private boolean answer = false;  
        public boolean getAnswer() { return answer; }  
    
        public CustomDialogSearch(JFrame frame, boolean modal, String myMessage) {  
            super(frame, modal);  
            myPanel = new JPanel();  
            getContentPane().add(myPanel);  
            myPanel.add(new JLabel(myMessage));  
            yesButton = new JButton("Yes");  
            yesButton.addActionListener(this);  
            myPanel.add(yesButton);   
            noButton = new JButton("No");  
            noButton.addActionListener(this);  
            myPanel.add(noButton);    
            pack();  
            setLocationRelativeTo(frame);  
            setVisible(true);  
        }  
    
        public void actionPerformed(ActionEvent e) {  
            if(yesButton == e.getSource()) {  
                System.err.println("Search User chose yes.");  
                answer = true;  
                //setVisible(false);  
            }  
            else if(noButton == e.getSource()) {  
                System.err.println("Search User chose no.");  
                answer = false;  
                setVisible(false);  
            }  
        }  
    
    } 
    
    我甚至尝试将CustomDialogSearch的父级设置为CustomDialog 行为仍然不正确

    我认为你在这里是正确的,但是你需要使用对话框。例如:

    • 将自定义对话框主(“父”对话框)的模态类型设置为。当此对话框可见时,执行此操作将阻止除其子窗口以外的所有窗口
    • 将自定义对话框搜索(“子”对话框)的模态类型设置为。这样它就不会阻塞任何其他窗口,您可以从子窗口转到父窗口,反之亦然
    为了更好地理解,请参阅本文

    例子 下面是一个关于使用模态的代码示例,正如我上面所建议的:

    import java.awt.Dialog;
    import java.awt.Window;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.JDialog;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    
    public class Demo {
    
        private void createAndShowGUI() {
            JButton button = new JButton("Create Parent modal dialog");
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JButton button = (JButton)e.getSource();
                    JFrame owner = (JFrame)SwingUtilities.windowForComponent(button);
                    Demo.this.createAndShowParentDialog(owner);                
                }
            });
    
            JFrame frame = new JFrame("Demo");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.getContentPane().add(button);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        private void createAndShowParentDialog(JFrame owner) {
            JButton button = new JButton("Create Child non-modal dialog");
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JButton button = (JButton)e.getSource();
                    JDialog parent = (JDialog)SwingUtilities.windowForComponent(button);
                    Demo.this.createAndShowChildrenDialog(parent);                
                }
            });
    
            JDialog parentDialog = new JDialog(owner, "Parent dialog");
            parentDialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
            parentDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            parentDialog.getContentPane().add(button);
            parentDialog.pack();
            parentDialog.setLocationRelativeTo(null);        
            parentDialog.setVisible(true);
        }
    
        private void createAndShowChildrenDialog(JDialog parent) {        
            JButton backButton = new JButton("Back to parent dialog");
            backButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JButton button = (JButton)e.getSource();
                    Window dialog = SwingUtilities.windowForComponent(button);
                    dialog.getOwner().toFront();
                }
            });
    
            JDialog childDialog = new JDialog(parent, "Child dialog");
            childDialog.setModalityType(Dialog.ModalityType.MODELESS);
            childDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            childDialog.getContentPane().add(backButton);
            childDialog.pack();
            childDialog.setLocationRelativeTo(null);        
            childDialog.setVisible(true);
        }
    
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new Demo().createAndShowGUI();
                }
            });
        }    
    }
    
    编辑 我可以选择父JDialogs和子JDialogs的窗口,但当我 选择父JDialog窗口,子JDialog仍在前面 父JDialog的

    我现在对问题有了更好的理解。此行为取决于本机窗口系统处理聚焦窗口和活动窗口的方式。话虽如此,例如,如果调用,它将尝试将窗口置于堆栈顶部,但某些平台不允许拥有其他窗口的窗口出现在其子窗口顶部。调用方法时也会发生同样的情况。有关更多详细信息,请参阅javadocs


    我已经在Windows7上测试了我的代码(32位,如果它有什么不同的话),父对话框变成了焦点,但是它的子对话框仍然显示在顶部(没有焦点)。如上所述,如何处理此问题取决于窗口系统。

    我在您的代码中也看到了相同的行为。即使在我们提到这个对话框之后,子JDialog也不会返回到父JDialog。我可以选择父JDialog和子JDialog的窗口,但是当我选择父JDialog窗口时,子JDialog仍然在父JDialog的前面。这与我将CustomDialogSearch的父级设置为CustomDialogSearch时观察到的行为相同谢谢您的详细解释。