[英]JTextArea not updating in real time despite attempt at correct threading
Here is another one of those 'how do I get a JTextArea to update in real time' questions. 这是“我如何获得一个JTextArea实时更新”问题中的另一个问题。 I've read every one of the existing posts, and I think that I am threading this correctly.
我已经阅读了现有的每一篇帖子,并且我认为自己对此进行了正确的处理。 However, I'm still having that same problem - my JTextArea doesn't update until the loop has finished and then it updats in one big blast.
但是,我仍然遇到同样的问题-我的JTextArea直到循环完成后才更新,然后一次刷新就更新了。 Can somebody see where I am doing this incorrectly?
有人可以看到我在哪里做错了吗? I can't see it.
我看不到 Thanks!
谢谢!
EDIT: switch the text area updating the called method. 编辑:切换文本区域更新调用的方法。 But I still have the same result!
但是我仍然有相同的结果!
private void saveImagesToDisk() {
textArea.append("\nPreparing to save photos to photos directory\n\n");
for (MediaFeedData mfd : imagesMetaDataList) {
try {
String imageURL = mfd.getImages().getLowResolution().getImageUrl();
final String filename = mfd.getId(); // just name the file using the image id from instagram
System.out.println(filename);
SaveImageFromUrl.saveImage(imageURL, filename, textArea);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Then, on in the save method, I have this: 然后,在save方法中,我有以下内容:
public class SaveImageFromUrl {
public static Boolean saveImage(final String imageUrl, String destinationFile, final JTextArea textArea) throws IOException {
String directoryName = "photos";
if (!makePhotosDirectory(directoryName, textArea)) {return false;}
File file = new File(directoryName, destinationFile);
URL url = new URL(imageUrl);
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(file);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.close();
new Thread() {
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textArea.append(imageUrl + " written to photos directory\n");
}
});
}
}.start();
return true;
}
Both the for loop and the code in the method below need to be called in a background thread, and this you're not doing. for循环和下面方法中的代码都需要在后台线程中调用,而您无需这样做。
if (SaveImageFromUrl.saveImage(imageURL, filename, textArea)) {
Just using a background thread will not help if the time-intensive code is not the code that is called in the background. 如果耗时的代码不是在后台调用的代码,仅使用后台线程将无济于事。
Consider using a SwingWorker, something like,... 考虑使用SwingWorker,类似...
private void saveImagesToDisk() {
textArea.append("\nPreparing to save photos to photos directory\n\n");
final SwingWorker<Void, String> imageWorker = new SwingWorker<Void, String>() {
@Override
protected Void doInBackground() throws Exception {
for (MediaFeedData mfd : imagesMetaDataList) {
final String imageURL = mfd.getImages().getLowResolution().getImageUrl();
final String filename = mfd.getId();
System.out.println(filename);
String textToPublish = "";
if (SaveImageFromUrl.saveImage(imageURL, filename, textArea)) {
textToPublish = filename + " written to photos directory\n";
} else {
textToPublish = filename + " not saved!\n";
}
// publish String so it can be used in the process method
publish(textToPublish);
}
return null;
}
@Override
protected void process(List<String> chunks) {
// Strings sent to the EDT by the publish method
// This called on the Swing event thread.
for (String chunk : chunks) {
textArea.append(chunk);
}
}
};
imageWorker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
try {
// need to call this on the event thread
// to catch any exceptions that have occurred int he Swing Worker
imageWorker.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
// TODO catch exceptions buried in this guy
e.printStackTrace();
}
}
}
});
// run our SwingWorker
imageWorker.execute();
}
For more details, please read Concurrency in Swing . 有关更多详细信息,请阅读Swing中的并发 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.