我正在尝试在处理循环之前更新Swing JSLable文本,但它没有更新:
public void actionPerformed(ActionEvent event)
{
title.setText("Ready"); // Initialize display
if (source == uploadButton) {
int returnVal = fc.showOpenDialog(UserInterface.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File[] files = fc.getSelectedFiles();
if (files.length < 2) {
title.setText("<html>Text1</html>"); // Is shown
} else {
title.setText("<html>Text2</html>"); // Not displaying, feels like UI is locked here
for (int i = 0; i < files.length; i++) {
filesUploaded.add(uploadFile(files[i]));
}
Images imgs = new Images();
imgs.processImages(filesUploaded); // Some processing loop inside, takes around 0.5~1s
title.setText("Completed"); // displayed corectly.
}
}
}
}
所以基本上我希望有序列:
Ready
Text2
Completed
但是我得到了这个序列(缺少Text2
输出):
Ready
Completed
答案 0 :(得分:2)
GUI线程被阻止,您应该将这部分代码包装到SwingUtilities.invokeLater
:
SwingUtilities.invokeLater(new Runnable() {
for (int i = 0; i < files.length; i++) {
filesUploaded.add(uploadFile(files[i]));
}
Images imgs = new Images();
imgs.processImages(filesUploaded); // Some processing loop inside, takes around 0.5~1s
title.setText("Completed"); // displayed corectly.
});
BTW,C风格的for
循环在Java中不受欢迎,你应该使用“增强版”构造:
for (File file: files)
filesUploaded.add (files);
甚至
filesUploaded.addAll(Arrays.asList(files))
答案 1 :(得分:0)
没关系,因为你阻止了GUI线程(在该线程中执行了操作),并且在退出方法之前它不会更新。
寻找&#34;阻止gui线程java&#34;。您会发现经常在actionPerformed中发生。
答案 2 :(得分:0)
Swing
适用于Single Threaded Model
并且Swing应用程序的线程被称为EDT (EventDispatchThread)
它始终建议不要对此线程进行任何繁重的处理,因为它会阻止UI线程,你的UI将会在这段时间内没有回应。我建议将文件上传部分移到一个单独的线程中,以保持您的UI响应。
并使用SwingUtilities.invokeLater
从这个单独的线程安排任何与EDT相关的UI工作。
另一种方法可能是使用SwingWorker
答案 3 :(得分:0)
使用SwingWorker或Foxtrot来实施长时间运行的任务。您的长时间运行任务会阻止EDT(事件调度程序线程 - 主Swing线程)和无法执行事件处理后必须执行的重绘事件。
答案 4 :(得分:0)
您应该将这些HTML标记放在其他位置,因为当您将文本放在HTML之外时,它会混淆swing。例如。您应该将开始标记放在准备好的单词之前,将结束标记放在完成的字符串之后。您还应该知道setText方法覆盖元素中的文本。你应该使用:
setText(object.getText()+"Text");
例如
title.setText("<HTML>Ready");
//...
title.setText(title.getText()+"Text2");
//...
title.setText(title.getText()+"Completed</HTML>");
请注意,actionPerformed()方法由管理图形用户界面的事件调度线程调用,并且您将其用于冗长的任务。由于EDT不能用于更新GUI,因此冻结了GUI。改为使用不同的线程:
Thread t=new Thread(new Runnable(){
public void run(){
<your code here>
}
});
此外,如果您正在访问swing,Java建议在事件线程上执行它,就像调用setText()或类似的东西一样:
SwingUtilities.invokeLater(new Runnable(){
public void run(){
<your code to access swing>
}
});