gpt4 book ai didi

java - 在 SwingWorker.execute() 之后执行代码...在它之后

转载 作者:行者123 更新时间:2023-12-01 11:00:07 24 4
gpt4 key购买 nike

在我的应用程序中,我想做类似的事情

  • 显示一个等待对话框,其中一些准备任务正在后台进行
  • 完成准备任务后,关闭对话框
  • 当对话框关闭时(或 SwingWorker.done(),执行我的其余代码)

我开始注意到问题:代码之后我的new WaitScreen().execute();正在之前执行,我有手动关闭对话框以触发 done()

为了尝试理解它,我拿了一些 simpler code ,将其制作为我自己的,并用它来模拟我的问题。这是:

导入java.awt.EventQueue;导入 java.awt.BorderLayout;

import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIManager;

public class SwingWorkerDialogTest
{

public static void main(String[] args)
{
new SwingWorkerDialogTest();
}
private JDialog dialog;

public SwingWorkerDialogTest()
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex)
{

}
catch (javax.swing.UnsupportedLookAndFeelException ex)
{

}

MyWorker worker = new MyWorker(true);
worker.execute();
new MyWorker(false).execute();
}
});
}

public class MyWorker extends SwingWorker<Object, Object>
{
private boolean runGUI;
public MyWorker(boolean b) { this.runGUI = b; }
@Override
protected Object doInBackground() throws Exception
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
if (runGUI)
{
getDialog().setVisible(true);
}
else
{
for (int j = 0; j < 30; j++)
{
System.out.println("j == " + j);
}
}
}
});
Thread.sleep(20000);
return null;
}

@Override
protected void done()
{
System.out.println("now in done...");
JDialog dialog = getDialog();
// Don't care, dismiss the dialog
//dialog.setVisible(false);
dialog.dispose();
}

}

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;
}

}

当只有 worker 运行时,它工作正常。但是,当我 execute()d 另一个 MyWorker 时,我的问题又出现了。我该如何解决这个问题?

最佳答案

因此,SwingWorker 的目的是允许您在事件调度线程上下文之外的后台线程中执行长时间运行/阻塞的任务,因此您不会阻塞用户界面。

the code after my new WaitScreen().execute(); was being executed before it and I had to manually close the dialog to trigger the done()

是的,这是预料之中的,这就是 SwingWorker 的全部意义。发生的情况是,当您调用执行创建一个新的Thread时,它会(间接)调用您的doInBackground方法,同时,所有允许其他线程(如 EDT)继续运行。

SwingWorker 中使用 SwingUtilities.invokeLater 也是毫无意义的,该工作线程旨在提供功能,以便轻松地将更新发送回 EDT。

好吧,就您的情况而言,一个简单的解决方案是首先调用execute,然后立即显示对话框,从而阻止此时的代码执行,例如...

import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIManager;

public class SwingWorkerDialogTest {

public static void main(String[] args) {
new SwingWorkerDialogTest();
}
private JDialog dialog;

public SwingWorkerDialogTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) {

} catch (javax.swing.UnsupportedLookAndFeelException ex) {

}

MyWorker worker = new MyWorker(true);
worker.execute();
new MyWorker(false).makeItSo();
System.out.println("I'm free !");
}
});
}

public class MyWorker extends SwingWorker<Object, Object> {

private boolean runGUI;

public MyWorker(boolean b) {
this.runGUI = b;
}

public void makeItSo() {
execute();
getDialog().setVisible(true);
}

@Override
protected Object doInBackground() throws Exception {
for (int j = 0; j < 30; j++) {
System.out.println("j == " + j);
Thread.sleep(10);
}
Thread.sleep(20000);
return null;
}

@Override
protected void done() {
System.out.println("now in done...");
JDialog dialog = getDialog();
// Don't care, dismiss the dialog
//dialog.setVisible(false);
dialog.dispose();
}

}

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;
}

}

关于java - 在 SwingWorker.execute() 之后执行代码...在它之后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33406447/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com