我写过以下代码。我没有显示完整的源代码,但是没有显示psudo代码。
class UI extends JFrame
{
//created UI with one Button
onButtonclick()
{
//did some operation before set icon to button
//say opened fileopen dialog and get file
button.setText("");
ImageIcon progressbar = new
ImageIcon(DatasetExporterUI.class.getResource("/progreassbar.gif"));
buttonExport.setIcon(progressbar);
// did some database operations
//again removed icon from button
button.setIcon(null);
button.setText("click");
}
}
当我点击按钮它打开文件打开对话框并且按钮文本设置为空。 但它没有将Icon设置为按钮。当所有数据库操作都完成后,在Icon设置为按钮后执行该时间Icon出现在按钮上。 为什么会这样? 如何将Icon设置为按钮并执行一些数据库操作并再次将其删除? 谢谢。 :)
答案 0 :(得分:3)
GUI系统一次只能做一件事,就像大多数代码一样(使用线程的代码除外)。打电话给你的听众是一回事。在监听器运行时,GUI系统无法执行任何其他操作。
您的数据库操作需要在另一个线程(您可以创建)上运行,然后在完成后更新GUI。像这样:
void onButtonPressed() {
// The code to open the file dialog goes here
button.setText("");
ImageIcon progressbar = new
ImageIcon(DatasetExporterUI.class.getResource("/progreassbar.gif"));
buttonExport.setIcon(progressbar);
new Thread() {
@Override
public void run() {
// do some database operations here
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
//again remove icon from button
button.setIcon(null);
button.setText("click");
}
});
}
}.start();
}
不同线程中的代码同时运行。这很方便但很危险。从新线程访问数据时要格外小心 - 如果一个线程更改了一个字段而另一个线程读取了该字段,则结果可能与您预期的不同。最简单的方法是确保主线程在运行时不会更改新线程使用的任何变量。
完成数据库操作后,只需调用setText就无法将按钮恢复正常。只允许主线程影响GUI - 如果主线程在数据库操作线程正在更改文本的同时在屏幕上绘制按钮怎么办?该按钮可能绘制不正确。所以你需要调用EventQueue.invokeLater
来告诉GUI系统在不忙的时候在不久的将来运行你的代码。 new Runnable() {}
中的代码就像按钮侦听器中的代码一样 - 没有其他与GUI相关的代码会运行。
答案 1 :(得分:0)
这应该有效:
Image progressbar= ImageIO.read(DatasetExporterUI.class.getResource("/progreassbar.gif"));
buttonExport.setIcon(new ImageIcon(progressbar));