如何制作setVisible块的非模态对话框?

Joo*_*kka 2 java swing visibility dialog blocking

在Swing(J)对话框中,setModal设置模态 - 即对话框是否应阻止对其他窗口的输入.然后,setVisible docs说模态对话框:

如果对话框尚未显示,则在通过调用setVisible(false)或dispose隐藏对话框之前,此调用将不会返回.

实际上,如果对话框不是模态的,setVisible 它会立即返回.示例代码:

JDialog jd = new JDialog();
jd.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

/**
 * If set to false, setVisible returns right away.
 * If set to true, setVisible blocks until dialog is disposed.
 */
jd.setModal(false);

System.out.println("setting visible");
jd.setVisible(true);
System.out.println("set visible returned");
Run Code Online (Sandbox Code Playgroud)

我想创建一个阻止输入到其他窗口的对话框,但仍然阻止调用者.有什么好方法可以做到这一点,现在setVisible当对话框不是模态时不阻止?

有一些理由说明为什么 setVisible行为取决于形态?

per*_*erp 5

我需要创建一个不阻止输入到其他窗口的对话框,但会阻止调用者,以便我知道对话框何时关闭.

我通常不是通过阻止调用者来解决这个问题,而是通过使用某种类型的回调来解决这个问题 - 一个简单的接口,当对话框完成时会调用它.假设您的对话框有一个"确定"和"取消"按钮,您需要区分哪一个被按下.然后你可以做这样的事情:

public interface DialogCallback {
    void ok();
    void cancel();
}

public class MyModelessDialog extends JDialog {
    private final DialogCallback cbk;
    private JButton okButton, cancelButton;        

    public MyModelessDialog(DialogCallback callback) {
        cbk = callback;
        setModalityType(ModalityType.MODELESS);

        okButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                onOK();
            }
        };

        cancelButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                onCancel();
            }
        };

        // Treat closing the dialog the same as pressing "Cancel":
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e)  {
                onCancel();
            }
        };
    }

    private void onOK() {
        cbk.ok();
    }

    private void onCancel() {
        cbk.cancel();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你只需将DialogCallback的一个实例传递给构造函数:

MyModelessDialog dlg = new MyModelessDialog(new DialogCallback() {
    public void onOK() { 
        // react to OK
    }
    public void onCancel() { 
        // react to Cancel
    }
 });
Run Code Online (Sandbox Code Playgroud)

编辑

有没有理由说为什么setVisible的行为取决于模态?

嗯,这就是模态窗口应该如何工作,不是吗?模态窗口应该在显示时阻止当前工作流程,而非模态窗口/非模态窗口则不应该.参见例如模态窗口对话框上的维基百科页面.