【问题标题】:Modeless JDialog not showing contents无模式 JDialog 不显示内容
【发布时间】:2011-03-19 12:35:07
【问题描述】:

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

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

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

谢谢!

【问题讨论】:

  • 错误引用会很有帮助。
  • “我选择使用无模式的 JDialog,以便程序在 JDialog 可见时继续运行并工作”。模态对话框阻止程序其余部分中的任何线程运行,仅阻止用户访问父控件。当用户在 JOptionPane 中弹出配置选项时,我有 2D 动画继续渲染。
  • @Andrew Thompson 是正确的;这是一个简短的example。我仍然很好奇您要避免什么“错误”。

标签: java user-interface swing jdialog modeless


【解决方案1】:

这不是错误,您必须在主线程旁边的单独线程中运行您的重量级工作和轻量级摆动工作。这是必要的,因为 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();
    // ... 
    }
//...
}

终于成功了,希望对你有所帮助;)

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      我正在使用它并且它可以工作 - 原始代码(没有我在运行时找到的用于重新绘制的修复程序)来自这里: 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());
      

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

      【讨论】:

      • 哦,是的,使用最新的 java,对话框的初始化和设置可见发生在处理我的循环开始时(在进入之前),在我的循环结束时,就在它外面,我 dialog.dispose().
      【解决方案4】:

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

      【讨论】:

      • 是的,我已经尝试过调用组件进行绘制的所有形式。我没有添加源代码的原因是因为我知道这是 Swing 的一个错误,我正在寻找替代实现(如建议使用 SwingWorker),或者找到解决方法的人这与操作系统无关 - Windows 机器上不会出现此问题。
      • 我感觉,必须有一个解决方法,同时仍然使用 JDialog。
      猜你喜欢
      • 1970-01-01
      • 2023-03-10
      • 2019-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-19
      • 1970-01-01
      • 2020-04-17
      相关资源
      最近更新 更多