Как работать с элементами(Label, TextView и т.д), контроллера из другого класса(не из другой сцены, а из другого класса!)
Ох, боже, столько ответов, а все не уточняют, как правильно манипулировать элементами контроллера в java классе. Допустим я не хочу работать в Controller-е, так как как это не удобно. Я подготовил небольшой проект, у меня есть сценка, где при нажатии кнопки, он считывает это нажатие в Controllere и передаёт обработку уже в другой класс Test.java, где есть метод test(), он меняет LabelTest("Тест"), на ("Тест прошёл успешно"). Но появляется ошибка NullPointerException.
Код:
package application;
import javax.print.DocFlavor.URL;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
java.net.URL fxmlURL = getClass().getResource("xmlFiles/oneOkon.fxml");
Parent root = FXMLLoader.load(fxmlURL);
Scene scene = new Scene(root);
primaryStage.setTitle("Hello world");
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
package application;
import javafx.fxml.FXML;
import javafx.event.ActionEvent;
import javafx.scene.control.Label;
public class MainController {
@FXML
private Label LabelTest;
public Label getLabelTest() {
return LabelTest;
}
@FXML
public void buttonTest(ActionEvent event) {
Test.test();
}
}
package application;
public class Test {
public static void test() {
MainController t = new MainController();
t.getLabelTest().setText("Тест прошёл успешно");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.text.Font?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController">
<top>
<Label fx:id="LabelTest" prefHeight="76.0" prefWidth="503.0" text="Тест" BorderPane.alignment="CENTER">
<font>
<Font size="30.0" />
</font>
</Label>
</top>
<center>
<Button mnemonicParsing="false" onAction="#buttonTest" prefHeight="187.0" prefWidth="526.0" text="Проверка" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
Ответы (1 шт):
Тот экземпляр MainController, который создан в Test.test() не имеет ничего общего с тем, который отвечает за то, что на экране.
У вас есть несколько вариантов:
Передать в метод test Consumer
new Consumer<String>() { @Override public void accept(String s) { LabelTest.setText(s); }});
А уже в самом методе тест, передать нужную строку
public void test(Consumer<String> consumer) {
consumer.accept("Тест прошёл успешно");
}
Могут возникнуть осложнения, если сам тест будет проходить в другом потоке, но это уже другой вопрос.
Если test() исполняется синхронно, то самое простое вернуть из него результат исполнения в качестве строки или более сложного объекта и уже в контроллере присвоить этот результат в LabelTest
@FXML public void buttonTest(ActionEvent event) { LabelTest.setText(Test.test()); } public String test() { // Do Job return "Тест прошёл успешно"; }Самый топорный вариант это в тест передать сам контроллер. Если вы это делаете в качестве какого-то задания, то избегайте такой вариант.
@FXML public void buttonTest(ActionEvent event) { Test.test(this); } public static void test(MainController t) { t.getLabelTest().setText("Тест прошёл успешно"); }
У Fx так же есть классы SimpleStringProperty и подобные. Можно привязать значение текста в LabelTest к значению SimpleStringProperty и передавать/менять его. Чем-то похоже на первый вариант.