【发布时间】:2016-08-23 08:38:56
【问题描述】:
我使用了一个扩展 SwingWorker 的类,如下所示:
public class Analyzer extends SwingWorker<Integer, Object> {
String source;
public Analyzer(String simulation, DBConnector connection)
throws ClassNotFoundException, SQLException, IOException {
super();
source=simulation;
//creating several objects that get their data from a DB and will be "analyzed" in the background
}
@Override
protected Integer doInBackground() {
tripAnalyzer ta = new tripAnalyzer();
if (trips.getIterator().hasNext()) {
if (isCancelled()) {
trips.close();
ta.cancelFinish();
return FAILED;
}
ta.init(null, null, false);
while (trips.getIterator().hasNext()) {
setProgress(trips.getProgress());
ta.prepare(source, trips.getIterator().next());
}
//export the results to a text-file
return SUCCESS;
}
}
@Override
protected void done() {
setProgress(100);
trips.close();
super.done();
}
}
模拟的String值来自一个JTable。到目前为止,对于一个“模拟键”来说一切正常,但现在我想扩展它以便能够为几个“模拟键”做 Worker 的东西。 我想到的一种方法可能是使用模拟键传递一个数组或字符串列表,并适当地更改构造函数。但这将变得非常笨拙,因为我必须在构造函数的执行期间创建大量对象,并且要处理大量数据。我还可以专门为字符串数组创建一个单独的构造函数,但这将是大约 60 行代码的复制/粘贴,并且会出现结块问题。
我的想法是在对之前的模拟进行分析后,使用不同的模拟键重新实例化 Analyzer 类。 (是的,我知道在 EDT 期间多次实例化同一个 SwingWorker 不会多次调用 doInBackground 方法。但是一旦完成并摆脱困境,它应该可以工作......至少在我的脑海中:))。但是现在我碰壁了,真的不知道该怎么做。
工作流程应该是这样的:
1:我选择 f.ex。存储在数组或列表中的 JTable 中的 3 个模拟键 [1,2,3]
2:然后 Worker 从我的 GUI 类中实例化,并在第一个键(即 '1')上完成他的工作
3:在“1”上的工作完成后,工人应该被重新实例化并开始在“2”上工作
4:以此类推,直到处理完所有模拟密钥。
也许我的想法太僵硬了,有更好的方法来实现这一点,因此任何能帮助我指出正确方向的帮助都将不胜感激!谢谢
编辑
public Analyzer(String simulation, DBConnector connection){
this(new String[]{simulation}, connection);
source = simulation;
}
public Analyzer(String[] simulation, DBConnector connection){
super();
for( String s : simulation) this.simulations.add(s);
this.connection = connection;
}
正如下面的 cmets 中所述,不需要 publish() 方法,因为状态栏会正确更新。
我放置所有键的列表是一个 LinkedList,它在每个循环周期中都会删除一个键,直到它为空。
【问题讨论】:
-
为什么不循环遍历
doInBackground()和publish()中的List<Key>一个中间结果,因为每个都结束了? -
@trashgod 事情是我继承了这个项目,我不想更改类的签名,因为最初编写它的人将所有 PreparedStatements 以及“trips”放在构造函数中目的。 I didn't want to create lets say 20 "trips" objects when 20 simulations are selected... One simulation consists of more than 2million households with more than 20million trips.我已经有了将所有内容放入“doInBackgroung()”的想法。但不幸的是,我也必须适应其他课程。
-
对不起,如果我遗漏了什么,但实际的泛型参数
Object未使用;影响似乎很小。另请参阅approach 了解非顺序任务。 -
@trashgod 另一方面,我现在正在考虑将数据库内容放入
doInBackground()方法并设置2个构造函数......一个用于字符串变量,一个用于列表,让doInBackGround()处理剩下的。那可以解决。我应该把publish()方法放在哪里?在迭代块结束时? -
@trashgod 它有效。我将所有繁重的 DB 代码放入
doInBackground()方法中,并添加了一个额外的构造函数,该构造函数采用 StringArray。我会将其作为编辑放入帖子中。我什至不必打电话给publish()