Как просматривать ProgressMonitor Progress в режиме реального времени? - PullRequest
0 голосов
/ 20 сентября 2019
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
    // TODO add your handling code here:
    int jTableRows = jTable1.getRowCount();
    ProgressMonitor progressMonitor;
    progressMonitor = new ProgressMonitor(ImportDataFromExcel.this, "Running a Long Task", "", 0, jTableRows);
    for (int i = 0; i < jTableRows; i++) {
        String message = String.format("Completed %d.\n", i);
        progressMonitor.setNote(message);
        progressMonitor.setProgress(i);
    }
}

Когда я нажимаю кнопку для вставки данных в базу данных, я ожидаю, что ProgressMonitor получит прогресс, но получит результат только после завершения всего процесса.Как я могу просмотреть прогресс в режиме реального времени.

1 Ответ

1 голос
/ 20 сентября 2019

Все тяжелые задачи в Swing должны выполняться SwingWorkers .В противном случае большая задача будет затруднять работу Thread Dispatch Thread , поэтому события не могут происходить (графический интерфейс остановится).

Итак, вам нужно создать SwingWorker и вычислитьВыполните шаги задачи в процентах и ​​присвойте значение индикатору выполнения.Однако вы должны иметь в виду, что, поскольку progressbar.setValue(int value) является обновлением компонента, оно должно происходить только внутри EDT.Вот почему вы должны использовать publish и process методы работника.

Давайте рассмотрим пример, в котором мы должны записать 1000 строк в текстовый файл в Desktop и увидеть его прогресс.Это «большая задача» (я сплю), так что она соответствует нашему случаю.

public class ProgressExample extends JFrame {
    private static final long serialVersionUID = 5326278833296436018L;

    public ProgressExample() {
        super("test");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(new ProgressPanel());

        pack();
        setLocationRelativeTo(null);

    }

    private static class WriteTextWorker extends SwingWorker<Void, Integer> {
        private ProgressableView view;

        public WriteTextWorker(ProgressableView view) {
            this.view = view;
        }

        @Override
        protected void process(List<Integer> chunks) {
            int progress = chunks.get(0);
            view.setProgress(progress);
        }

        @Override
        protected Void doInBackground() throws Exception {
            publish(0);
            File desktop = new File(System.getProperty("user.home"), "Desktop");
            File textFile = new File(desktop, "stackoverflow.txt");
            int linesToWrite = 1000;
            try (FileWriter fw = new FileWriter(textFile, true);
                    BufferedWriter bw = new BufferedWriter(fw);
                    PrintWriter out = new PrintWriter(bw)) {
                for (int i = 0; i < linesToWrite; i++) {
                    out.println("This is line: " + i);
                    out.flush();
                    //Calculate percentage of completed task
                    int percentage = ((i * 100) / linesToWrite);
                    System.out.println("Percentage: " + percentage);
                    publish(percentage);
                    Thread.sleep(10); //Heavy task
                }
            }
            return null;
        }

    }

    private static class ProgressPanel extends JPanel implements ProgressableView {
        private JProgressBar progressBar;
        private SwingWorker<Void, Integer> worker;

        public ProgressPanel() {
            super(new BorderLayout());
            progressBar = new JProgressBar();
            add(progressBar, BorderLayout.PAGE_START);

            JButton writeLinesButton = new JButton("Press me to do a long task");
            writeLinesButton.addActionListener(e -> worker.execute());
            add(writeLinesButton, BorderLayout.PAGE_END);

            worker = new WriteTextWorker(this);
        }

        @Override
        public int getProgress() {
            return progressBar.getValue();
        }

        @Override
        public void setProgress(int progress) {
            progressBar.setValue(progress);
        }

    }

    public static interface ProgressableView {
        int getProgress();

        void setProgress(int progress);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new ProgressExample().setVisible(true));
    }
}
...