[英]Why java swing does not allow changes from an ExecutorService Thread
I have a problem about my java GUI management. 我的java GUI管理有问题。 I'm making an updater but when i'm trying to edit some JText or JProgressbar from an ExecutorService Thread, nothing.. 我正在制作更新程序但是当我尝试从ExecutorService线程编辑一些JText或JProgressbar时,没有...
Why is it broken ? 它为什么坏了? This is my ControllerManager: 这是我的ControllerManager:
public class UpdateManager extends AppManager {
private final List<Controller> controllers;
@Getter private final ExecutorService worker;
@Getter private final UserInterface form;
private boolean isEnd;
public UpdateManager() {
this.controllers = new ArrayList<>();
this.form = new Form(this);
this.worker = Executors.newCachedThreadPool();
}
@Override
public void start(Controller... controllers) {
form.initialize();
this.controllers.addAll(Arrays.asList(controllers));
for(Controller controller: controllers)
controller.start();
}
@Override
public void end(boolean dispose) {
if(isEnd) return;
for(Controller controller: controllers)
controller.end();
if(dispose) form.dispose();
isEnd = true;
}
}
And here is an example when i'm trying to change some labels: 这是一个例子,当我试图改变一些标签:
/**
* Created by romain on 17/05/2015.
*/
public class ReleaseController implements Controller {
private final AppManager manager;
@Getter private final LinkedBlockingDeque<URL> files;
private Future<?> future;
private final SerializedObject<SerializedReleases> serializedReleases;
private final SerializedObject<Integer> serializedRelease, serializedTimestamp;
public ReleaseController(AppManager manager) {
this.manager = manager;
this.files = new LinkedBlockingDeque<>();
this.serializedReleases = SerializedObjectImpl.create(FileUtils.path("releases", "releases.dat"), true, null);
this.serializedRelease = SerializedObjectImpl.create(FileUtils.path("swtour", "release.int"), false, 0);
this.serializedTimestamp = SerializedObjectImpl.create(FileUtils.path("swtour", "timestamp.int"), false, 0);
}
/**
* TODO: checking local files
*/
@Override
public void start() {
this.future = manager.getWorker().submit(new Runnable() {
@Override
public void run() {
int release = serializedRelease.get();
int serverRelease = serializedReleases.get().lastRelease(AppUtils.OS);
int result = serverRelease - release;
if(result == 0 || result < 0) {
manager.getForm().alreadyUpdated(); //HERE
return;
}
for(int i=release+1;i<serverRelease;i++) {
try {
files.addLast(new URL(
FileUtils.path(Main.SERVER, "releases", AppUtils.OS.toString(), i + ".zip")));
} catch(Exception e) {
System.out.println(e.getMessage());
}
}
serializedRelease.setObject(serverRelease).write();
serializedTimestamp.setObject((int)System.currentTimeMillis()).write();
}
});
}
@Override
public void end() {
if(future != null && !future.isCancelled())
future.cancel(true);
}
}
If you saw correctly, it: 如果你看得对,它:
manager.getForm().alreadyUpdated();
Modifies my GUI : 修改我的GUI:
public void alreadyUpdated() {
content.getFirstLine().setText("");
content.getSecondLine().setText("Your client is already up-to-date!");
content.getPlayButton().setEnabled(true);
}
but nothing.. My gui is not changed ! 但没什么..我的gui没变! Thank you 谢谢
There are two problems with attempting to update a Swing data structure from another thread: 尝试从另一个线程更新Swing数据结构有两个问题:
As already noted in a comment, you need to use invokeAndWait
or invokeLater
to make your changes in the Swing event handling thread. 正如在注释中已经指出的那样,您需要使用invokeAndWait
或invokeLater
在Swing事件处理线程中进行更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.