gpt4 book ai didi

java - JavaFX 多线程导致 java.lang.IllegalStateException : Not on FX application thread

转载 作者:行者123 更新时间:2023-12-03 02:54:39 34 4
gpt4 key购买 nike

所以我得到了一个相当简单的 JavaFX 应用程序,它在按下启动按钮时创建并启动 2 个线程。我还有一个重置按钮,它应该中断线程并清除 GUI 组件。这似乎工作正常。然后我应该能够按下重置按钮,然后再次按下启动按钮来创建 2 个线程并再次启动它们。这也有效。当这些线程执行时,它们使用我的回调,将字符串返回给我的 Controller 类,然后将其添加到 ListView 中。当我第一次运行应用程序时,这工作正常,但如果我按清除然后启动,则回调在将数据添加到 ListView 时会抛出错误。 java.lang.IllegalStateException:不在 FX 应用程序线程上

据我了解,每当 main 之外的其他线程尝试更改 fx 元素时,就会抛出此错误。但为什么我第一次点击开始时可以正常工作,但点击清除然后再次开始后就不行了?这是我的代码:

/**
* Controls GUI and start threads..
*
*
*/
public class Controller implements Initializable {
@FXML
private Button btnRun;

@FXML
private Button btnReset;

@FXML
private TextArea taInput;

@FXML
private ListView<String> lwProducer;

@FXML
private ListView<String> lwConsumer;

private boolean sync;
private Buffer buffer;
private ObservableList<String> conData;
private ObservableList<String> proData;
private Thread consumerThread;
private Thread producerThread;
private Runnable producerR;
private Runnable consumerR;

/**
* Initializes elements, sets an initial value for the textbox.
*/
public void initialize(URL location, ResourceBundle resources) {
taInput.setText("The quick brown\nfox jumps over\nthe lazy dog");
btnReset.setDisable(true);
btnRun.setDefaultButton(true);
lwProducer.setStyle("-fx-focus-color: transparent;");
lwConsumer.setStyle("-fx-focus-color: transparent;");
}

/**
* Eventhandler for btnRun that will start new threads.
*
* @param e
*/
@FXML
protected void btnRun(ActionEvent e) {
System.out.println(sync);
conData = FXCollections.observableArrayList();
proData = FXCollections.observableArrayList();

buffer = new Buffer();

producerR = new Producer(new ProducerCB(), buffer, taInput.getText());
consumerR = new Consumer(new ConsumerCB(), buffer);

producerThread = new Thread(producerR);
consumerThread = new Thread(consumerR);

producerThread.start();
consumerThread.start();

btnRun.setDisable(true);
taInput.setDisable(true);
btnReset.setDisable(false);
}

/**
* Eventhandler for btnReset. If pressed, threads and all gui components
* will be cleared.
*
* @param e
*/
@FXML
protected void btnReset(ActionEvent e) {
System.out.println("Resetting");
producerThread.interrupt();
consumerThread.interrupt();
producerThread = null;
consumerThread = null;
lwProducer.getItems().clear();
lwConsumer.getItems().clear();
conData = null
proData = null
producerR = null;
consumerR = null;
btnRun.setDisable(false);
taInput.setDisable(false);
btnReset.setDisable(true);
}

/**
* Callback for producer thread. Updates the left hand listview with added
* data.
*
*
*/
private class ProducerCB implements Callback {
@Override
public void returnData(String str) {
proData.add(str);
lwProducer.setItems(proData);
}
}

/**
* Callback for consumer thread. Updates the right hand listview with read
* data.
*
*/
private class ConsumerCB implements Callback {
@Override
public void returnData(String str) {
conData.add(str); // Throws exception!!!!!!!
lwConsumer.setItems(conData);
}
}
}

堆栈跟踪

Exception in thread "Thread-7" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-7
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:236)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
at com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
at com.sun.javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:575)
at com.sun.javafx.scene.control.skin.LabeledSkinBase.handleControlPropertyChanged(LabeledSkinBase.java:204)
at com.sun.javafx.scene.control.skin.ListCellSkin.handleControlPropertyChanged(ListCellSkin.java:49)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$61(BehaviorSkinBase.java:197)
at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:103)
at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:144)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
at javafx.beans.property.StringProperty.setValue(StringProperty.java:65)
at javafx.scene.control.Labeled.setText(Labeled.java:145)
at com.sun.javafx.scene.control.skin.ListViewSkin$2.updateItem(ListViewSkin.java:319)
at javafx.scene.control.ListCell.updateItem(ListCell.java:471)
at javafx.scene.control.ListCell.lambda$new$160(ListCell.java:167)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.add(ModifiableObservableListBase.java:155)
at java.util.AbstractList.add(AbstractList.java:108)
at assignment2.Controller.addData(Controller.java:163)
at assignment2.Controller.access$2(Controller.java:162)
at assignment2.Controller$ConsumerCB.returnData(Controller.java:158)
at assignment2.Consumer.run(Consumer.java:22)
at java.lang.Thread.run(Thread.java:745)

最佳答案

与 AWT 事件调度程序线程类似,您只能在使用该 Java FX 应用程序线程时更新 JavaFx UI 组件。

参见here进一步阅读有关该主题的内容。解决此类问题的一种方法是使用 Platform.runLater() .

关于java - JavaFX 多线程导致 java.lang.IllegalStateException : Not on FX application thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40640407/

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