Как запустить процесс, который выводит текст и записывает этот текст в текстовую область Javafx по мере ее вывода? - PullRequest
0 голосов
/ 28 марта 2019

Я создаю графический интерфейс, на котором выполняется программа, которая запускает тесты и записывает их вывод в виде текста на консоль.Я создал таблицу, которая позволяет пользователю выбирать тесты, которые он хочет запустить, когда пользователь нажимает «выполнить», затем он проходит через таблицу и запускает выбранные тесты и должен записать вывод в textArea.Когда я запускаю программу, textArea не будет обновляться до тех пор, пока не будут выполнены все тесты, но мне нужно обновить ее, поскольку тест выводит текст.

Из того, что я прочитал, мне нужно создать несколько потоков, потому чтоЗапуск программы и запись в textArea - оба процесса.Я не совсем понимаю, как работает Threading, но я попытался использовать StringBuffer, чтобы результаты теста могли быть сохранены и использованы вторым созданным мной потоком.

public void runTest(ArrayList<String> arr) throws InterruptedException{
        StringBuffer sb = new StringBuffer();

        Thread t = new Thread(() -> {
            try {
                ProcessBuilder builder = new ProcessBuilder(arr);
                builder.redirectErrorStream(true);
                Process p = builder.start();
                BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
                String line;
                while((line = r.readLine()) != null){
                    sb.append(line).append("\n");
                }  
                System.out.println(line);
            } catch (IOException ex) {
                Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
            }
        });

        Thread t2 = new Thread(()->{
            String line = sb.toString();
            System.out.println(line);
            txtOutputArea.appendText(line + "\n");
        });

        t.start();
        t2.start();

        t.join();
        t2.join();

    }

IЯ печатаю текст в консоль, и он работает, но по какой-то причине нет вывода в textArea.

Ответы [ 2 ]

1 голос
/ 28 марта 2019

Сделайте это в одном потоке, например, переместите txtOutputArea.appendText(line + "\n"); внутри цикла while в Потоке Один и оберните его в Platform.runlater, чтобы он не выдавал исключение not on main thread, как это.

private ExecutorService executorService = Executors.newSingleThreadExecutor();

public void runTest(ArrayList<String> arr) throws InterruptedException{
    Thread t = new Thread(() -> {
        try {
            ProcessBuilder builder = new ProcessBuilder(arr);
            builder.redirectErrorStream(true);
            Process p = builder.start();
            BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line;
            while((line = r.readLine()) != null){
                //sb.append(line).append("\n");//Remove this if thats all you were using it for
                Platform.runLater(()->txtOutputArea.appendText(line + "\n"));
            }
            System.out.println(line);//Move this inside the loop if you want it to print th output to the console
        } catch (IOException ex) {
            Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
        }
    });
    executorService.submit(t);
}

Чтобы добавить к этому, как сказал @Slaw, исправить эту проблему, если вы используете newSingleThreadExecutor, это приведет к тому, что все, что вы отправляете в эту службу, будет обрабатываться как очередь, поэтому, если вы вызовете runTest, а затем выполните всеВаш второй тест и отправьте его на executorService (как и первый).Придется подождать, потому что в executorService.

есть только рабочий поток.
0 голосов
/ 29 марта 2019

В качестве примечания: обратите внимание, что JavaFX TextArea будет работать абсолютно ужасно, если текст в вашей TextArea слишком длинный.Поэтому, если ваш вывод может стать несколькими тысячами строк, это не сработает (из-за того, что TextAre не виртуализирован).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...