我有一个JTabbedpane面板,在每个选项卡中可以设置参数以执行查询。当一个查询忙于从数据库中检索他的数据时,您可以打开一个新选项卡来设置新的参数。为避免数据库过载,只能同时执行一个查询。但是当你点击执行时,程序必须记住哪些查询以正确的顺序执行。在执行过程中,显示一个加载器图标,并且可能不会冻结GUI,因为有一个停止按钮可以单击以停止执行。
我使用了一个swingworker来避免GUI在执行查询时被阻塞,并且工作正常。但是现在我想阻止下一个查询在前一个查询完成之前启动。在模型中,共同为整个面板,我初始化一个信号:private final Semaphore semaphore = new Semaphore(1, true);
这是开始的SwingWorker的代码(我已经添加的println命令来查看相应地开始,停止或完成)依次使用信号量运行swingworkers
private void doStoredQuery() {
try {
semaphore.acquire();
System.out.println(queryName + "started");
worker.execute();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
,这是我的SwingWorker(initializeWorker()从主类的构造函数调用):
private SwingWorker<StoredQueryDataModel, Integer> initializeWorker() {
worker = new SwingWorker<StoredQueryDataModel, Integer>() {
@Override
protected StoredQueryDataModel doInBackground() throws Exception {
try {
StoredQueryDataModel dataModel = null;
publish(0);
try {
dataModel = new StoredQueryDataModel(queryRunner, ldbName, queryName, params);
} catch (S9SQLException e) {
//
} catch (Throwable e) {
showErrorMessage(e);
}
return dataModel;
}
finally {
semaphore.release();
System.out.println(queryName + "finished");
}
}
@Override
protected void process(List<Integer> chunks) {
//ignore chunks, just reload loader icon
panel.repaint();
}
@Override
protected void done() {
String error;
try {
result = get();
error = null;
} catch (Exception e) {
error = e.getMessage();
}
if(result == null) {
semaphore.release();
System.out.println(queryName + " stopped");
}
if(error == null) {
// process result
}
else {
showErrorMessage(new Throwable(error));
}
}
};
return worker;
}
我试图把获取和释放在代码的其他位置,但似乎没有任何工作。我在Swingworker和sempahores bot很新...有人可以帮忙吗?