gpt4 book ai didi

java - 为什么 java swing 不允许从 ExecutorService 线程进行更改

转载 作者:行者123 更新时间:2023-11-29 05:05:23 25 4
gpt4 key购买 nike

我的 Java GUI 管理有问题。我正在制作一个更新程序,但是当我尝试从 ExecutorService 线程编辑一些 JText 或 JProgressbar 时,什么都没有..

为什么坏了?这是我的 Controller 管理器:

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;
}
}

这是我尝试更改一些标签时的示例:

/**
* 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);
}

}

如果你没看错的话,它:

manager.getForm().alreadyUpdated();

修改我的图形用户界面:

public void alreadyUpdated() {
content.getFirstLine().setText("");
content.getSecondLine().setText("Your client is already up-to-date!");
content.getPlayButton().setEnabled(true);
}

但什么都没有..我的图形用户界面没有改变!谢谢

最佳答案

尝试从另一个线程更新 Swing 数据结构有两个问题:

  1. Swing 并非设计为多线程安全的。您可能会破坏其数据结构。
  2. 没有任何强制它看到在另一个线程中所做的更改。它可以使用不受内存更改影响的寄存器或缓存中的值运行。

如评论中所述,您需要使用 invokeAndWaitinvokeLater 在 Swing 事件处理线程中进行更改。

关于java - 为什么 java swing 不允许从 ExecutorService 线程进行更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30546775/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com