Хобрук: Ваш путь к мастерству в программировании

PrintWriter в JTextArea, ничего не отображается, пока вызываемый метод не закроется

Контекст: я читаю данные с последовательного порта на скорости 115,2 кбод. Прочитанные данные печатаются с помощью PrintWriter, который затем добавляется к JTextArea.

Все работает хорошо, но текст в JTextArea не появляется до тех пор, пока метод отправки потока из последовательного порта в мой PrintWriter не завершится. Я бы хотел, чтобы он отображался ближе к реальному времени, так как время от времени я буду получать более 20-30 МБ текста за раз, и то, как общий поток текста изменяется по мере выполнения программы, будет ценным.

Я использую метод PrintWriter to JTextArea здесь. Я думаю, что решение, вероятно, связано с Threads и PipedWriter/PipedReader, но каждая попытка реализовать это с треском провалилась.

Спасибо за помощь.

//code calling method;  VerifierReader does not inherit from Reader 
//or any such class. it's wholly homegrown. I send it the PrintWriter 
//as out, telling it to output there


verifierInstance=new VerifierReader("COM3", verifierOutputLocString.getText());
verifierInstance.setSysOutWriter(out);
verifierInstance.readVerifierStream();

// and the relevant code from VerifierReader

public void setSysOutWriter (PrintWriter outWriter) {
        sysOutWriter=new PrintWriter(outWriter);            

    }
public void readVerifierStream() throws SerialPortException, 
InterruptedException{

    try{
        sysOutWriter.println("Listening for verifier...");
                    //sysOutWriter.flush();

        verifierPort.addEventListener(new verifierListener());

        lastReadTimer=System.currentTimeMillis();

        while(verifierPort.isOpened()) {

            Thread.sleep(1000);
            //System.out.println(timeOut);
            if( ((long)(System.currentTimeMillis()-lastReadTimer))>timeOut){
                sysOutWriter.println("Finished");
                verifierPort.removeEventListener();
                verifierPort.closePort();

            }
        }
    }

    finally {

        if (verifierPort.isOpened()) {
            verifierPort.closePort();
        }

        bfrFile.close();

    }
}








private class verifierListener implements SerialPortEventListener{

    String outBuffer;




    public void serialEvent(SerialPortEvent event) {
        if(event.isRXCHAR()){//If data is available
            timeOut=200;
            lastReadTimer=System.currentTimeMillis();
            if(event.getEventValue() > 0){//Check bytes count in the input buffer

                try {
                    byte[] buffer = verifierPort.readBytes(event.getEventValue());
                    outBuffer=new String(buffer);

                    bfrFile.print(outBuffer);
                    sysOutWriter.print(outBuffer);
                        //bfrFile.flush();
                        //sysOutWriter.flush();
                }
                catch (SerialPortException ex) {
                    sysOutWriter.println(ex);
                }

            }
        }



    }
}

Редактировать:

Я попытался сделать то, что было рекомендовано ниже, и внес следующие изменения:

 private class VerifierTask extends SwingWorker<Void, String> {



    public VerifierTask() throws IOException, SerialPortException, InterruptedException{
        verifierInstance= new VerifierReader(streamReader);
        verifierInstance.setReaderIO("COM3", verifierOutputLocString.getText());
        verifierInstance.readVerifierStream();

    }


    @Override
    protected Void doInBackground() throws IOException{
        int charItem;
        char[] charBuff = new char[10];
        String passString;

        while ((charItem = streamReader.read(charBuff, 0, 10)) !=-1) {

            passString = new String(charBuff);
            publish(passString);
        }


        return null;
    }

    @Override 
    protected void process(List<String> outList) {

        for (String output : outList) {
            outputArea.append(output);
        }

    }



}

был добавлен, и я изменил свою кнопку, чтобы немедленно вызвать новый экземпляр класса VerifierTask, в дополнение к тому, чтобы VerifierReader реализовал PipedWriter для вывода (все это было строками).

Я не уверен, что я делаю неправильно здесь. Когда этот код выполняется, процесс Java просто зависает на неопределенный срок.

Правильно ли я предполагаю, что VerifierReader, созданный в любом потоке VerifierTask, привязан к этому потоку, и поэтому мои операторы thread.sleep и while(true) больше не создают проблемы?


Ответы:


1

Не вызывайте Thread.sleep или do while (true) в основном потоке событий Swing, EDT. Всегда. Вместо этого делайте подобные вещи в фоновом потоке, таком как тот, который предоставляется через SwingWorker. Вы должны использовать пару методов публикации/обработки для получения промежуточных результатов в JTextArea.

Подробнее об этом читайте в руководстве: Параллелизм в Swing.

18.11.2011
Новые материалы

Учебные заметки JavaScript Object Oriented Labs
Вот моя седьмая неделя обучения программированию. После ruby ​​и его фреймворка rails я начал изучать самый популярный язык интерфейса — javascript. В отличие от ruby, javascript — это более..

Разбор строк запроса в vue.js
Иногда вам нужно получить данные из строк запроса, в этой статье показано, как это сделать. В жизни каждого дизайнера/разработчика наступает момент, когда им необходимо беспрепятственно..

Предсказание моей следующей любимой книги 📚 Благодаря данным Goodreads и машинному обучению 👨‍💻
«Если вы не любите читать, значит, вы не нашли нужную книгу». - J.K. Роулинг Эта статья сильно отличается от тех, к которым вы, возможно, привыкли . Мне очень понравилось поработать над..

Основы принципов S.O.L.I.D, Javascript, Git и NoSQL
каковы принципы S.O.L.I.D? Принципы SOLID призваны помочь разработчикам создавать надежные, удобные в сопровождении приложения. мы видим пять ключевых принципов. Принципы SOLID были разработаны..

Как настроить Selenium в проекте Angular
Угловой | Селен Как настроить Selenium в проекте Angular Держите свое приложение Angular и тесты Selenium в одной рабочей области и запускайте их с помощью Mocha. В этой статье мы..

Аргументы прогрессивного улучшения почти всегда упускают суть
В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

Введение в Джанго Фреймворк
Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..