【问题标题】:Java Swing ProgressBar update while computingJava Swing ProgressBar 在计算时更新
【发布时间】:2015-08-18 18:24:31
【问题描述】:

有一些类似问题的例子 (Progress Bar Java) 和 (Java uploading percentage progressbar thread) 但不明白如何使它适用于我的代码。

我的主要有 2 个面板,一个在另一个之上(其中一个是带有 2 个选项卡的 tabbedPane)

public class MainIRH {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }
                MainWindow window = new MainWindow();
                JPanel mainPanel = new JPanel(new BorderLayout(0, 20));
                mainPanel.setBorder(new EmptyBorder(20, 20, 20, 20));

                JTabbedPane tabbedPane = new JTabbedPane();
                tabbedPane.setBorder(BorderFactory.createLineBorder(Color.BLACK));

                ControlPanel controlPanel = new ControlPanel();

                tabbedPane.setBorder(new EmptyBorder(10, 10, 10, 10));
                controlPanel.setBorder(new EmptyBorder(0, 20, 20, 20));

                ECPanel ecPanel = new ECPanel();
                SMRPanel smrPanel = new SMRPanel();

                tabbedPane.addTab("Environnement Canada", null, ecPanel, "Convertir des données des stations d\'Environnement Canada");
                tabbedPane.addTab("Station Météo Routière", null, smrPanel, "Convertir des données des stations météos routières");

                mainPanel.add(tabbedPane, BorderLayout.NORTH);
                mainPanel.add(controlPanel, BorderLayout.CENTER);
                window.add(mainPanel);

                new ControllerIRH(ecPanel, smrPanel, controlPanel);

                window.setVisible(true);
            }
        });
    }
}

重要的是这个对象:SMRPanel smrPanel = new SMRPanel();

在这个对象中,我有一个 JButton convertArchiveButton,我从 Controller 类中添加了一个 ActionListener

public void addConvertArchiveButton(ActionListener ConvertArchiveButton) {
    convertArchiveButton.addActionListener(ConvertArchiveButton);
}

下面是Controller中Listener的实现

private class ConvertArchiveButtonListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent event) {
             converter.convert();
    }
}

converter 是执行冗长操作的类

File[] listOfFiles = folder.listFiles();

for (int file = 0; file < listOfFiles.length; file++) {

     int progress = Math.round(file * 100 / listOfFiles.length);

     //tried a lot of things here...

    //...computing

}

我的示例尝试使用EventQueueSwingUtilities 添加一些新的Runnable,但没有成功。 SwingWorker 课程会有用吗?不太明白用处。

基本上,int progress 将被传递给SMRPanel 中的JProgressBar

使用 ControlAltDel 编辑答案:

还是不行,converter.readFile(file); 没有被调用。

private class ConvertArchiveButtonListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent event) {
        File[] listOfFiles = folder.listFiles();

        System.out.println(listOfFiles.length);

        for (int i = 0; i < listOfFiles.length; i++) {
            final File file = listOfFiles[i];
            final int idx = (i * 100) / listOfFiles.length;
            Thread t = new Thread(new Runnable() {
                public void run() {
                    converter.readFile(file);

                    System.out.println(idx);

                    SwingUtilities.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            smrPanel.setProgressBarValue(idx);
                        }
                    });
                }
            });

            try {
                t.start();
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        converter.convert(year);

    }
}

【问题讨论】:

  • 基本上,您需要在除 EDT 之外的任何线程中执行 runnable。 EventQueue 和 SwingUtilities 仅调度到 EDT。是的,SwingWorker 会在这方面做得很好:对于 example
  • 对不起,应该试试 try { t.start(); t.join(); } ...
  • 我已经修改了我的代码...我犯了一个错误,可能导致文件处理线程完成并且无法按顺序调整 ProcessBar。我现在已经解决了这个问题
  • @ControlAltDel 你一开始想的那样,但更新成功了。

标签: java swing swingworker jprogressbar swingutilities


【解决方案1】:

您的问题是您在 EDT 线程中运行循环。通过在另一个线程中运行它,然后在处理完文件时在 EDT 中设置更新的进度值来修复

private class ConvertArchiveButtonListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent event) {
            new Thread(new Runnable() {
            public void run() {
               for (int file = 0; file < listOfFiles.length; file++) {
                  final File f = listOfFiles[i];
                  final idx = file;
                  Thread t = new Thread(new Runnable() {
                    converter.convert(f);
                    swingUtilities.invokeLater(new Runnable() {
                      myProgressBar.setValue(idx);
                    });
                   t.start();
                   t.join();
                  });
                 }
             }).start();
    }
}

【讨论】:

  • 我尝试实现这个但没有成功,我在最后尝试更新了我的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-14
  • 1970-01-01
  • 1970-01-01
  • 2016-03-08
  • 2022-01-18
  • 2015-08-15
相关资源
最近更新 更多