java - 使用线程更新jlabel的内容
问题描述
单击一个按钮时,我想使用线程来更改 JLabel 的内容。此按钮将处理一个花费大量时间的文档。但是当我点击按钮时,JLabel 的内容会在处理完文档后显示出来。我希望它可以立即显示。
这是代码
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String command = e.getActionCommand();
// Load button
if (command.equals("Load")) {
// set load to true
load = true;
// get text area name
name = nameField.getText();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
loadState.setText("Loading document "+name+" . Please wait!");
}
}).start();
// load daffodils
if (name.toLowerCase().equals("daffodils.txt")) {
try {
loadText(tpPoem);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
任何人都可以告诉我为什么这个线程不起作用。
解决方案
Swing 大多是单线程的,从多个线程调用方法可能会导致问题。您应该在称为事件调度线程 (EDT) 的特殊线程上修改您的标签。
ActionListener.actionPerformed
在这个线程上运行,所以而不是
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
loadState.setText("Loading document "+name+" . Please wait!");
}
}).start();
你可以写:
loadState.setText("Loading document "+name+" . Please wait!");
您的加载似乎也在 EDT 上运行:
if (name.toLowerCase().equals("daffodils.txt")) {
try {
loadText(tpPoem);
} catch (IOException e1) {
e1.printStackTrace();
}
}
如果您在该方法中使用后台线程,则可以,否则请查看SwingWorker。那是为了在后台线程中执行冗长的任务。如果您使用长时间运行的任务阻止 EDT,则在任务完成之前不会更新标签。
如果您想从后台线程更新您的 GUI,则SwingWorker
有相应的方法。此外,您可能会发现这个问题很有趣:When and Where to call EventQueue.invokeLater() method
推荐阅读
- javascript - 使用 JS .getElementsByClassName 更改文本:类名相同,我只想更改一个的文本
- c - 如何使用 Atoi 函数将字符串转换为 int?
- python - 我似乎无法掌握如何在 python 中使用径向基函数内核进行分类任务
- go - gzip 请求体自动解压
- ios - 为什么可以选择声明 Swift 包的产品是动态的还是静态的?
- bash - tar & split 远程文件在本地保存输出从输出中删除“tar:从成员名称中删除前导 `/'”消息
- javascript - 如何通过使用 ID 单击删除按钮来删除帖子?
- xml - Web 服务生成错误的 xml:十六进制值 0x00 是无效字符错误
- html - 如何在表格的两侧制作带有双线的标题
- javascript - MailApp 未与大量收件人一起发送