我必须通过按钮同步两个数据库。在Button下,我在JScrollPanel中有一个JTextPane。我的TextPane类看起来像:
public class InfoArea extends JTextPane {
private final HTMLEditorKit kit = new HTMLEditorKit();
private final HTMLDocument doc = new HTMLDocument();
private static ia;
public static InfoArea getInfoArea {
if (ia == null) ia = new InfoArea();
return ia;
}
private InfoArea() {
setEditorKit(kit);
setDocument(doc);
showInfo("Please wait...");
setEditable(false);
}
public void showInfo(String msg) {
try {
kit.insertHTML(doc, doc.getLength(), "<b><font color=\"#00AA00\">" + msg + "</font></b>", 0, 0, null);
} catch (BadLocationException | IOException e) {
e.printStackTrace();
}
}
}
&#34; TextPane&#34;在GUI中添加到SOUTH。
现在我有几个课程:
private static final InfoArea ia = InfoArea.getInfoArea();
首先,我初始化数据库连接。因为这样做非常快,所以信息会立刻显示出来。但后来我做了这样的事情:
private void doSmth() {
for(int i = 0; i < smth; ++i) {
if(sync()) ia.showInfo("OK");
else ia.showInfo("Not OK");
}
}
在其他类中,结果集可能需要一段时间。问题是,在每个方法运行之前,文本窗格不会更新。我对这种行为很反感,我知道问题在于事件调度程序线程(EDT)。我尝试更新showInfo(String msg),如下所示:
private void showInfo(String msg) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
kit.insertHTML(doc, doc.getLength(), msg, 0, 0, null);
} catch (BadLocationException | IOException e) {
e.printStackTrace();
}
}
});
}
但这不是诀窍。我也尝试过覆盖doInBackground(),publish()和process()的SwingWorker但也没有成功。我还尝试了一个工作线程而不是SwingUitilities。最后我试过了:
private void doSmth() {
for(int i = 0; i < smth; ++i) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if(sync()) ia.showInfo("OK");
else ia.showInfo("Not OK");
}
});
}
}
没有成功。另外我相信这次尝试是最糟糕的,因为它阻止了EDT。
你可能会注意到,我现在有点绝望,因为我不知道在哪里看别的。抱歉没有发布SwingWorker和WorkerThreads的所有尝试,但他们会炸毁这篇文章。它已经够大了。
有人可以告诉我,我需要做些什么才能让它发挥作用?对于希望在同步过程运行时看到某些内容的客户,我需要它。如果缺少某些东西,我也愿意提供更多信息。
答案 0 :(得分:0)
自己解决了。我误解了昨天发的一些文章。解决方案是将整个任务放在一个线程中,而不仅仅是输出的方法。
正如我所说,我单击一个按钮开始同步过程。该按钮只调用一个方法:
public void syncDB() {
ia.showInfo("Sync cat...");
doCatSync();
ia.showInfo("Sync item...");
doItemSync();
...
}
现在我必须围绕任务包装一个线程:
public void syncDB() {
new Thread() {
public void run() {
ia.showInfo("Sync cat...");
doCatSync();
ia.showInfo("Sync item...");
doItemSync();
...
}
}.start();
}
这就是诀窍。我总是乐于改进。