我有一个applet,它调用包含JProgressBar组件的JDialog。我将JDialog子类化以公开更新JProgressBar的方法,如:
public class ProgressDialog extends javax.swing.JDialog {
public void setProgress(double progress) {
jProgressBar1.setValue(jProgressBar1.getMinimum() + (int) (progress * jProgressBar1.getMaximum()));
}
...
}
我以下列方式使用此对话框:
public void test() throws Exception {
progressDialog = new ProgressDialog(null, true);
try {
progressDialog.setLocationRelativeTo(null);
// show the dialog
EventQueue.invokeLater(new Runnable() {
public void run() {
progressDialog.setVisible(true);
}
});
// business logic code that calls progressDialog.setProgress along the way
doStuff();
} finally {
progressDialog.setVisible(false);
progressDialog.dispose();
}
}
它适用于Windows /任何浏览器。但是,在Mac上的Firefox 2/3 / 3.5上调用上述功能时,progressDialog会无限期显示,即它不会关闭。
我怀疑在EventQueue中调用setVisible(true)导致了问题,因为它是一个阻塞调用并且可能完全阻塞队列,所以我尝试将其更改为:
// show the dialog
new Thread() {
public void run() {
progressDialog.setVisible(true);
}
}.start();
通过此更改,progressDialog现在可以正确关闭,但是出现了一个新问题 - 对话框的内容(包括进度条,图标和用于显示消息字符串的JLabel)不再显示在对话框中。它仍然是Mac Firefox上的一个问题。
有什么想法吗?我意识到这可能是一些AWT线程问题,但我已经在这几天了,无法找到一个好的解决方案。将doStuff()业务逻辑包装在一个单独的新线程中似乎可行,但将实际的业务逻辑代码重构为一个单独的线程并不容易,所以我希望有一个更简单的解决方案。
envt是: Mac OSX 10.5 Java 1.5 Firefox 2/3 / 3.5
答案 0 :(得分:1)
发现问题是applet函数在AWT调度程序线程内执行,因此线程阻塞并且在applet函数完成执行之前不会处理任何事件。
解决方法是在调用setVisible(true)之前将处理逻辑移动到由ProgressDialog对象生成的单独线程中。 setVisible(true)会阻塞主线程,但仍然允许事件调度程序继续处理,从而呈现对话框的内容,直到生成的线程调用setVisible(false)来隐藏对话框。