Search code examples
javajavafxrx-javarx-java2rx-javafx

How to get JavaFX to display API feed


My question is pretty straight forward (I'm just a recreational coder playing around with stuff). I have established a connection to an API and via the magic of RxJava I can subscribe to the json data emitted the API . I have also created a very basic GUI using FXML.

How do I make the text within TextArea = textAreaA update every time an event is emitted via subscription? Said differently, how do I make the TextArea display the API feed?

I've read the RxJavaFx-guide from cover to cover and it seems to focus more on the Fx to Rx directional flow of events :(

Here is a sample of my code:

    public class Tester extends Application{

    private static final Logger LOG = LoggerFactory.getLogger(Tester.class);

    public static void main(String[] args) throws IOException, InterruptedException{

        launch(args);

    }

    public void start (Stage primaryStage) throws Exception {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
        Parent root = loader.load();

        primaryStage.setTitle("App Window");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();


        TESTER_API.TESTER_API_Connector();       


    }

}

    public class TESTER_API {

    public static void TESTER_API_Connector() throws IOException, InterruptedException {
        StreamingEvents emissions = StreamingEventsFactory.INSTANCE.createEvents(TheseStreamingEvents.class.getName());     
        emissions.connect().blockingAwait();
        emissions.getEvents().getSomethingSpecific()
        .subscribe(event -> System.out.println(event.getSomethingSpecific()) // Here is the event that I would like to bind or otherwise push to textAreaA in the FXML controller
        ,throwable -> new Exception("GUI error!"));

    }
}

    public class FXMLDocumentController implements Initializable {

    @FXML 
    public TextArea textAreaA;

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        // TODO Auto-generated method stub

    }


}

Solution

  • My idea was to make TESTER_API call a function in FXMLDocumentController that updates textAreaA. I would recommend using Platform.runLater() to enshure thread safety.

    public class Tester extends Application{
    [...]
    
    public void start (Stage primaryStage) throws Exception {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
        Parent root = loader.load();
    
        FXMLDocumentController controller = loader.getController();
    
        primaryStage.setTitle("App Window");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    
    
        TESTER_API.TESTER_API_Connector(controller);       
    }
    

    }

    public class TESTER_API {
    
    public static void TESTER_API_Connector(FXMLDocumentController controller) throws IOException, InterruptedException {
        [...]
        emissions.getEvents().getSomethingSpecific()
        .subscribe(event -> Platform.runLater(() -> {
            controller.updateTextArea(event.getSomethingSpecific());
        }),
        throwable -> new Exception("GUI error!"));
    
    }
    

    }

    public class FXMLDocumentController implements Initializable {
    
        @FXML 
        public TextArea textAreaA;
    
        [...]
        public void updateTextArea(String string) {
            textAreaA.setText(string);
        }
    }