LoadException: Root value already specified on custom control

旧城冷巷雨未停 提交于 2019-12-11 12:59:08

问题


Example below causes

javafx.fxml.LoadException: Root value already specified.

The code is written according to example here: http://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm

Code:

public class NavigationView extends ButtonBar {

   private static final String defaultTemplate = "/fxml/navigator.fxml";

   public NavigationView() {
      this(null);
   }


   public NavigationView(URL resource) {
      //FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("custom_control.fxml"));

      if( resource == null ) {
         resource = getClass().getResource(defaultTemplate);
      }

      FXMLLoader fxmlLoader = new FXMLLoader(resource);
      fxmlLoader.setRoot(this);
      fxmlLoader.setController(this);

      try {
         fxmlLoader.load();
      } catch (IOException exception) {
         throw new RuntimeException(exception);
      }
   }

   public static class Runner extends Application {
      @Override
      public void start(Stage primaryStage) throws Exception {
         Scene scene = new Scene(new NavigationView(), 800, 600);
         primaryStage.setTitle("NavigationView");
         primaryStage.setScene(scene);
         primaryStage.show();
      }

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

If I remove line

fxmlLoader.setRoot(this);

then the view is empty, which is essential, because remains no connection between NavigationView and FXML template.

How to accomplish?

UPDATE

FXML is follows:

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>

<ButtonBar maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="38.0" prefWidth="651.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.91">
  <buttons>
    <Button fx:id="previousButton" mnemonicParsing="false" text="&lt;&lt; Previous" />
      <Button fx:id="nextButton" mnemonicParsing="false" text="Next &gt;&gt;" />
      <Button fx:id="editButton" mnemonicParsing="false" text="Edit" />
      <Button fx:id="createButton" mnemonicParsing="false" text="Create" />
      <Button fx:id="saveButton" mnemonicParsing="false" text="Save" />
      <Button fx:id="cancelButton" mnemonicParsing="false" text="Cancel" />
      <Button fx:id="deleteButton" mnemonicParsing="false" text="Delete" />
  </buttons>
</ButtonBar>

回答1:


Use a "dynamic root". The <ButtonBar> element is an instruction to the FXMLLoader to create an object from the ButtonBar class, and (since it's the root element of the FMXL file) use it as the root of the structure created. If you want to call setRoot(this), you already have an object created that is going to play that role.

So you should use:

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>

<fx:root type="ButtonBar" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="38.0" prefWidth="651.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.91">
  <buttons>
    <Button fx:id="previousButton" mnemonicParsing="false" text="&lt;&lt; Previous" />
      <Button fx:id="nextButton" mnemonicParsing="false" text="Next &gt;&gt;" />
      <Button fx:id="editButton" mnemonicParsing="false" text="Edit" />
      <Button fx:id="createButton" mnemonicParsing="false" text="Create" />
      <Button fx:id="saveButton" mnemonicParsing="false" text="Save" />
      <Button fx:id="cancelButton" mnemonicParsing="false" text="Cancel" />
      <Button fx:id="deleteButton" mnemonicParsing="false" text="Delete" />
  </buttons>
</fx:root>


来源:https://stackoverflow.com/questions/36985552/loadexception-root-value-already-specified-on-custom-control

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!