4

(Java SE 6) 我正在尝试创建一个弹出对话框,在我的程序执行一些耗时的工作时显示“请稍候”消息。为此,我选择使用无模式的 JDialog,以便程序在 JDialog 可见时继续运行并工作(如果您使用模式的,程序将停止,直到用户关闭对话框) .

问题是,当您以这种方式使用无模式对话框时,会出现带有标题的 JDialog,但内容不会出现(我猜它们由于某种原因没有被绘制)。我试过调用重绘等,但似乎没有任何效果。

现在,根据互联网上的一群人的说法,这是 Swing 的一个真正的错误,我发现的唯一答案是不要以这种方式做事,而是找到一些其他方法来通知用户等待。我很好奇这里是否有人以前遇到过这个问题并找到了解决方法。

谢谢!

4

4 回答 4

5

这不是错误,您必须在主线程旁边的单独线程中运行您的重量级工作和轻量级摆动工作。这是必要的,因为 Dialog GUI 线程和它的 ActionListenerEvents 关系之间的逻辑冲突与后台的繁重工作有关。如果你不分开你的主线程将由于一些通知事件而确定 Swing 抽奖。我遇到了同样的问题,我尝试监视从 JFrame 开始的 FTP 上传进度的进度,以在 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();
    // ... 
    }
//...
}

最后它起作用了,希望它会有所帮助;)

于 2012-12-13T12:14:02.977 回答
4

作为替代方案,请考虑使用SwingWorker并显示临时进度,如本示例中所建议的那样。

于 2011-03-19T12:50:39.787 回答
2

我正在使用它并且它有效 - 原始代码(没有我在运行时找到的用于重新绘制的修复程序)来自这里:http: //inversionconsulting.blogspot.com/2008/03/java-jdialog-and-jprogressbar-例子.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());

找到这个解决方案花了很多时间和反复试验。希望它对你有用,就像对我一样。

于 2011-05-28T23:25:22.807 回答
0

您是否尝试过validate()(将组件添加到容器后需要它)?还可以考虑发布源代码,以便我们检查。祝你好运。

于 2011-03-19T13:03:06.940 回答