在SwingWorker在Java中完成后启动另一个线程
我知道有很多问题,但没有一个有足够好的答案,在这里问之前,我专门搜索了很多,但没有什么能说清楚。我只是想在我的SwingWorker完成它的工作时启动另一个线程 我想在SwingWorker完成工作后启动计时器,但不知道如何启动在SwingWorker在Java中完成后启动另一个线程,java,multithreading,swing,swingworker,Java,Multithreading,Swing,Swingworker,我知道有很多问题,但没有一个有足够好的答案,在这里问之前,我专门搜索了很多,但没有什么能说清楚。我只是想在我的SwingWorker完成它的工作时启动另一个线程 我想在SwingWorker完成工作后启动计时器,但不知道如何启动 class createGUI extends SwingWorker<Void, Void> { @Override protected Integer doInBackground() throws Exception {
class createGUI extends SwingWorker<Void, Void>
{
@Override
protected Integer doInBackground() throws Exception
{
//Some long processing
}
@Override
protected void done()
{
//Doing GUI work here
prgBar.setInderminent(false);
}
}
//Starts a progressBar and calls createGUI();
prgBar.setInderminent(true);
new createGUI().execute();
但是我不明白我该怎么做?除非我遗漏了什么,否则您可以在构造函数中传递一个对createGUI的引用,并在完成后启动它 差不多
new createGUI(new Thread(new startTimer())).execute();
此外,类名应以大写字母开头。CreateGUI和StartTimer除非我遗漏了什么,否则您可以将构造函数中的引用传递给CreateGUI,并在完成后启动它 差不多
new createGUI(new Thread(new startTimer())).execute();
此外,类名应以大写字母开头。CreateGUI和StartTimer注意:Elliot的答案没有错,希望它将工作流耦合到worker,并将对象引用传递给worker,否则就不需要为他的答案加上+1
作为向可能不需要知道或关心这些事情的类传递引用的替代方法,您可以使用SwingWorkers PropertyChangeListener支持
这将使worker解耦,并使其更易于重用
CreateGUI worker = new CreateGUI();
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("state".equals(evt.getPropertyName())) {
SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue();
switch (state) {
case DONE:
prgBar.setInderminent(false);
startTimer.start();
break;
}
}
}
});
worker.execute();
这将简单地运行
public class CreateGUI extends SwingWorker<Integer, Integer> {
@Override
protected Integer doInBackground() throws Exception {
// Working hard or hardly working...
return ???;
}
}
这确保了StartTimer在CreateGUI完成或失败之前无法运行…注意:Elliot的答案没有错,希望它将工作流耦合到worker,并将对象引用传递给worker,否则就不需要+1作为他的答案
作为向可能不需要知道或关心这些事情的类传递引用的替代方法,您可以使用SwingWorkers PropertyChangeListener支持
这将使worker解耦,并使其更易于重用
CreateGUI worker = new CreateGUI();
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("state".equals(evt.getPropertyName())) {
SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue();
switch (state) {
case DONE:
prgBar.setInderminent(false);
startTimer.start();
break;
}
}
}
});
worker.execute();
这将简单地运行
public class CreateGUI extends SwingWorker<Integer, Integer> {
@Override
protected Integer doInBackground() throws Exception {
// Working hard or hardly working...
return ???;
}
}
这将确保StartTimer在CreateGUI完成或失败之前无法运行…这将在CreateGUI启动后立即启动StartTimer线程,但我希望StartTimer在Swingworker启动时启动finished@JavaDrunk否。这将在执行完的方法结束时启动startTimer线程。线程只有在调用start时才会开始。如果您不想以不同的方式重复使用SwingWorker,可以将PropertyChangeListener附加到SwingWorker并监视state属性,作为替代方案…@MadProgrammer我不确定,但是在SwingWorker上附加一个PropertyChangeListener会不会比Elliott建议的有点长?我很惊讶Elliott给出了完美的解决方案,而且效果很好。我尝试了我的袖子的每一个技巧,但我能想到这一点。非常感谢埃利奥特真的很有帮助。非常感谢。这将在createGUI启动后立即启动startTimer线程,但我希望startTimer在Swingworker启动时启动finished@JavaDrunk否。这将在执行完的方法结束时启动startTimer线程。线程只有在调用start时才会开始。如果您不想以不同的方式重复使用SwingWorker,可以将PropertyChangeListener附加到SwingWorker并监视state属性,作为替代方案…@MadProgrammer我不确定,但是在SwingWorker上附加一个PropertyChangeListener会不会比Elliott建议的有点长?我很惊讶Elliott给出了完美的解决方案,而且效果很好。我尝试了我的袖子的每一个技巧,但我能想到这一点。非常感谢埃利奥特真的很有帮助。非常感谢。如果不希望UI冻结,可能需要执行另一个SwingWorker,因为更新数据库是一项很长的操作。您可以在第二个SwingWorker开始时启动计时器,并在第二个SwingWorker完成时停止/取消该计时器。是的,但我怎么知道何时启动第二个SwingWorker或线程呢?在第一个SwingWorker的完成方法末尾。如果不希望UI冻结,您可能需要执行另一个SwingWorker,因为更新数据库是一项很长的操作。您可以在第二个SwingWorker开始时启动计时器,并在第二个SwingWorker完成时停止/取消计时器。是的,但我怎么知道何时启动第二个SwingWorker或线程呢?在第一个SwingWorker的完成方法末尾。哇,这是另一个很好的解决方案,因为我可以看到它在某些情况下非常方便好我必须感谢你的榜样。一如既往地爱你。我已经是你的超级粉丝了。当设置ProgressBar和determinent属性时,它会非常有用。非常感谢ManWOW,这是另一个很棒的解决方案,因为我可以看到它在某些情况下也很方便。我必须感谢你的榜样。一如既往地爱你。我已经是你的忠实粉丝了。这会很有帮助的 l使用determinent属性设置ProgressBar时。谢谢你,伙计
ExecutorService es = Executors.newSingleThreadExecutor();
es.submit(new CreateGUI());
es.submit(new StartTimer());
es.shutdown();