Передача параметров между экранами в JavaFX/FXML/SceneBuilder

Я пытаюсь создать простую программу проверки концепции, используя SceneBuilder и FXML, состоящую из двух экранов. Первый экран — это просто текстовое поле и кнопка, которая переводит вас на второй экран, а второй экран имеет только метку, которая, в идеале, будет отображать все, что было внутри текстового поля, когда была нажата кнопка. Каждый экран имеет свой файл FXML и собственный контроллер. Я читал сверху, снизу и сбоку о FXMLLoader, так как мои исследования показывают, что это идеальный способ сделать это, но я до сих пор не могу понять, как правильно его использовать. В конечном счете, я хотел бы реализовать это на своего рода предигровом экране «создания персонажа» для ролевой игры, где выбор статов/инвентаря игроков перемещается с начального экрана либо на модель для расчета/обработки, либо ко второму контроллеру экранов для отображения.


person Fgsfds    schedule 30.05.2015    source источник
comment
2 экрана изначально открыты? или второй экран открывается по нажатию кнопки?   -  person Mohamed Benmahdjoub    schedule 30.05.2015
comment
Второй экран настроен на открытие при нажатии кнопки.   -  person Fgsfds    schedule 31.05.2015
comment
См. stackoverflow.com/questions/14187963/   -  person James_D    schedule 31.05.2015
comment
Спасибо @James_D, дело в том, что я это читал и до сих пор не совсем понял. Я нигде не нашел хорошего описания синтаксиса FXMLLoader и того, как я могу использовать его для получения доступа к переменным одного контроллера из другого или для доступа к переменным контроллера из класса, не являющегося контроллером. Я знаю, что создаю новый FXMLLoader, который использует getClass и getResources для получения другого файла FXML, и что в строке ниже я должен каким-то образом получить контроллер, но именно здесь я теряю след.   -  person Fgsfds    schedule 31.05.2015
comment
Синтаксис такой же, как и для любого другого объекта Java; это просто Ява. Вероятно, вам нужно опубликовать код, чтобы показать, что вы делаете.   -  person James_D    schedule 31.05.2015
comment
Должен ли я сделать это в новом вопросе или я могу процитировать код в комментариях? (Достаточно ли места в комментарии для этого?) Извините, если я человек с миллионом вопросов и только спорадическими знаниями, я пытаюсь самообучаться с помощью свободно доступных средств, и это только одна часть, которую я просто не могу разобраться без чьей-либо помощи, поэтому я глубоко благодарен вам. Исходя из того, что я понимаю из ответа corpico ниже, мне нужно создать новые FXMLLoaders, поскольку они являются объектами, а затем позже, в классе, в котором я создал этот объект, я могу использовать nameofloader.fxidofUIelement.dosomething()?   -  person Fgsfds    schedule 31.05.2015


Ответы (1)


Хорошо, это своего рода ответ, потерпите меня, я нашел видео некоего Сахила Гусейнзаде, которое, я думаю, наконец-то сделало этот щелчок для меня. Я думал, что мог бы использовать FXMLLoader как своего рода импорт, который я мог бы каким-то образом использовать во время создания моего контроллера для доступа к другим контроллерам по желанию. Я скопировал ниже некоторый код, который я получил, работая с FXMLLoader, с некоторыми комментариями, относящимися к тому, как, по моему мнению, работает FXMLLoader. Извините, если объяснения тупые или плохо сформулированы с технической точки зрения, или если я был новичком/болваном на протяжении всего этого. Однако у меня был еще один вопрос, я ожидаю, что задавать его в ответе нехорошо, есть ли способ сделать так, чтобы информация динамически обновлялась в окнах? Например, могу ли я сделать так, чтобы в одном окне была кнопка броска кубиков, чьи результаты автоматически появлялись в другом окне?

package twoscreentest;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

public class Screen1Controller implements Initializable {

    @FXML
    public Label label;
    @FXML
    public Button button;
    @FXML
    private TextField textCharName;

    public String testtext;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        label.setText(Byte.toString((byte) (Math.floor(Math.random()*6)+1)));
    }    

    @FXML
    private void btnSend(ActionEvent event) throws IOException {
        PlayerInfo player = new PlayerInfo(textCharName.getText(), Double.parseDouble(label.getText()));  // Creating the temporary container.
        //((Node)event.getSource()).getScene().getWindow().hide(); This is to close the previous window, for testing it was easier to disable it.
        FXMLLoader loader = new FXMLLoader(); // Creating a the FXMLLoader
        loader.setLocation(getClass().getResource("Screen2.fxml")); // Telling it to get the proper FXML file.
        loader.load(); // Loading said FXML.
        Parent p = loader.getRoot(); // Setting up the window, I think I get how this works,
        //probably...
        Stage stage = new Stage();
        stage.setScene(new Scene(p));
        Screen2Controller screen2controller = loader.getController(); // This right here I 
        //don't entirely get, I know that I'm using the loader to get the controller, but
        //what's with the "NameofControllerClass variablename"?
        screen2controller.setCurrentInfo(player); // Setting the empty container in
        // the second class' variables to the ones in the the temporary container that
        // I created earlier.
        screen2controller.testlabel.setText(testtext); // An additional test, setting a label
        // on the second screen to a variable I set in this controller with a separate button.
        stage.show(); // Create the second screen.

    }

    @FXML
    private void btnSend2(ActionEvent event) {

        testtext = "Hello world";
    }

}
person Fgsfds    schedule 31.05.2015