Операция записи выполняется в JTextArea

#java #multithreading #swing

#java #многопоточность #swing

Вопрос:

Я написал приложение, которое создает графические изображения на основе списка x: f (x) . В графическом интерфейсе он должен показывать, какая пара записывается на графике в данный момент, но JTextArea показывает сообщения только после завершения цикла, который генерирует изображение. Как сообщения могут отображаться в режиме реального времени?

Я думал об использовании нескольких потоков, но все равно не сработал.

ниже приведен код генератора графов:

 public static void processFile(String filename, String currentDir){
    File file = new File(filename);

    LogWindow logWindow = showLogWindow();

    String line, function;
    TreeMap<Integer, Integer> dataSet = null;

    try(BufferedReader reader = new BufferedReader(new FileReader(file))) {
        logWindow.log("Starting processing of file "   file.getName());
        skipHeader(reader, Constantes.HEADER_LINES);
        while ((line = reader.readLine()) != null){
            if(line.startsWith("function ")){
                function = line.substring(25, 35).trim();

                if(dataSet != null){
                    logWindow.log("Graph of function "   function   " created.");
                    Graph demo = new Graph(dataSet);
                    demo.writeAsPNG(currentDir   File.separator   function   ".png");
                }

                dataSet = new TreeMap<Integer, Integer>();
            }else{                  
                int x = Integer.valueOf(line.substring(20,25).trim());
                int fX = Integer.valueOf(line.substring(25,30).trim());
                dataSet.put(x, fx);
                logWindow.log("Adding values of x = "   x   " and f(x) = "   fX);
            }
        }

        //Writing last set of data
        logWindow.log("Graph of function "   function   " created.");
        Graph demo = new Graph(dataSet);
        demo.writeAsPNG(currentDir   File.separator   function   ".png");
    } catch (FileNotFoundException e) {
        //TODO log this better
        e.printStackTrace();
    } catch (IOException e) {
        //TODO log this better
        e.printStackTrace();
    }   
}
  

И это код класса LogWindow

 public class LogWindow extends JPanel {
private JTextArea log;

public LogWindow() {
    super(new BorderLayout());
            log = new JTextArea(5,40);
            log.setMargin(new Insets(5,5,5,5));
            log.setEditable(false);
            JScrollPane logScrollPane = new JScrollPane(log);
            add(logScrollPane, BorderLayout.CENTER);
}

public void log(String message){
        LogThread t = new LogThread(log, message);
    t.start();
    try {
        t.join();
    } catch (InterruptedException e) {
        // TODO Log this better
        e.printStackTrace();
    }
}
}

class LogThread extends Thread{
JTextArea log;
String message;

public LogThread(JTextArea log, String message) {
    this.log = log;
    this.message = message;
}

@Override
public void run() {
    log.append(message   Constantes.lineBreak);
    log.setCaretPosition(log.getDocument().getLength());        
}
}
  

Заранее спасибо

Комментарии:

1. Вероятно, вам нужно обновить TextArea в потоке Swing с помощью invokeLater() — см. Руководство по Swing

Ответ №1:

  • ваш код не завершен, отправьте SSCCE / MVCE


  • у вас проблема с совместимостью в Swing, Swing является однопоточным, и все обновления уже видимого AWT / Swing GUI должны быть в EDT

  • быстрое исправление путем переноса log.append(message Constantes.lineBreak); в invokeLater()

  • не знаю, почему причина есть t.join();


  • (вызываемая повторно) строка кода log.setCaretPosition(log.getDocument().getLength()); должна быть заменена (работает только в том случае, если все обновления выполняются в EDT) единым определением для JTextArea /event . JTextComponent

.

 DefaultCaret caret = (DefaultCaret) log.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
  

Комментарии:

1. В конце я изменил быстрое исправление для подхода SwingWorker, как предложено в рабочих потоках и SwingWorker