Я программирую приложение-симулятор на Java. Есть 3 разных класса. Некоторые изменения в этих классах должны изменить TextField в GUI (сделано SceneBuilder). Нажатие кнопки в gui, должно менять объекты в классах. Я сделал GUI с SceneBuilder
, я знаю, как использовать класс контроллера. Есть ли способ использовать класс контроллера для FXML
в классе объекта для изменения текста в TextField? Примерно так:
@Override
public void run() {
while (0 != 1) {
if (!stack.isEmpty())
controls.settfAI("INFECTED"); //controls is FXML controller // settfAI is id of text field
try {
sleep(3000);
} catch (InterruptedException e) {
CCLogger.cclogger(Watchman.class.getName(), Level.INFO, e);
}
}
}
Второй вопрос, могу ли я запрограммировать изменение объекта в классе управления, когда я нажимаю кнопку? Примерно так:
@FXML
Button btnOne; //btnOne is id in SceneBuilder file
//...
// AmbulanceCar ambulanceCar=new AmbulanceCar();
public void clicked() {
ambulanceCar.go(); // send ambulance car in some location
}
В моей программе много кнопок и 3 текстовых поля, которые должны изменять состояние симулятора.
ОБНОВЛЕНИЕ: У меня есть город и движущиеся люди. Когда человек заражен, Watchman должен видеть в текстовом поле позицию человека. У меня f xml с кнопками и текстовыми полями. Я знаю, что у класса Watchman должен быть Controler от f xml. Я получаю Controler с
Parent watchBtns = FXMLLoader.load(getClass().getResource("ControlGUI.fxml"));
URL contronLinkUrl=Paths.get("/ControlGUI.fxml").toUri().toURL();
FXMLLoader loader=FXMLLoader.load(contronLinkUrl);
После этого я отправляю Controler в класс Watchman с помощью
city.getWatchman().setControler(loader.getController());
В классе Watchman я пытаюсь отредактировать TextField с помощью этого кода:
public void setControler(ControlerControlGUI controlGUI)
{
controlerControlGUI=controlGUI;
System.out.println("Controler set!");
}
@Override
public void run()
{
System.out.println("Watchman started!");
while(0!=1)
{
try {
if(!stack.isEmpty())
{
controlerControlGUI.settfAI("INFECTED");
}
sleep(3000);
} catch (InterruptedException e) {
CCLogger.cclogger(Watchman.class.getName(), Level.INFO, e);
}
}
}
Теперь я получил ошибку
Вызвано: java .lang.ClassCastException: класс javafx.scene.layout.AnchorPane не может быть преобразован в класс javafx.f xml .FXMLLoader (javafx .scene.layout.AnchorPane находится в модуле javafx.graphics загрузчика app; javafx.f xml .FXMLLoader находится в модуле javafx.f xml загрузчика app)
ОБНОВЛЕНИЕ, если ответ ниже для вас сложен ... В класс контроллера вы можете помещать объекты, которые вы будете контролировать. В моем случае это примерно так:
Person infectedPerson;
Ambulance ambulance;
//call in main function
public void setInfectedInfo(Person person,Ambulance amb)
{
infectedPerson=person;
ambulance=amb;
}
В другом классе я помещаю этот код, чтобы установить тот же контроллер для f xml и класса, который будет использовать их оба
Stack<Alarm> stack= new Stack<>();
Vector<Ambulance> ambulances=new Vector<>();
ControlerControlGUI controlerControlGUI;
public void setControler(ControlerControlGUI controlGUI)
{
controlerControlGUI=controlGUI;
}
В основном классе вы можете указать:
FXMLLoader loader=new
FXMLLoader(getClass().getResource("ControlGUI.fxml"));
Parent watchBtns=loader.load();
city.getWatchman().setControler(loader.getController());
watchBtns.setLayoutX(840);
watchBtns.setLayoutY(100);
groupCity.getChildren().add(watchBtns);
Я постараюсь объяснить последнюю часть кода. Сначала вы создаете FXMLLoader с файлом f xml, в котором определен контроллер. Затем вы его загружаете. (если вы не вызываете load (), это не сработает). После этого вы должны вызвать getController, чтобы в вашей функции был такой же контроллер, и вы можете вызывать функции контроллера извне для управления своей частью GUI.