Как создать несколько контроллеров javafx с разными файлами fxml?

18

Я просматривал некоторые блоги и другие вопросы, связанные с stackoverflow, и я не вижу прямого ответа на мой вопрос. Я создаю javafx gui client, и я хочу, чтобы моя строка была одним контроллером в одном fxml, а затем я хочу, чтобы область содержимого была дополнительным файлом fxml. Экран входа в систему будет одним fxml, после того, как экран входа в систему будет основным содержимым приложения и будет находиться в одном fxml. Как мне это сделать?

Я просто не хочу иметь весь свой код для моего входа, меню и основного содержимого в том же файле. Это образ того, над чем я работаю:

    
задан j will 13.10.2013 в 07:38
источник
  • Некоторые примеры кода с использованием понятий из некоторых ответов на вопрос. –  jewelsea 13.10.2013 в 20:11
  • Еще один пример здесь: ссылка –  Dil 27.10.2013 в 12:16

4 ответа

26

Используйте FXML как компоненты, используя пользовательский класс java как fx: root и как fx: контроллер вашего файла FXML: Ссылка

Для этого вам нужно вызвать конструктор вашего пользовательского класса java class FXMLLoader, который загрузит ваш FXML. Преимущество заключается в изменении способа загрузки компонентов FXML.

Классический способ создания компонентов с помощью FXMLLoader с вложенными контроллерами: сначала FXML, затем контроллер для каждой части.

С помощью этого метода это: сначала контроллер, затем FXML для каждого компонента. И вы не будете загружать FXML в FXML напрямую, вы импортируете свои пользовательские классы java в FXML.

Это лучшая абстракция (не нужно знать, как реализован компонент при импорте в FXML) и помогает повторно использовать код, поскольку он похож на реализацию пользовательского виджета с поддержкой FXML. Чтобы сделать ваш компонент многоразовым, убедитесь, что ваша реализация не имеет жесткой связи с другими частями или использует IOC для этого (например, с интеграцией Spring с JavaFX). Таким образом, вы сможете самостоятельно импортировать свой компонент в любую часть вашего приложения (так же, как виджет DateInput), и вы не будете дублировать код.

В вашем случае у вас будет:

public class MenuBox extends VBox {

@FXML
private LoginBox loginBox;

@FXML
private ProfilesBox profilesBox;

public MenuBox() {
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("menu.fxml"));
    fxmlLoader.setRoot(this);
    fxmlLoader.setController(this);
    try {
        fxmlLoader.load();
    } catch (IOException exception) {
        throw new RuntimeException(exception);
    }
}

public class LoginBox extends VBox {
public LoginBox() {
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("login.fxml"));
    fxmlLoader.setRoot(this);
    fxmlLoader.setController(this);
    try {
        fxmlLoader.load();
    } catch (IOException exception) {
        throw new RuntimeException(exception);
    }
}

public class ProfilesBox extends VBox {
public ProfilesBox() {
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("profiles.fxml"));
    fxmlLoader.setRoot(this);
    fxmlLoader.setController(this);
    try {
        fxmlLoader.load();
    } catch (IOException exception) {
        throw new RuntimeException(exception);
    }
}

И вы импортируете LoginBox и ProfilesBox в menu.fxml, который управляет глобальным расположением вашей страницы:

<?import com.foo.bar.LoginBox ?>
<?import com.foo.bar.ProfilesBox ?>
<fx:root type="javafx.scene.layout.VBox"
    xmlns:fx="http://javafx.com/fxml">

<!-- Stuff here to declare the menu bar-->

    <HBox>
       <ProfilesBox fx:id="profilesBox"/>
       <LoginBox fx:id="loginBox"/>
    </HBox>

</fx:root>

login.fxml и profiles.fxml содержат только базовые компоненты.

    
ответ дан zenbeni 13.10.2013 в 08:18
  • Я как бы понимаю, что вы говорите, я просто не думаю, что получаю полную картину. Есть ли у вас более сложные примеры? –  j will 13.10.2013 в 08:28
  • И это нормально создавать собственные виджеты (т. е. ProfilesBox & LoginBox) и размещать их в файле fxml? И как выглядят файлы login.fxml и profiles.fxml? –  j will 13.10.2013 в 18:50
  • Чтобы добавить к уже прекрасному примеру, вам просто нужно убедиться, что вы импортируете свой настраиваемый элемент управления в FXML. Например. <? import com.foo.bar.LoginBox?>. –  chooks 13.10.2013 в 23:47
  • В дополнение к этому ответу, эта статья помогла: javacodegeeks.com/2013/03/javafx-2-with-spring.html –  j will 15.10.2013 в 05:09
5
  1. Вы можете включить документы FXML один внутри другого - это должно помочь вам отделить логику проектирования

  2. Это означает, что вы можете вложенные контроллеры - по одному для каждого документа.

В документации вы можете настроить свой код таким образом, чтобы логику можно было отделить, а также вызвать из корневого контроллера (если необходимо).

Надеюсь, что это поможет.

    
ответ дан Harsha R 13.10.2013 в 07:53
  • Я просмотрел документацию вложенных контроллеров, и если бы я мог видеть, что входит в include fxml, то, что находится в методе инициализации основных контроллеров, и как выглядит контроллер диалога, я думаю, что это было бы очень полезно. Я просто не понимаю, как работают мелкие детали. –  j will 13.10.2013 в 08:09
0

Мне нужно всплывающее окно с аналогичными требованиями (больше контроля над узлами и макетом).

Проработав мои рекомендации, я нашел решение, которое может быть полезно.

Сначала я создал второй документ fxml и второй контроллер (в NetBeans, New - & gt; Empty FXML ... - & gt; Использовать Java-контроллер - & gt; Создать новый ...).

Немного сложно было выяснить, как построить сцену в главном контроллере и подключить ее к контроллеру всплывающих окон.

Ссылка Передача параметров JavaFX FXML дает некоторые реальные хорошие идеи и методы.

Последний код выглядит следующим образом (надеюсь, что это может помочь кому-то):

// Anchor Pane from the popup
@FXML
AnchorPane anchorPanePopup;

@FXML
private void soneButtonAction(ActionEvent event) throws IOException {     
    Stage newStage = new Stage();
    AnchorPane anchorPanePopup = (AnchorPane) FXMLLoader.load(getClass().getResource("Popup_FXML.fxml"));
    Scene scene = new Scene(anchorPanePopup);
    newStage.setScene(scene);
    newStage.initModality(Modality.APPLICATION_MODAL);
    newStage.setTitle("Dialog Window");
    newStage.showAndWait();        
}
    
ответ дан rainer 29.12.2016 в 23:06
0
package javafxapplication11;
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.CheckBox;
import javafx.stage.Stage;

public class FXMLDocumentController implements Initializable {
@FXML
private CheckBox c1;

@FXML
private CheckBox c2;

public void clicked1(ActionEvent e) throws IOException {
Parent home_page_parent 
=FXMLLoader.load(getClass().getResource("AddDcuFXML.fxml"));
 Scene home_page_scene = new Scene(home_page_parent);
 Stage app_stage = (Stage) ((Node) e.getSource()).getScene().getWindow();
  app_stage.hide(); //optional
  app_stage.setScene(home_page_scene);
  app_stage.show();
   }
   public void clicked2(ActionEvent e) throws IOException {
   Parent home_page_parent 
    =FXMLLoader.load(getClass().getResource("ViewDCU.fxml"));
   Scene home_page_scene = new Scene(home_page_parent);
   Stage app_stage = (Stage) ((Node) e.getSource()).getScene().getWindow();
    app_stage.hide(); //optional
      app_stage.setScene(home_page_scene);
         app_stage.show();
     }
      public void clicked3(ActionEvent e) throws IOException {
     Parent home_page_parent 
   =FXMLLoader.load(getClass().getResource("ViewDCU.fxml"));
    Scene home_page_scene = new Scene(home_page_parent);
    Stage app_stage = (Stage) ((Node) e.getSource()).getScene().getWindow();
     app_stage.hide(); //optional
     app_stage.setScene(home_page_scene);
     app_stage.show();
      }
     @Override
       public void initialize(URL arg0, ResourceBundle arg1) {
        // TODO Auto-generated method stub
           } 
               }
    
ответ дан Laxmi 12.03.2018 в 01:25
  • Добро пожаловать в StackOverflow. Ответы только с кодом в них, как правило, помечены для удаления, так как они «низкого качества». Пожалуйста, прочитайте раздел справки по ответам на вопросы, затем подумайте над добавлением некоторых комментариев к своему ответу. –  Graham 12.03.2018 в 01:50