【问题标题】:JDialog does not appearJDialog 不出现
【发布时间】:2015-03-29 21:51:32
【问题描述】:

该程序大部分工作正常,但不打开任何窗口。它应该在桌面的右下角显示一个小对话框。但是对于另一个人来说,编译相同的代码没有问题。我们有相同的 Java 运行时(1.8_u40)。我该如何解决这个问题?

我把代码放在下面:

import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.RoundRectangle2D;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ProgressDialog {
    private JDialog dialogFrame;
    private JProgressBar progressBar;
    private JLabel headingLabel;
    private Uploader callerUploader;

    public ProgressDialog() {

        dialogFrame = new JDialog();
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
                | UnsupportedLookAndFeelException ex) {
            System.err.println(ex.toString());
        }

        dialogFrame.setSize(200, 50);
        dialogFrame.setLayout(new GridBagLayout());

        GridBagConstraints constraints = new GridBagConstraints();

        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.weightx = 1.0;
        constraints.weighty = 1.0;
        constraints.insets = new Insets(5, 5, 5, 5);

        headingLabel = new JLabel();
        Font f = headingLabel.getFont();
        f = new Font(f.getFontName(), Font.BOLD, f.getSize());
        headingLabel.setFont(f);
        headingLabel.setOpaque(false);
        dialogFrame.add(headingLabel, constraints);
        dialogFrame.setUndecorated(true);

        // Bottone
        constraints.gridx = 1;
        constraints.gridy = 0;
        constraints.weightx = 0;
        constraints.weighty = 0;

        JButton xButton = new JButton("X");
        xButton.setMargin(new Insets(1, 4, 1, 4));
        xButton.setFocusable(false);
        dialogFrame.add(xButton, constraints);

        // Progress bar
        constraints.gridx = 0;
        constraints.gridy = 1;
        constraints.weightx = 1.0;
        constraints.weighty = 1.0;
        constraints.gridwidth = 2;

        progressBar = new JProgressBar();
        progressBar.setMaximum(100);
        progressBar.setMinimum(0);
        Dimension dim = new Dimension();
        dim.width = 130;
        dim.height = 20;
        progressBar.setMinimumSize(dim);
        progressBar.setStringPainted(true);
        progressBar.setBorderPainted(true);
        dialogFrame.add(progressBar, constraints);

        xButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                dialogFrame.dispose();
                stoppedUploaderClose();
            }
        });
    }

    private void autoPosition() {
        // Per il posizionamento in basso a destra
        Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize();
        // altezza taskbar
        Insets toolHeight = Toolkit.getDefaultToolkit().getScreenInsets(dialogFrame.getGraphicsConfiguration());
        dialogFrame.setLocation(scrSize.width - 5 - dialogFrame.getWidth(), scrSize.height - 5 - toolHeight.bottom
                - dialogFrame.getHeight());
    }

    public void destroy() {
        new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(500);
                    for (float i = 1.00f; i >= 0; i -= 0.01f) {
                        dialogFrame.setOpacity(i);
                        Thread.sleep(15);
                    }
                    dialogFrame.dispose();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            };
        }.start();

    }

    public void setUploader(Uploader callerUploader) {
        this.callerUploader = callerUploader;
    }

    public void set(int n) {
        progressBar.setValue(n);
        progressBar.setString(n + "");
    }

    public void setMessage(String headingLabel) {
        this.headingLabel.setText(headingLabel);
        autoPosition();
        dialogFrame.setShape(new RoundRectangle2D.Double(1, 1, 200, 50, 20, 20));
        dialogFrame.setVisible(true);
    }

    public void setWait() {
        headingLabel.setText("Waiting link...");
    }

    public void close() {
        dialogFrame.dispose();
    }

    public void stoppedUploaderClose() {
        try {
            callerUploader.stopUpload();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

【问题讨论】:

  • 如需更直接的帮助,请考虑创建并发布sscceminimal example program/mcve,在其中将代码压缩为仍可编译和运行的最小位,没有外部依赖项(例如需要链接到数据库或图像),没有与您的问题无关的额外代码,但仍能证明您的问题。我们不想要你的整个程序,只需要一个演示问题的程序——我们志愿者要通过的代码更少。

标签: java swing awt java-8 jdialog


【解决方案1】:

您正在从后台线程中进行 Swing 调用来更改 GUI 的 Swing 组件的状态,这可能并且将会导致不可预知的错误。最好使用 Swing Timer 而不是 Thread.sleep(...),因为 Timer 的 ActionListener 中的所有代码都在 Swing 事件线程上调用。

另外,我想知道

  1. 正是 Uploader 类的作用,... 可能它会创建长时间运行的代码,这就引出了一个问题,它是否在后台线程中被适当地调用?这看起来是 SwingWorker 的好地方。
  2. 如何调用此对话框代码?

如需更直接的帮助,请考虑创建并发布 sscceminimal example program/mcve,在其中将代码压缩为仍可编译和运行的最小位,没有外部依赖项(例如需要链接到数据库或图片),没有与您的问题无关的额外代码,但仍能演示您的问题。

编辑:好的,我通常不这样做,但我在您的 GitHub project link 中查看了您的代码,并且正如我所怀疑的那样,上传器在 Swing 事件线程执行长时间运行的代码,并调用您在上面发布的此类。我建议你对长时间运行的代码使用 SwingWorker,使用它的setProgress(...) 方法将其进度状态从 0 更改为 100,并使用 PropertyChangeListener 监听此状态的更改,然后设置 JProgressBar 的基于此的价值。这将需要您做很多工作,但非常值得。详情请看:Lesson: Concurrency in Swing

我有一些示例 SwingWorker 程序,您可以在这里找到:

【讨论】:

  • 你说的是destroy()方法吗?它是唯一一个带有线程和 thread.sleep 的。如果是,则它不会生成对话框,而只是将其销毁,并且此时不会被调用。
  • @SergiX44:最初是的,但现在我怀疑问题出在您的 Uploader 类及其调用上。我仍然怀疑 Swing 线程问题,但你的问题不完整,所以现在是我的答案。我正在考虑删除我的答案,直到您可以向我们提供更多相关信息。
  • 如需更直接的帮助,请考虑创建并发布sscceminimal example program/mcve,在其中将代码压缩为仍可编译和运行的最小位,没有外部依赖项(例如需要链接到数据库或图像),没有与您的问题无关的额外代码,但仍能证明您的问题。我们不想要你的整个程序,只需要一个演示问题的程序——我们志愿者要通过的代码更少。
  • @SergiX44:请参阅编辑:是的,您在很大程度上遇到了 Swing 线程问题。您的代码具有太多的圈复杂性,无法让我创建一个简单且易于发布的修复程序,但通过一些努力,您应该能够修复它,或者简化您的类,以便我们更好地帮助您。
  • @SergiX44:永远不应该出现new Thread(...).run()。但是您的代码应该在某处存在new Thread(...).start() 或更好的new MySwingWorker.execute(),以便在Swing 事件线程之外运行您的长时间运行的进程,但您的代码没有。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多