1

I've got troubles with getting access to FXML TextArea.

Main.java:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
}


    public static void main(String[] args) {
        launch(args);
    }
}

Controller.java:

package sample;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextArea;
import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable {

    @FXML
    private TextArea textArea;

    @Override
    public void initialize(URL location, ResourceBundle resources){
        new ClientRead().start();//creating and running new thread
    }

    void refreshTextArea(String text){
        if (text != null){
            this.textArea.setText(text);
        }
    }

}

ClientRead.java:

package sample;

import javafx.fxml.FXMLLoader;

import java.io.IOException;

public class ClientRead extends Thread {

    public void run(){
        refreshTextArea("content");
    }

    private void refreshTextArea(String text){

        FXMLLoader fxmlLoader = new FXMLLoader();
        fxmlLoader.setLocation(getClass().getResource("sample.fxml"));

        try {
            fxmlLoader.load();
        }catch (IOException e){
            System.out.println(e.getMessage());
        }

        Controller c = fxmlLoader.getController();
        c.refreshTextArea(text);
    }
}

sample.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <children>
      <TextArea fx:id="textArea" layoutX="39.0" layoutY="20.0" prefHeight="130.0" prefWidth="110.0" />
   </children>
</AnchorPane>

I want to get reference to textArea in ClientRead class to call setText() on it from another class, in another thread. However, I tried this method and it didn't work. I've tried to pass instance of class Controller, by using this to constructor of ClientRead as well, but the result was the same.

What am I doing wrong?

Thanks for help :)

Piotr
  • 55
  • 8
  • 1
    Please create a [MCVE](https://stackoverflow.com/help/mcve). To sum it up it is a Minimal(small amount of code) Complete(Fully runnable) Verifiable(I can put into my IDE and run without errors) Example(Recreate your problem). There is too many thing I can't see in your code such as why your calling `new ClientRead().start();` in LoggedController which builds UI with another LoggedController as the root its confusing and cyclical. Which is why you can't debug on your own. – Matt Feb 28 '19 at 14:27
  • Thanks for feedback, as You suggested, I created MCVE. I'm new here, so thanks for tips :) – Piotr Feb 28 '19 at 15:42
  • You might want to take a look to [Concurrency in JavaFX](https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm) tutorial in order to implement the background task properly. In other words, `ClientRead` should extend from `Task` not `Thread`, in order to avoid blocking the `Platform` thread and making the UI unresponsive. – dic19 Feb 28 '19 at 15:47
  • 1
    Do not initialize `sample`in `Client`. Add a constructor to `Client` that can accept a reference to `TextArea` : `new ClientRead(textarea)` or a reference to `Controller` : `new ClientRead(this)` – c0der Feb 28 '19 at 15:53

0 Answers0