JavaFX .getChildren()。add(root)抛出java.lang.IllegalStateException

时间:2012-07-03 11:43:51

标签: java user-interface javafx-2

我有问题,当我想从其他线程向我的GUI添加节点时。它抛出IllegalStateException,我不知道如何解决它。

public class DashBoardController implements Initializable {
    @FXML
    private FlowPane dashBoardPane;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
    try {
        RTMClientV2 client = new RTMClientV2("localhost", 9009, new DashBoardArranger(this));
        Thread clientTH = new Thread(client);
        clientTH.start();
    } catch (IOException ex) {
        Logger.getLogger(DashBoardController.class.getName()).log(Level.SEVERE, null, ex);
    }
    }        

    public synchronized void addToDashBoard(Pane root){
        dashBoardPane.getChildren().add(root);
    }
}

我只是使用此控制器将我的.FXML文件加载到GUI,当程序启动时,运行Thread负责与服务器的通信(clientTH.start();),一切正常。但是当服务器在init之后发送数据。我希望这些数据添加到我的仪表板,我使用方法public synchronized void addToDashBoard(Pane root),但它抛出java.lang.IllegalStateException并且我不知道为什么。

btw:我发现这个:“如果这个Parent节点附加到一个Scene,那么它的子列表只能在JavaFX Application Thread上修改。如果违反了这个限制,就会抛出IllegalStateException。”,但它对我没用。仪表板已添加到我的GUI中的另一个窗格中。

btw:输出:

  

线程“Thread-4”中的异常java.lang.IllegalStateException:不在FX应用程序线程上; currentThread = Thread-4
      at com.sun.javafx.tk.Toolkit.checkFxUserThread(Unknown Source)
      at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(Unknown Source)
      在javafx.scene.Parent $ 1.onProposedChange(未知来源)
      at com.sun.javafx.collections.VetoableObservableList.add(Unknown Source)
      at com.sun.javafx.collections.ObservableListWrapper.add(Unknown Source)
      在probeobserver.gui.probeSite.DashBoardController.addToDashBoard(DashBoardController.java:125)
      在probeobserver.gui.probeSite.DashBoardArranger.setCompName(DashBoardArranger.java:66)
      at probeobserver.rtm.RTMClientV2.readAllDataAndUpdate(RTMClientV2.java:144)
      在probeobserver.rtm.RTMClientV2.run(RTMClientV2.java:80)
      在java.lang.Thread.run(Thread.java:722)

1 个答案:

答案 0 :(得分:4)

在您的I / O线程中,您需要与UI线程中的UI进行交互:

Platform.runLater(new Runnable() {
    @Override
    public void run() {
        Pane root = ...; //if you set any properties of the pane, do it here.
        dashBoardController.addToDashBoard(root);
    }
}