java 如何制作 setVisible 块的非模态对话框?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6895265/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I make non-modal dialog whose setVisible blocks?
提问by Joonas Pulakka
In a Swing (J)Dialog, setModalsets the modality - that is, whether the dialog should block input to other windows or not. Then, setVisibledocs say for modal dialogs:
在 Swing (J)Dialog 中,setModal设置模态 - 即对话框是否应阻止对其他窗口的输入。然后,setVisible文档说模态对话框:
If the dialog is not already visible, this call will not return until the dialog is hidden by calling setVisible(false) or dispose.
如果对话框不可见,则在通过调用 setVisible(false) 或 dispose 隐藏对话框之前,此调用不会返回。
Indeed, setVisible
doesreturn right away if the dialog is not modal. Sample code:
事实上,如果对话框不是模态的,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");
I want to make a dialog that doesn'tblock input to other windows, but still doesblock the caller. What is a good way to do this, now that setVisible
doesn't block when the dialog is not modal?
我想制作一个不会阻止对其他窗口的输入的对话框,但仍然会阻止调用者。这样做的好方法是什么,现在setVisible
当对话框不是模态时不会阻塞?
Is there some rationale whysetVisible
's behavior depends on the modality?
是否有一些理由为什么setVisible
's 的行为取决于模式?
回答by perp
I need to make a dialog that doesn't block input to other windows, but does block the caller so that I know when the dialog has been closed.
我需要创建一个对话框,它不会阻止对其他窗口的输入,但会阻止调用者,以便我知道对话框何时关闭。
I usually solve this not by blocking the caller, but by using a callback of some sort - a simple interface that the dialog invokes when it's done. Let's say your dialog has an "OK" and a "Cancel" button and you need to distinguish which one is pressed. Then you could do something like this:
我通常不是通过阻止调用者来解决这个问题,而是通过使用某种回调 - 一个简单的界面,对话框在完成时调用。假设您的对话框有一个“确定”和一个“取消”按钮,您需要区分按下了哪个按钮。然后你可以做这样的事情:
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();
}
}
Then you just pass in an instance of DialogCallback to the constructor:
然后你只需将 DialogCallback 的实例传递给构造函数:
MyModelessDialog dlg = new MyModelessDialog(new DialogCallback() {
public void onOK() {
// react to OK
}
public void onCancel() {
// react to Cancel
}
});
EDIT
编辑
Is there some rationale why setVisible's behavior depends on the modality?
为什么 setVisible 的行为取决于模式有什么理由吗?
Well, that's just how how modalwindows are supposed to work, no? A modal window shouldblock the current workflow when displayed, and a non-modal/modeless should not. See e.g. the Wikipedia pages on modal windowsor dialog boxes.
嗯,这就是模态窗口应该如何工作,不是吗?模态窗口在显示时应阻止当前工作流,而非模态/无模式不应。参见例如关于模态窗口或对话框的维基百科页面。
回答by Noman_1
Just put this.setModal(true)
but not set the parent dialog on the constructor:
只需this.setModal(true)
在构造函数上放置但不设置父对话框:
MyDialog dlg = new JDialog();
MyDialog dlg = new JDialog();
this.setModal(true);
this.setModal(true);
When you call setVisible(true)
, it wont stop
当你打电话时setVisible(true)
,它不会停止
回答by Karthi
The direct approach is by:
直接的方法是:
JDialog dialog = new JDialog(owner, ModalityType.DOCUMENT_MODAL);
回答by JC Wouters
I have found another way to do this. In the constructor of my progress bar, which extends javax.swing.JDialog, I added:
我找到了另一种方法来做到这一点。在我的进度条的构造函数中,它扩展了 javax.swing.JDialog,我添加了:
setModalityType(ModalityType.APPLICATION_MODAL);
I then overrode the setVisible method:
然后我覆盖了 setVisible 方法:
@Override
public void setVisible(boolean b) {
if (b) {
new Thread(new Runnable() {
@Override
public void run() {
showProgress();
}
}).start();
} else {
super.setVisible(false);
}
}
In the run(), you can see a call to showProgress(). This simply is:
在 run() 中,您可以看到对 showProgress() 的调用。这简直是:
public void showProgress() {
super.setVisible(true);
}
What happens here, is the setVisible() method of JDialog blocks. So I overrode it, and called setVisible() of the JDialog, in a thread. Resulting in it not blocking.
这里发生的是 JDialog 块的 setVisible() 方法。所以我覆盖了它,并在一个线程中调用了 JDialog 的 setVisible()。导致它没有阻塞。