(Java SE 6) 我正在尝试创建一个弹出对话框,显示“请稍候”消息,而我的程序会执行一些时间密集的工作。为此,我选择使用无模式JDialog,以便程序继续运行并在JDialog可见时工作(如果使用模态,程序将暂停,直到用户关闭对话框)
问题在于,当你以这种方式使用无模式对话框时,会出现带有标题的JDialog,但内容却没有(我猜他们不会因为某些原因而被绘制)。我试过调用重绘等,但似乎没有任何效果。
现在,根据互联网上的一群人的说法,这是Swing的一个真正的错误,我发现的唯一答案就是不以这种方式做事并找到其他方法通知用户等待。我很好奇以前是否有人在这里遇到过这个问题并且已经找到了解决办法。
谢谢!
答案 0 :(得分:5)
这不是一个错误,你必须在主线程旁边的sepred线程中运行你的重量级工作和轻量级的工作。这是必要的,因为Dialog GUI Thread与ActionListenerEvents之间的逻辑关系与backround中的重量级作业有关。如果您没有单独使用主线程,则会因某些通知事件而确定Swing绘图。 我有同样的问题,我试图监控FTP上传进度的进度,我从一个JFrame开始,在JDialog中显示它。
首先我尝试了:
//Activated by Upload Button
public void actionPerformed(ActionEvent e) {
if("Upload".equals(e.getActionCommand())){
// some Declarations
new Thread(){
public void run() {
/*Run JDialog with the Upload - ProgressBar*/
FileUploadProgressBar fileUploadProgressBar = new FileUploadProgressBar(localFile, remoteFile, ftpPersistence);
}
}.start();
/*Run the heavy weigth Job - the Upload*/
ftpPersistence.uploadFile(localFile, remoteFile);
// ...
}
//...
}
但是这样我就可以使用JDialog FrameBorder和一个黑色的内容窗格但是......
接下来尝试:
//Activated by Upload Button
public void actionPerformed(ActionEvent e) {
if("Upload".equals(e.getActionCommand())){
// some Declarations
new Thread(){
public void run() {
/*Run JDialog with the Upload - ProgressBar*/
FileUploadProgressBar fileUploadProgressBar = new FileUploadProgressBar(localFile, remoteFile, ftpPersistence);
}
}.start();
new Thread(){
public void run()
/*Run the heavy weigth Job - the Upload*/
ftpPersistence.uploadFile(localFile, remoteFile);
}
}.start();
// ...
}
//...
}
最后它起作用了,希望它会有所帮助;)
答案 1 :(得分:4)
作为替代方案,请考虑使用SwingWorker
并显示临时进度,如example中所述。
答案 2 :(得分:2)
我正在使用它并且它可以工作 - 原始代码(没有我在运行时重新绘制的修复)来自这里: http://inversionconsulting.blogspot.com/2008/03/java-jdialog-and-jprogressbar-example.html
但我将其合并(略有变化):
JProgressBar pb = new JProgressBar(0,100);
pb.setPreferredSize(new Dimension(275,30));
pb.setString("Running");
pb.setStringPainted(true);
pb.setValue(0);
JLabel label = new JLabel("Progress: ");
JPanel center_panel = new JPanel();
center_panel.add(label);
center_panel.add(pb);
JDialog dialog = new JDialog((JFrame)null, "Working ...");
dialog.getContentPane().add(center_panel, BorderLayout.CENTER);
dialog.pack();
dialog.setVisible(true);
dialog.setLocationRelativeTo(null); // center on screen
在我的代码中,当它在我的循环中运行时(使用变量'tot'为1到10)我重新绘制对话框,在程序运行循环时更新进度条,因此(这不是在上面的页面链接上给出)(我没有使用多个线程,所有这些都在主线程中):
//set progress bar
pb.setValue(tot*10);
//repaint it
dialog.getContentPane().paintAll(pb.getGraphics());
找到这个解决方案需要花费大量时间和反复试验。希望它对你有用,就像对我一样。
答案 3 :(得分:0)
您是否尝试过validate()(将容器添加到容器后需要)? 还要考虑发布源代码,以便我们检查它。祝你好运。