Каков наилучший способ, если возможно, отправить информацию из Java PrintStream в JTextPane? - PullRequest
2 голосов
/ 16 марта 2010

В Java у меня есть пакет, который переводит метаданные XML из одного стандарта в другой. В конечном итоге доступ к этому пакету осуществляется через одну функцию и отправляет весь свой вывод через объект PrintStream. Отправленный вывод - это просто состояние каждого файла и его перевод или нет.

Это довольно неплохо, если я просто печатаю в System.out, но на самом деле я хочу напечатать это на JTextPane , а переводит (вроде как текстовое поле прогресса) , Не будет большой проблемой просто напечатать статус после того, как он завершит перевод XML, но, поскольку могут быть тысячи файлов XML, это просто невозможно.

Одна вещь, которую я попробовал, - это использовать поток, который берет всю информацию из PrintStream (которая присоединена к ByteArrayOutputStream) и позволяет ему отправлять любую новую информацию в текстовую панель. К сожалению, это все равно отправляет информацию сразу в конце перевода. Это работает правильно для System.out.

Вот код, который выполняет перевод и пытается показать вывод:

public class ConverterGUI extends javax.swing.JFrame {

    boolean printToResultsBox = false;
    PrintStream printStream = null;
    ByteArrayOutputStream baos = null;

    private class ResultsPrinter implements Runnable {

        public ResultsPrinter() {
            baos = new ByteArrayOutputStream();
            printStream = new PrintStream(baos);
        }

        public void run() {
            String tempString = "";
            while (printToResultsBox) {
                try {
                    if (!baos.toString().equals(tempString)) {
                        tempString = baos.toString();
                        resultsBox.setText(tempString);
                    }
                } catch (Exception ex) {
                }
            }
        }
    }

    ...

    ResultsPrinter rp = new ResultsPrinter();
    Thread thread = new Thread(rp);
    thread.start();

    // Do the translation.
    try {
        printToResultsBox = true;
        boolean success = false;
        TranslationEngine te = new TranslationEngine();
        // fileOrFolderToConvert is a text box in the GUI.
        // linkNeeded and destinationFile are just parameters for the translation process.
        success = te.translate(fileOrFolderToConvert.getText(), linkNeeded, destinationFile, printStream);
        if (success) {
            printStream.println("File/folder translation was a success.");
        }
        resultsBox.setText(baos.toString());
    } catch (Exception ex) {
        printStream.println("File translation failed.");
    } finally {
        printToResultsBox = false;
    }

    ...

}

В конечном счете, этот код распечатывается на JTextPane очень хорошо после того, как весь перевод сделан, но не во время. Какие-либо предложения? Нужно ли мне менять PrintStream на что-то другое?

1 Ответ

2 голосов
/ 16 марта 2010

Проблема с тем, как работает ваш поток, заключается в том, что вы не участвуете в потоке событий пользовательского интерфейса при обновлении окна результатов. Взгляните на класс SwingWorker . Или вы можете использовать SwingUtilities.invokeAndWait

...