我有一个执行文件操作的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上,而是会跳到“应用更新...”
如何在我告诉它时准确发布和更新JTextArea?
答案 0 :(得分:2)
publish(V... chunks)
中使用 doInBackground()
将数据发送到process(List<V> chunks)
以在GUI线程中处理它们。你错过的是重写过程方法:
@Override
protected void process(List<String> chunks) {
for (String s : chunks) {
textArea.append(s + "\n");
}
}
答案 1 :(得分:2)
不要发布或处理任何内容。在您的情况下,因为您的JTextArea正在接收从System.out重定向的输出,所以您需要做的就是在需要在JTextArea中显示的文本上调用System.out.println(...)
。
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;
}
}
请参阅this answer中的代码,以获取包含后台线程使用情况的更完整示例。