如何链式调用带条件/可选分支的多个SwingWorker?
带条件分支的SwingWorker链式调用最佳实现方案
我有一个大型后台任务,其中存在需要用户输入的中间节点。例如:buttonLoad_actionPerformed → 加载、验证有效性 → 若内容过时,询问用户是否更新;是则执行更新,否则终止。
目前我编写的代码如下:
// load worker SwingWorker<Status,Object> swLoad=new SwingWorker<> () { Validity doInBackGround() { return load(file); } void done() { Validity validity=get(); switch (validity) { case UPTODATE: return; case OUTDATED: int res=JOptionPane.showConfirmDialog("File obsolete. Do you want to update it ?"); if (res != JOptionPane.YES_OPTION) return; // update worker SwingWorker<Boolean,Object> swUpdate = new SwingWorker<>() { Boolean doInBackGround() { return update(); } void done() { Boolean success=get(); if (!success) .... } }; swUpdate.execute(); } } }; swLoad.execute();
但当存在多步骤时,这种写法可读性会变得很差。请问链式调用带条件/可选分支的SwingWorker的最佳实现方案是什么?
解决方案:拆分职责+回调解耦
核心思路是避免嵌套匿名内部类,将每个后台任务封装为独立的SwingWorker子类,通过回调接口解耦任务间的依赖关系,让流程逻辑更清晰。
1. 封装独立的任务Worker类
将加载、更新等单一职责的任务拆分为独立类,每个类只负责自身的后台操作,并通过回调传递执行结果:
import java.util.function.Consumer; import java.util.function.Runnable; import javax.swing.SwingWorker; import javax.swing.JOptionPane; // 加载任务:负责文件加载与有效性验证 class LoadWorker extends SwingWorker<Validity, Object> { private final File file; private final Consumer<Validity> onComplete; public LoadWorker(File file, Consumer<Validity> onComplete) { this.file = file; this.onComplete = onComplete; } @Override protected Validity doInBackground() throws Exception { // 后台执行加载逻辑 return load(file); } @Override protected void done() { try { // 将结果传递给回调 Validity validity = get(); onComplete.accept(validity); } catch (Exception e) { // 统一处理后台任务异常 JOptionPane.showMessageDialog(null, "加载失败:" + e.getMessage()); e.printStackTrace(); } } } // 更新任务:负责文件更新操作 class UpdateWorker extends SwingWorker<Boolean, Object> { private final Runnable onSuccess; private final Runnable onFailure; public UpdateWorker(Runnable onSuccess, Runnable onFailure) { this.onSuccess = onSuccess; this.onFailure = onFailure; } @Override protected Boolean doInBackground() throws Exception { // 后台执行更新逻辑 return update(); } @Override protected void done() { try { Boolean success = get(); if (success) { onSuccess.run(); } else { onFailure.run(); } } catch (Exception e) { onFailure.run(); JOptionPane.showMessageDialog(null, "更新失败:" + e.getMessage()); e.printStackTrace(); } } }
2. 线性编排任务流程
在事件触发点(如按钮点击),通过回调串联各个任务和用户交互逻辑,代码结构更直观:
buttonLoad.addActionListener(e -> { // 第一步:执行加载任务 new LoadWorker(file, validity -> { switch (validity) { case UPTODATE: JOptionPane.showMessageDialog(null, "文件已是最新状态"); break; case OUTDATED: // 询问用户是否更新 int res = JOptionPane.showConfirmDialog(null, "文件已过时,是否更新?"); if (res == JOptionPane.YES_OPTION) { // 第二步:执行更新任务 new UpdateWorker( () -> JOptionPane.showMessageDialog(null, "更新成功"), () -> JOptionPane.showMessageDialog(null, "更新失败,请重试") ).execute(); } break; } }).execute(); });
3. 扩展多步骤场景
如果后续需要新增更多步骤(比如更新后再校验、通知用户),只需新增对应的Worker类,在回调中继续串联即可,完全不需要修改原有任务类,符合开闭原则。
内容的提问来源于stack exchange,提问作者lvr123
相关产品推荐
相关产品推荐

