正在JTextArea中执行的写操作

时间:2014-06-26 13:39:38

标签: java multithreading swing

我写了一个基于x:f(x)列表创建图形图像的应用程序。在gui,它应该显示当前正在图形上写入的对,但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 个答案:

答案 0 :(得分:2)

  • 您的代码未完成,发布了SSCCE / MVCE


  • 您遇到Concurency in Swing问题,Swing是单线程的,所有更新都已显示AWT/Swing GUI must be on 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);