setModal在Jframe中有2个Jdialogs问题

时间:2014-02-26 09:52:28

标签: java swing modal-dialog jframe jdialog

当我设置第一个JDialog模态而第二个非模态时,我遇到了问题。

这是我试图实现的功能:

  1. 点击“测试对话框!”按钮,名为自定义对话框的JDialog将会打开。
  2. 如果在自定义对话框主中单击“是”选项,则另一个 名为自定义对话框搜索JDialog将会打开。
  3. 如果在自定义对话框搜索中单击“是”选项,则 自定义对话框主应该在前面。
  4. 我应该可以选择任何JDialog。例如,如果我选择 自定义对话框搜索,另一个对话框应该去 反之亦然。
  5. 我面临的问题是当我在自定义对话框主中单击“是”时,主对话框后面会显示自定义对话框搜索

    这种情况正在发生,因为我正在设置自定义对话框搜索非模态。 如果我这个对话框模式它正确显示但是在我点击“是”之后自定义对话框主不在前面。

    我甚至试图将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);  
            }  
        }  
    
    } 
    

1 个答案:

答案 0 :(得分:3)

  

我甚至尝试将CustomDialogSearch的父级设置为CustomDialog   行为仍然不正确。

我认为你在这里正确,但你需要使用对话框模态类型。例如:

  • 自定义对话框主(“父”对话框)的模态类型设置为Dialog.ModalityType.APPLICATION_MODAL。通过此对话框可见时,它将阻止除其子项之外的所有窗口。
  • 自定义对话框搜索(“子”对话框)的模态类型设置为Dialog.ModalityType.MODELESS。这样它就不会阻挡任何其他窗口,你可以从孩子到父母,反之亦然。

为了更好地理解,请查看How to Use Modality in Dialogs文章。

实施例

以下是关于使用模态的代码示例,如上所述:

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的窗口,但是当我   选择父JDialog窗口,子JDialog仍在前面   父JDialog。

我现在对问题有了更好的了解。此行为取决于本机窗口系统如何处理聚焦和活动窗口。如果您调用实例toFront(),它会尝试将窗口放在堆栈的顶部但是某些平台不允许拥有其他窗口的窗口显示在其子代之上。调用toBack()方法时会发生同样的情况。有关详细信息,请参阅javadoc。

我已经在Windows 7上测试了我的代码(32位,如果它有任何区别)并且父对话框变得集中,但它的孩子仍然在顶部显示(没有聚焦)。如上所述,窗口系统决定如何处理这个问题。