我正在用Java的swing库构建一个用户界面,但是我遇到了一个问题。
当在长方法中更新文本区域时,在方法运行时有一个暂停,然后文本区域一次更新,而不是一次更新一点点。
我设法解决了这个问题,使用一个新的线程在以下方式:
private void jButtonActionPerformed(java.awt.event.ActionEvent evt) {
Thread x = new Thread() {public void run() {
// do things that update a text area
}}; x.start();
}
这对于文本区域的小块更新是完美的,而不是一次全部更新。
然而,唯一的问题是这个方法只能被调用一次,否则Java会崩溃。我读到这与只能创建线程一次有关。如何修改代码以保持所需的功能?嗯,我怀疑你的代码崩溃是因为Thread
的创建,因为每次方法被调用,你正在创建一个新的Thread
(你不能重新启动一个已经启动的Thread
的现有实例(即使它已经完成或没有)),可能的原因是你得到一个并发修改异常,因为Swing不是线程安全的…
可能最简单的解决方案是使用SwingWorker
,它将允许您在后台执行长时间运行的任务,但通过publish
, process
和done
方法提供易于使用的功能来安全地更新UI。
为了防止可能的问题,你也可以考虑禁用按钮,直到加载操作完成,这将防止人们破坏按钮产生多个后台进程…
你可以创建一个新的线程对象,覆盖所有可运行的方法。
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Executed..*****");
}
}).start();
试试这个。
为了便于比较,这里有一个使用swingutility . invokelater的例子。我赞同MadProgrammer的建议,从长远来看,学习SwingWorker 会更有益,并提供更好的变量处理。
newGame.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent arg0) {
panelList.get("newGame").setEnabled(false);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// this is where the heavy processing occurs
newGameButton();
// re-enables the button afterwards
panelList.get("newGame").setEnabled(true);
}
});
}
});
而且,一旦您的代码工作得更好,您可能就可以寻找优化更新速度的方法(即使在处理Swing对象时也是如此)。上面的调用过去挂起一秒钟左右,但我已经得到了大约50 - 100ms左右的延迟与模型上的进一步工作:)