JProgressBar в диалоговом окне не работает должным образом - PullRequest
0 голосов
/ 16 мая 2018

У меня есть Java-программа, которая загружает текстовый файл в качестве входных данных, читает его содержимое, изменяет некоторые строки и затем печатает результат в текстовое поле.Из-за нескольких секунд, требуемых для этой операции, я хотел бы показать JProgressBar во время этого действия, чтобы проинформировать пользователя о том, что выполняется, и когда действие завершено, закройте диалоговое окно, содержащее JprogressBar, и напечатайте результаты.

Вот код:

JButton btnCaricaFile = new JButton("Load text file");
        panel.add(btnCaricaFile);
        btnCaricaFile.setIcon(UIManager.getIcon("FileView.directoryIcon"));
        btnCaricaFile.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                //JFileChooser choice = null;
                final JFileChooser choice = new JFileChooser(userDir +"/Desktop");
                int option = choice.showOpenDialog(GUI.this);
                if (option == JFileChooser.APPROVE_OPTION) {
                    final JDialog dialog = new JDialog(GUI.this, "In progress", true);
                    JProgressBar progressBar = new JProgressBar(0, 100);
                    progressBar.setIndeterminate(true);
                    dialog.getContentPane().add(BorderLayout.CENTER, progressBar);
                    dialog.getContentPane().add(BorderLayout.NORTH, new JLabel("Elaborating strings..."));
                    dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
                    dialog.setSize(300, 75);
                    dialog.setLocationRelativeTo(GUI.this);
                    Thread t = new Thread(new Runnable() {
                        public void run() {
                            dialog.setVisible(true);
                            File file = choice.getSelectedFile();
                            lista.clear();
                            textArea.setText("");
                            lista = loadFile.openFile(file);
                            for(int i=0; i<lista.size(); i++) {
                                textArea.append(lista.get(i)+"\n");
                            }
                            dialog.setVisible(false);
                        }
                    });
                    t.start();
                }
            }
        });

Для этой цели я использую JDialog в качестве контейнера для JProgressBar, выполняемого соответствующим потоком.Проблема в том, что индикатор выполнения отображается бесконечно долго и ничего не печатается в текстовой области.

Не могли бы вы помочь мне решить эту проблему?Спасибо

1 Ответ

0 голосов
/ 16 мая 2018

Да, вы создаете фоновый поток для чтения вашего файла, хорошо, но вы также делаете вызовы Swing из этого же фонового потока, не очень хорошо, и это, вероятно, связывает поток событий Swing ненадлежащим образом. Ключ заключается в том, чтобы сохранить ваши потоки отдельно - фоновая работа идет в фоновом потоке, а работа Swing идет только в потоке Swing. Пожалуйста, прочитайте Урок: Параллельность в Swing Подробнее об этом.

Сам я бы создал и использовал SwingWorker<Void, String> и использовал бы пару метода публикации / обработки рабочего для безопасной отправки строк в JTextArea.

Например, что-то вроде ...

final JDialog dialog = new JDialog(GUI.this, "In progress", true);
JProgressBar progressBar = new JProgressBar(0, 100);
progressBar.setIndeterminate(true);
dialog.getContentPane().add(BorderLayout.CENTER, progressBar);
dialog.getContentPane().add(BorderLayout.NORTH, new JLabel("Elaborating strings..."));
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.setSize(300, 75);
dialog.setLocationRelativeTo(GUI.this);
lista.clear();
SwingWorker<Void, String> worker = new SwingWorker<Void, String>() {

    @Override
    public Void doInBackground() throws Exception {
        // all called *off* the event thread
        lista = loadFile.openFile(file);
        for (int i = 0; i < lista.size(); i++) {
            publish(lista.get(i));
        }
        return null;
    }

    @Override
    protected void process(List<String> chunks) {
        // called on the event thread
        for (String chunk : chunks) {
            textArea.append(chunk + "\n");
        }
    }

    // called on the event thread
    public void done() {
        dialog.setVisible(false);
        // should call get() here to catch and handle
        // any exceptions that the worker might have thrown
    }
};
worker.execute();
dialog.setVisible(true); // call this last since dialog is modal

Примечание: код не проверен и не скомпилирован

...