gpt4 book ai didi

java - 正确管理 JavaFX 中的线程

转载 作者:行者123 更新时间:2023-11-30 07:54:44 25 4
gpt4 key购买 nike

我正在尝试调用外部命令并在生成时在 TextArea 中打印其输出。我阅读了有关 JavaFX 并发性的文档,并且我相信我已经做了我必须做的事情来使其工作。

我正在使用 Task 类来运行我的作业:

public synchronized void run(ProcessBuilder processBuilder) throws IOException, InterruptedException {
ExternalCommandRunner self = this;
Thread taskThread = new Thread(new Task<Void>() {
@Override
public Void call() throws Exception {
setActive();
try {
runningProcess = processBuilder.start();

StreamPrinter inputStream = new StreamPrinter(runningProcess.getInputStream(), self::handleLog);
StreamPrinter errorStream = new StreamPrinter(runningProcess.getErrorStream(), self::handleLog);
outputTextArea.clear();

new Thread(inputStream).start();
new Thread(errorStream).start();
runningProcess.waitFor();
return null;
} finally {
stop.fire();
setInactive();
}
}
});
taskThread.setDaemon(true);
taskThread.start();
taskThread.join();
}

private void handleLog (String line) { Platform.runLater(() -> outputTextArea.appendText(line + "\n")); }
private void setActive () { setState(STOP_ACTIVE_ICON , false) ; }
private void setInactive() { setState(STOP_INACTIVE_ICON, true) ; }
private void setState (String iconPath, boolean disableButton) {
stop.setGraphic(imageViewFromResource(iconPath, Resources.class));
stop.setDisable(disableButton);
}

但是,我遇到以下异常:

Exception in thread "Thread-5" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-5
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(Unknown Source)
at javafx.scene.Parent$2.onProposedChange(Unknown Source)
at com.sun.javafx.collections.VetoableListDecorator.setAll(Unknown Source)
at com.sun.javafx.collections.VetoableListDecorator.setAll(Unknown Source)
at com.sun.javafx.scene.control.skin.LabeledSkinBase.updateChildren(Unknown Source)
at com.sun.javafx.scene.control.skin.LabeledSkinBase.handleControlPropertyChanged(Unknown Source)
at com.sun.javafx.scene.control.skin.ButtonSkin.handleControlPropertyChanged(Unknown Source)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$61(Unknown Source)
at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(Unknown Source)
at javafx.beans.value.WeakChangeListener.changed(Unknown Source)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(Unknown Source)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(Unknown Source)
at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(Unknown Source)
at javafx.beans.property.ObjectPropertyBase.markInvalid(Unknown Source)
at javafx.beans.property.ObjectPropertyBase.set(Unknown Source)
at javafx.css.StyleableObjectProperty.set(Unknown Source)
at javafx.beans.property.ObjectProperty.setValue(Unknown Source)
at javafx.scene.control.Labeled.setGraphic(Unknown Source)
at com.dici.javafx.components.ExternalCommandRunner.setState(ExternalCommandRunner.java:66)
at com.dici.javafx.components.ExternalCommandRunner.setActive(ExternalCommandRunner.java:63)
at com.dici.javafx.components.ExternalCommandRunner.access$000(ExternalCommandRunner.java:19)
at com.dici.javafx.components.ExternalCommandRunner$1.call(ExternalCommandRunner.java:39)
at com.dici.javafx.components.ExternalCommandRunner$1.call(ExternalCommandRunner.java:36)
at javafx.concurrent.Task$TaskCallable.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

stop 只是一个按钮。我哪里做的不对?从文档来看,使用 Task 这种方式应该足够了......

最佳答案

如果我猜对了,堆栈跟踪只是表明代码中还有另一行,其中某些 UI 控件是从 FX 应用程序线程外部进行操作的 - 而这种情况一定不会发生。

应用程序代码的第一行(不是 JDK 代码)是: 在com.dici.javafx.components.ExternalCommandRunner.setState(ExternalCommandRunner.java:66)

在您的示例中,这似乎是以下几行:

stop.setGraphic(imageViewFromResource(iconPath, Resources.class));
stop.setDisable(disableButton);

如果 stop 只是一个按钮,并且方法 setState() 操纵它并从您自己的自定义线程调用,那么就会发生框架所提示的情况。

尝试将操作 UI 控件的任何内容放在 FX 应用程序线程上,就像您在 Platform.runLater(() -> { ... }) 中所做的那样handleLog 方法。

关于java - 正确管理 JavaFX 中的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32823180/

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