-1

我有一个执行文件操作的 java 程序,我有一个 GUI 类,它有一个 JTextArea,控制台输出重定向到它。我试图让 SwingWorker 在不同的类中发布到该 JTextArea 但我似乎无法让它正常工作。在我的 GUI 类中,我有以下方法:

public ShopUpdaterGUI() {
    initComponents();
    redirectSystemStreams();
}

private void updateTextArea(final String text) {
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            consoleTextAreaInner.append(text);
          }
        });
}


private void redirectSystemStreams() {
      OutputStream out = new OutputStream() {
        @Override
        public void write(int b) throws IOException {
          updateTextArea(String.valueOf((char) b));
        }

        @Override
        public void write(byte[] b, int off, int len) throws IOException {
          updateTextArea(new String(b, off, len));
        }

        @Override
        public void write(byte[] b) throws IOException {
          write(b, 0, b.length);
        }
      };

      System.setOut(new PrintStream(out, true));
      System.setErr(new PrintStream(out, true));
    }    

然后在我完成工作的另一个班级中,我有这个:

public void update(){
    (updateTask = new UpdateTask()).execute();
}

private class UpdateTask extends SwingWorker<Void, String>{

        @Override
        protected Void doInBackground() {
            try{
                publish("Creating backup...");
                mainBackup.createBackup();
                publish("Setting restore point...");
                setRestorePoint();
                publish("Applying update...");
                UPDHandler.unZipUpdate();
                saveModifiedFilesList();

            }catch(IOException ex){
                ex.printStackTrace();
            }catch(ClassNotFoundException ex){
                ex.printStackTrace();
            }finally{
                publish("Update Complete!");
            }

            return null;
        }


}

编辑:这里我的处理方法:

    protected void process(List<String> updates){
        String update = updates.get(updates.size() - 1);
        System.out.println(update);
    }

这有时有效,但有时它会完全跳过其中一个 publish() 调用。例如,当它到达永远不会真正显示在 JTextArea 上的 publish("Setting restore point...") 时,它只会跳到“Applying Update...”

当我告诉它时,如何让它准确地发布和更新 JTextArea?

4

2 回答 2

2

不要发布或处理任何内容。在您的情况下,由于您的 JTextArea 正在接收从 System.out 重定向的输出,看来您所要做的就是调用System.out.println(...)需要在 JTextArea 中显示的文本。

private class UpdateTask extends SwingWorker<Void, String>{

    @Override
    protected Void doInBackground() {
        try{
            publish("Creating backup...");
            mainBackup.createBackup();

            // publish("Setting restore point...");
            System.out.println("Setting restore point...");

            setRestorePoint();

            // publish("Applying update...");
            System.out.println("Applying update...");

            UPDHandler.unZipUpdate();
            saveModifiedFilesList();

        }catch(IOException ex){
            ex.printStackTrace();
        }catch(ClassNotFoundException ex){
            ex.printStackTrace();
        }finally{
            publish("Update Complete!");
        }

        return null;
    }
}

有关包含使用后台线程的更完整示例,请参阅此答案中的代码。

于 2013-11-05T17:17:44.790 回答
2

publish(V... chunks)用于内部doInBackground()发送数据以process(List<V> chunks)在 GUI 线程中处理它们。您错过的是覆盖 process 方法:

@Override
 protected void process(List<String> chunks) {
     for (String s : chunks) {
         textArea.append(s + "\n");
     }
 }
于 2013-11-05T17:14:11.493 回答