Java 安全地打开和关闭模态JDialog(使用SwingWorker)
我需要一种方法从数据库中获取一些数据,并防止用户在此时修改现有数据 我创建了一个SwingWorker来更新数据库,并创建了一个模态JDialog来向用户显示正在发生的事情(使用JProgressBar)。模态对话框的defaultCloseOperation设置为“不做任何事情”,因此只能通过正确的调用关闭它-我使用Java 安全地打开和关闭模态JDialog(使用SwingWorker),java,multithreading,swing,jdialog,swingworker,Java,Multithreading,Swing,Jdialog,Swingworker,我需要一种方法从数据库中获取一些数据,并防止用户在此时修改现有数据 我创建了一个SwingWorker来更新数据库,并创建了一个模态JDialog来向用户显示正在发生的事情(使用JProgressBar)。模态对话框的defaultCloseOperation设置为“不做任何事情”,因此只能通过正确的调用关闭它-我使用setVisible(false) SwingWorker在doInBackground()中执行一些操作,最后调用: myModalDialog.setVisible(false
setVisible(false)
SwingWorker在doInBackground()中执行一些操作,最后调用:
myModalDialog.setVisible(false);
我唯一关心的问题是:
SwingWorker是否可能在工作人员繁殖后的行中执行setVisible(false)
之前执行setVisible(true)
如果是这样,setVisible(true)
可能会永远阻塞(用户无法关闭模式窗口)
我是否必须实施以下措施:
while (!myModalDialog.isVisible()) {
Thread.sleep(150);
}
myModalDialog.setVisible(false);
要确保它确实会关闭?一般来说,是的
我要做的是在你的doInBackground
方法中使用SwingUtilities.invokeLater
来显示对话框,在你的done
方法中隐藏对话框
这应该意味着,即使对话框没有进入屏幕,您也可以对流程获得更多的控制
小问题是你现在必须将对话框传递给工人,这样工人才能控制它
public class TestSwingWorkerDialog {
public static void main(String[] args) {
new TestSwingWorkerDialog();
}
private JDialog dialog;
public TestSwingWorkerDialog() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
MyWorker worker = new MyWorker();
worker.execute();
}
});
}
public class MyWorker extends SwingWorker<Object, Object> {
@Override
protected Object doInBackground() throws Exception {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
getDialog().setVisible(true);
}
});
Thread.sleep(2000);
return null;
}
@Override
protected void done() {
System.out.println("now in done...");
JDialog dialog = getDialog();
// Don't care, dismiss the dialog
dialog.setVisible(false);
}
}
protected JDialog getDialog() {
if (dialog == null) {
dialog = new JDialog();
dialog.setModal(true);
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.setLayout(new BorderLayout());
dialog.add(new JLabel("Please wait..."));
dialog.setSize(200, 200);
dialog.setLocationRelativeTo(null);
}
return dialog;
}
}
公共类TestSwingWorkerDialog{
公共静态void main(字符串[]args){
新的TestSwingWorkerDialog();
}
专用JDialog对话框;
公共测试SwingWorkerDialog(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}捕获(ClassNotFoundException ex){
}catch(实例化异常){
}捕获(非法访问例外){
}捕获(无支持的LookandFeelexception ex){
}
MyWorker=新的MyWorker();
worker.execute();
}
});
}
公共类MyWorker扩展SwingWorker{
@凌驾
受保护对象doInBackground()引发异常{
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
getDialog().setVisible(true);
}
});
《睡眠》(2000年);
返回null;
}
@凌驾
受保护的void done(){
System.out.println(“现在完成…”);
JDialog dialog=getDialog();
//别在意,取消对话
对话框.setVisible(false);
}
}
受保护的JDialog getDialog(){
如果(对话框==null){
dialog=newjdialog();
dialog.setModal(true);
setDefaultCloseOperation(JDialog.DO\u NOTHING\u ON\u CLOSE);
setLayout(新的BorderLayout());
添加(新的JLabel(“请稍候…”);
对话框。设置大小(200200);
对话框.setLocationRelativeTo(空);
}
返回对话框;
}
}
您应该调用mymodaldiallog.setVisible(false)代码>在done()
中,而不是doInBackground()
。为什么不在执行之前调用setVisible(true)
?setVisible(true)是一个阻塞调用哈哈-非常好的观点:-)为了更快地获得更好的帮助,发布一个。好的,我会再试一次。感谢您的done()技巧。SwingUtilities.invokeLater
和EventQueue.invokeLater
之间有什么区别?如果我的问题很傻,很抱歉,但在您的示例中,可以保证invokeLater的run方法一定会在工作完成之前运行()?在我看来,我这篇文章的主要问题仍然存在——理论上不确定的并发性,但我可能是错的。@M.M.没有。SwingUtilities.invokeLater将调用转发给EventQueue.invokeLater@user1713059这样做的目的是保证1。该对话框将仅在工作程序启动和2之后打开。在工作完成之前不会关闭(或试图关闭)。因为done方法是在EDT的上下文中执行的,使用了与我打开它类似的方法,所以open事件将在关闭之前执行,因为它首先被添加到队列中。@我在这里得到了一个关于这一点的精度:
public class TestSwingWorkerDialog {
public static void main(String[] args) {
new TestSwingWorkerDialog();
}
private JDialog dialog;
public TestSwingWorkerDialog() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
MyWorker worker = new MyWorker();
worker.execute();
}
});
}
public class MyWorker extends SwingWorker<Object, Object> {
@Override
protected Object doInBackground() throws Exception {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
getDialog().setVisible(true);
}
});
Thread.sleep(2000);
return null;
}
@Override
protected void done() {
System.out.println("now in done...");
JDialog dialog = getDialog();
// Don't care, dismiss the dialog
dialog.setVisible(false);
}
}
protected JDialog getDialog() {
if (dialog == null) {
dialog = new JDialog();
dialog.setModal(true);
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.setLayout(new BorderLayout());
dialog.add(new JLabel("Please wait..."));
dialog.setSize(200, 200);
dialog.setLocationRelativeTo(null);
}
return dialog;
}
}