Classe do controlador JavaFX não funciona

Eu estou realmente lutando para entender os controladores JavaFX, meu objective é escrever para um TextArea para atuar como um log.

Meu código está abaixo, mas quero poder alterar os valores ETC de outra class para a qual eu possa ligar quando necessário. Eu tentei criar uma class de controlador que se estende inicializável, mas eu não consigo fazê-lo funcionar. Alguém poderia me guiar na direção correta?

Eu quero mover o código @FXML na parte inferior para outra class e atualizar a cena.

package application; import javafx.event.ActionEvent; import javafx.scene.control.Label; import javafx.scene.control.TextArea; import java.io.IOException; import javafx.application.Application; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.stage.Stage; import javafx.scene.Parent; import javafx.scene.Scene; public class Main extends Application { @Override public void start(Stage primaryStage) { try { Parent root = FXMLLoader.load(getClass().getResource("Root.fxml")); Scene scene = new Scene(root,504,325); scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm()); primaryStage.setScene(scene); primaryStage.show(); } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { launch(args); } public Thread thread = new Thread(new webimporter()); @FXML public Label runningLabel; @FXML public TextArea txtArea; @FXML void runClick(ActionEvent event) throws IOException{ changeLabelValue("Importer running..."); thread.start(); } @FXML protected void stopClick(ActionEvent event){ changeLabelValue("Importer stopped..."); thread.interrupt(); } @FXML void changeLabelValue(String newText){ runningLabel.setText(newText); } void changeTextAreaValue(String newText1){ txtArea.setText(newText1); } } 

    Não faça da class Application um controlador. É pecado. Há outras perguntas e respostas que abordam isso, mas minhas habilidades de pesquisa não podem encontrá-las no momento.

    A razão é um pecado é:

    1. Você deve ter apenas uma instância do Aplicativo e, por padrão, o carregador fará uma nova instância, para que você acabe com dois objects de aplicativo.
    2. Referenciar os objects membros é confuso, porque o aplicativo original não possui os campos injetados @FXML, mas a instância do aplicativo criado pelo carregador possui campos de injeção @FXML.

    Além disso, conselhos não relacionados: não comece a tentar escrever o código multiencadeado até que o aplicativo tenha, pelo menos, trabalhado até o ponto em que ele exibe sua interface do usuário.

    Um logger multi-threaded para JavaFX está na resposta à maneira mais eficiente de registrar mensagens no JavaFX TextArea via encadeamentos com estruturas de log customizadas simples , embora infelizmente não seja direto em sua implementação e venha com pouca documentação.


    amostra de saída

    textlogger / Root.fxml

     < ?xml version="1.0" encoding="UTF-8"?> < ?import javafx.geometry.*?> < ?import javafx.scene.control.*?> < ?import java.lang.*?> < ?import javafx.scene.layout.*?>                   

    textlogger.ImportController.java

     package textlogger; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Label; import javafx.scene.control.TextArea; import java.io.IOException; public class ImportController { @FXML private Label runningLabel; @FXML private TextArea textArea; private WebImporter importer; @FXML void run(ActionEvent event) throws IOException { changeLabelValue("Importer running..."); if (importer == null) { importer = new WebImporter(textArea); Thread thread = new Thread( importer ); thread.setDaemon(true); thread.start(); } } @FXML void stop(ActionEvent event){ changeLabelValue("Importer stopped..."); if (importer != null) { importer.cancel(); importer = null; } } private void changeLabelValue(String newText){ runningLabel.setText(newText); } } 

    textlogger.WebImporter.java

     import javafx.application.Platform; import javafx.concurrent.Task; import javafx.scene.control.TextArea; import java.time.LocalTime; public class WebImporter extends Task { private final TextArea textArea; public WebImporter(TextArea textArea) { this.textArea = textArea; } @Override protected Void call() throws Exception { try { while (!isCancelled()) { Thread.sleep(500); Platform.runLater( () -> textArea.setText( textArea.getText() + LocalTime.now() + "\n" ) ); } } catch (InterruptedException e) { Thread.interrupted(); } return null; } } 

    textlogger.TextLoggingSample.java

     import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class TextLoggingSample extends Application { @Override public void start(Stage stage) { try { FXMLLoader loader = new FXMLLoader(); Parent root = loader.load( getClass().getResourceAsStream( "Root.fxml" ) ); Scene scene = new Scene(root); stage.setScene(scene); stage.show(); } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { launch(args); } }