我有一个小问题,现在我必须在一个小的Java项目上工作。我尝试从按钮事件处理程序中运行几个线程;然后最后一个线程必须更新UI上的TextArea。线程正在做计算的工作。最重要的部分是让UI正常工作-我不想冻结UI,当然我想定期从其他线程(而不是ui的线程)更新ui的TextArea。下面是我的代码的一部分:
在Button的事件处理程序中,我启动了这4个线程:
Thread generate = new CombinaMaker();
generate.run();
Thread forward = new TranslateForward();
forward.run();
Thread backward = new TranslateBackward();
backward.run();
Thread refresh = new Refresher();
refresh.run();我希望线程同时工作。刷新线程必须定期更新UI TextArea组件。
因此,下面是我如何从刷新线程更新UI:
public static void updateProgress()
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
//HERE
//I have a loop that have to be looping at every 500 ms
}
}
}我的问题是:我应该这样做吗?我需要变得简单而有效。这个循环让我很伤感,因为只要应用程序正常工作,它就必须循环。这可能是冻结UI的原因吗?我知道我在某个地方犯了很大的错误,但此时此刻我无法独自找到它。也许你可以给我一些简单的解决方案。最后一个想法-前4个线程:我想“同时”启动它们,而不是冻结我的UI。是这样的吗(从事件处理程序中像这样启动它们...)正确的还是可能有更好的?非常感谢朋友们!
PS。如果通过我的“刷新”线程刷新UI是一项艰巨的工作,我已经准备好了一个折衷的变体--通过他自己的线程(UI线程)来更新UI。但在这种情况下,我可能必须使用一些“时间拍摄机制”--避免UI冻结。你在想什么?
发布于 2012-10-17 05:38:34
主要的问题是你的算法。而不是
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//HERE
//I have a loop that have to be looping at every 500 ms
}
}你应该有
// HERE
// I have a loop that have to be looping at every 500 ms
// and when something must be updated in the GUI:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// update the GUI as fast as possible
}
});即
while (true) {
Thread.sleep(500L);
String update = getUpdate();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textArea.append(update);
}
});
}传递给SwingUtilities.invokeLater()的runnable在事件分派线程中执行。它不能执行长时间运行的任务。无休止的循环是一项非常漫长的任务。
发布于 2012-10-17 05:38:11
您不希望在传递给invokeAndDoLater的runnable中进行循环。请看下面的示例:http://www.javamex.com/tutorials/threads/invokelater.shtml
发布于 2012-10-17 05:32:10
SwingUtilities.invokeLater未设计为调用长时间运行的线程。您的问题的一个解决方案可能是this one。
您还可以尝试颠倒循环和SwingUtilities.invokeLater调用的嵌套,但这样做的可行性取决于代码的其余部分
do {
// Sleep and other stuff
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Update UI
}
});
} while(...);https://stackoverflow.com/questions/12923625
复制相似问题