почему этот код не создает панель вкладок?

#javafx #fxml

#javafx #fxml

Вопрос:

     <TabPane fx:controller="application.FXMLcontrolor" prefHeight="400.0" prefWidth="600.0" tabClosingPolicy="ALL_TABS" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.65">
  <tabs>
    <Tab text="Untitled Tab 1">
      <content>
        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
      </content>
    </Tab>
    <Tab text="Untitled Tab 2">
      <content>
        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
      </content>
    </Tab>
  </tabs>
</TabPane>
  

и контроллер выглядит следующим образом

     public class FXMLcontrolor extends TabPane
{

    public FXMLcontrolor()
    {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource( "FXMLdocument.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

        try
        {
            fxmlLoader.load();
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
}
  

и основной выглядит так:

  public class Main extends Application
{
    @Override
    public void start(Stage stage) throws IOException
    {

        FXMLcontrolor mainControllor=new FXMLcontrolor();

        stage.setScene(new Scene(mainControllor));
        stage.setTitle("Custom Control");
        stage.setWidth(400);
        stage.setHeight(400);
        stage.show();
    }

    public static void main(String[] args)
    {
        launch(args);
    }
}
  

и в результате в нем нет вкладки, почему здесь не отображается ни одна вкладка? Я использовал FXML для создания пользовательского интерфейса и контроллера, что я должен сделать? Фактически, я ищу способ управлять панелью вкладок с несколькими вкладками и несколькими элементами управления в каждой из них, но даже при реализации этого простого примера у меня возникает проблема.

введите описание изображения здесь

Комментарии:

1. Это даже не компилируется для меня.

2. Вы всегда должны включать трассировку стека (исключение), которую вы получаете в вопросе.

Ответ №1:

Если вы динамически настраиваете root с помощью

 fxmlLoader.setRoot(...);
  

вам нужно использовать <fx:root> элемент в качестве корневого элемента FXML. Смотрите документацию.

Кроме того, если вы установите контроллер в коде с

 fxmlLoader.setController(...);
  

вам не следует указывать fx:controller атрибут в файле FXML. Итак, ваш файл FXML должен быть

 <?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.layout.AnchorPane?>

<fx:root type="TabPane" prefHeight="400.0" prefWidth="600.0" tabClosingPolicy="ALL_TABS" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.65">
  <tabs>
    <Tab  text="Untitled Tab 1">
      <content>
        <AnchorPane  minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
      </content>
    </Tab>
    <Tab text="Untitled Tab 2">
      <content>
        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
      </content>
    </Tab>
  </tabs>
</fx:root>
  

Комментарии:

1. это работает, но я вижу вашу ссылку, что означают эти предложения:

2. Методы setRoot() и setController() FXMLLoader позволяют вызывающей стороне вводить значения корня документа и контроллера соответственно в пространство имен document, вместо того, чтобы делегировать создание этих значений самому FXMLLoader. Это позволяет разработчику легко создавать повторно используемые элементы управления, которые внутренне реализованы с использованием разметки, но (с точки зрения API) выглядят идентично элементам управления, реализованным программно.

3. @delsa Они имеют в виду именно то, что говорят: не уверен, что я могу многое прояснить. При вызове setRoot(..) корневой элемент задается кодом Java, а не создается FXMLLoader в соответствии с корневым элементом файла FXML. Таким образом, нет смысла указывать класс в качестве корня FXML; вместо этого вы используете <fx:root> . Аналогично, setController(...) указывает контроллер. Если вы укажете контроллер, он не будет создан FXMLLoader , поэтому нет смысла указывать FXMLLoader создать его, что и делает fx:controller атрибут.