Почему я получаю javafx.fxml.LoadException, даже если путь к файлу fxml правильный

я получил

javafx.fxml.LoadException:

Когда я загружаю файл fxml, используя следующую строку кода.

AnchorPane anchorPane = (AnchorPane)loader.load()

Это мой файл fxml, за исключением операторов импорта.

<AnchorPane prefHeight="537.0" prefWidth="374.0"     xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.buddhikajay.controller.NewTransactionDialogController">
   <children>
      <GridPane hgap="5.0" layoutX="30.0" layoutY="10.0" prefHeight="544.0" prefWidth="314.0" vgap="5.0">
    <columnConstraints>
      <ColumnConstraints hgrow="SOMETIMES" maxWidth="142.0" minWidth="10.0" prefWidth="69.0" />
      <ColumnConstraints hgrow="SOMETIMES" maxWidth="226.0" minWidth="10.0" prefWidth="225.0" />
    </columnConstraints>
    <rowConstraints>
      <RowConstraints maxHeight="70.0" minHeight="10.0" prefHeight="33.0" vgrow="SOMETIMES" />
      <RowConstraints maxHeight="105.0" minHeight="10.0" prefHeight="38.0" vgrow="SOMETIMES" />
      <RowConstraints maxHeight="156.0" minHeight="10.0" prefHeight="51.0" vgrow="SOMETIMES" />
        <RowConstraints maxHeight="154.0" minHeight="10.0" prefHeight="43.0" vgrow="SOMETIMES" />
        <RowConstraints maxHeight="160.0" minHeight="10.0" prefHeight="43.0" vgrow="SOMETIMES" />
        <RowConstraints maxHeight="161.0" minHeight="10.0" prefHeight="63.0" vgrow="SOMETIMES" />
        <RowConstraints maxHeight="301.0" minHeight="10.0" prefHeight="180.0" vgrow="SOMETIMES" />
        <RowConstraints maxHeight="231.0" minHeight="10.0" prefHeight="106.0" vgrow="SOMETIMES" />
    </rowConstraints>
     <padding>
        <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
     </padding>
     <children>
        <Label text="ID" />
        <Label text="Date" GridPane.rowIndex="1" />
        <Label text="Amont" GridPane.rowIndex="2" />
        <Label text="Person" GridPane.rowIndex="4" />
        <Label text="Type" GridPane.rowIndex="3" />
        <Label text="Resolved" GridPane.rowIndex="5" />
        <Label />
        <Label text="Description" GridPane.rowIndex="6" />
        <TextField fx:id="idTextField" GridPane.columnIndex="1" />
        <TextField fx:id="dateTextField" GridPane.columnIndex="1" GridPane.rowIndex="1" />
        <TextField fx:id="amountTextField" GridPane.columnIndex="1" GridPane.rowIndex="2" />
        <TextArea fx:id="descriptionTextArea" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="6" />
        <HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="50.0" prefWidth="225.0" spacing="20.0" GridPane.columnIndex="1" GridPane.rowIndex="7">
           <GridPane.margin>
              <Insets />
           </GridPane.margin>
           <padding>
              <Insets bottom="10.0" left="20.0" right="10.0" top="10.0" />
           </padding>
           <children>
              <Button fx:id="okButton" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#okActionFired" prefHeight="25.0" prefWidth="75.0" text="Ok" />
              <Button fx:id="cancleButton" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#cancleActionFired" prefHeight="25.0" prefWidth="75.0" text="Cancle" />
           </children>
        </HBox>
        <ComboBox fx:id="typeComboBox" prefWidth="150.0" GridPane.columnIndex="1" GridPane.rowIndex="3" />
        <ComboBox fx:id="personComboBox" prefWidth="150.0" GridPane.columnIndex="1" GridPane.rowIndex="4" />
        <ComboBox fx:id="resolvedComboBox" prefWidth="150.0" GridPane.columnIndex="1" GridPane.rowIndex="5" />
     </children>
  </GridPane>
  </children>
</AnchorPane>

Компилятор жалуется, что в строке номер 1 ошибка. Я уверен, что путь к файлу fxml указан правильно. Что не так с моим кодом?

Вот полный стек ошибок

javafx.fxml.LoadException: 
/C:/Users/Buddhika/Documents/Programming/IdeaProjects/VirtualCreditDesktop/out/production/VirtualCreditDesktop/com/buddhikajay/view/NewTransactionDialog.fxml:9

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2595)
    at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:104)
    at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:928)
    at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:967)
    at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:216)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:740)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2701)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2521)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2435)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2403)
    at com.buddhikajay.controller.NewTransactionDialogController.showNewTransactionDialog(NewTransactionDialogController.java:68)
    at com.buddhikajay.controller.MainApp.start(MainApp.java:51)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821)
    at com.sun.javafx.application.LauncherImpl$$Lambda$50/1976027283.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323)
    at com.sun.javafx.application.PlatformImpl$$Lambda$46/301541210.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
    at com.sun.javafx.application.PlatformImpl$$Lambda$48/474926796.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
    at com.sun.javafx.application.PlatformImpl$$Lambda$47/1662429848.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$141(WinApplication.java:102)
    at com.sun.glass.ui.win.WinApplication$$Lambda$38/519284171.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.InstantiationException: com.buddhikajay.controller.NewTransactionDialogController
    at java.lang.Class.newInstance(Class.java:423)
    at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)
    at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:923)
    ... 23 more
Caused by: java.lang.NoSuchMethodException: com.buddhikajay.controller.NewTransactionDialogController.<init>()
    at java.lang.Class.getConstructor0(Class.java:3074)
    at java.lang.Class.newInstance(Class.java:408)
    ... 25 more

person Buddhika Jayawardhana    schedule 04.03.2015    source источник


Ответы (2)


Проблема описана в трассировке стека:

Caused by: java.lang.NoSuchMethodException: com.buddhikajay.controller.NewTransactionDialogController.()

что в основном говорит о том, что ваш класс контроллера не имеет конструктора с нулевым аргументом.

По умолчанию FXMLLoader создаст контроллер, вызвав его конструктор без аргументов. Удалите конструктор, который вы определили в классе контроллера, или удалите параметры, которые он принимает.

Если вам действительно нужно передать аргументы конструктору контроллера, вы можете создать контроллер в коде Java и передать его в FXMLLoader:

NewTransactionDialogController controller = new NewTransactionDialogController(someValue);
FXMLLoader loader = new FXMLLoader();
loader.setLocation(...);
loader.setController(controller);
AnchorPane anchorPane = loader.load();

(Используя этот код, вы должны удалить атрибут fx:controller из FXML.)

Или установите фабрику контроллера:

FXMLLoader loader = new FXMLLoader();
loader.setLocation(...);
loader.setControllerFactory(clazz -> {
    if (clazz == NewTransactionDialogController.class) {
        return new NewTransactionDialogController(someValue);
    } else {
        // default behavior:
        try {
            return clazz.newInstance();
        } catch (Exception exc) {
            throw new RuntimeException(exc);
        }
    }
});

AnchorPane anchorPane = loader.load();

(В этой версии оставьте атрибут fx:controller в файле FXML.)

person James_D    schedule 04.03.2015
comment
Большое спасибо @JAmes_D. Я создал контроллер в основном приложении и передал его в FXMLLoader, и он работает. - person Buddhika Jayawardhana; 04.03.2015
comment
Я думаю была только опечатка в fx:controller нет? Точка перед () выглядит подозрительно! - person tomsontom; 04.03.2015
comment
К сожалению, это не ЕДИНСТВЕННАЯ причина. У меня был пустой конструктор, и FXML работает очень хорошо, спасибо. Но когда я добавил обработчик ActionEvent для кнопки, меня приветствовало подобное сообщение: avafx fxml LoadException: Error resolving onAction='#handleButtonAction', either the event handler is not in the Namespace or there is an error in the script. **unknown path** - person will; 07.07.2016
comment
(...продолжение) ... Я думал, что рассматриваемый путь был путем к классам, но контроллер работает, когда #handleButtonAction не указан. СТРАННЫЙ? Да, это потому, что я вставил код для образца, нажмите кнопку, удалил пустые конструкторы, и я ТОЛЬКО (все еще) получаю сообщение об ошибке, когда указываю действие. - person will; 07.07.2016
comment
Довольно сложно вставить код, когда нет кода контроллера для вставки... Если у вас есть вопрос, отличный от вопроса ОП, вы должны опубликовать его... - person James_D; 07.07.2016

Я собирался ввести другой вопрос, как заметил @James_D для моего комментария, потому что, пока я не прочитал первую строку FXML по этому вопросу, я думал, что у меня другая проблема.

За свои грехи я сократил проблему до простого примера с одним контроллером и двумя файлами FXML. Один сработал, а второй не сработал/не сработал.

Отправной точкой является образец Netbeans "[Click me!]". Код вставлен ниже. И, сначала решение.

В качестве преамбулы позвольте мне сказать, что кажется, что все винят контроллер Java в этих ошибках загрузки. У меня была куча подобных ошибок в проекте пару лет назад. Мы исчерпали возможности отладки «controller» и, в конце концов, продвинулись вперед, перестроив экраны FXML с помощью ScendBuilder. Тогда у меня не было времени исследовать дальше.

На прошлой неделе мой прекрасно работающий экран FXML перестал загружаться, потому что мы переместили его в каталог времени выполнения (ранее он находился в области ресурсов JAR).

КЛАНК!

После 3 или 4 дней настройки того и этого я сделал комментарий о своей ошибке:

  • unknown path: 7
  • Javafx fxml LoadException: Error resolving onAction='#handleButtonAction', either the event handler is not in the Namespace or there is an error in the script.

Только в файле simple.fxml, но не в файле Scene.fxml. Файл «simple.fxml» уменьшен из файла приложения FXML, который изначально вызывал проблему. В этом исходном файле было слишком много переменных, так что чоп-кок-круп, чтобы соответствовать готовому демо.

Когда вы используете ТОЛЬКО это:

xmlns:fx="http://javafx.com/fxml"

Загрузки FXML из файлов на диске в папке вашего приложения работают так, как вы хотите (ну, во всяком случае, как я хочу). Глядя на FXML выше, он использует более «хрупкое» пространство имен, а именно.

Оригинальный FXML Queston:

  <AnchorPane ...
              xmlns="http://javafx.com/javafx/8" 
              xmlns:fx="http://javafx.com/fxml/1" ... >

Используя diff, я медленно преобразовал «simple.fxml», чтобы он был как можно ближе к «Scene.fxml», а «simple» просто не загружается. Пожалуйста, обрати внимание; всегда с одним и тем же контроллером

Загрузка FXML с другими метаданными не работала последовательно, файл FXML был перемещен. У меня нет объяснения, как это так.

Например, FXML хранится в каталоге с именем «test/resources/fxml/simple.fxml». Когда я собирал оба файла в JAR-файле проекта, «один и тот же» FXML в обоих случаях загружался и работал, как и ожидалось. Для меня есть что-то недосказанное об аспектах загрузки файла. Опять же, для меня это нежелательно, потому что значение KEY определения внешней сцены будет взаимозаменяемым.

Такого рода медвежьи ловушки в XML-разметке, которые (очевидно) не обнаруживаются инструментами разработки, такими как SceneBuilder или FXMLLoader(), являются препятствиями для прогресса в реальных проектах, у которых нет резерва для исследования эзотерических странностей вот так.

Это подтверждается нашим предыдущим проектным опытом — мне было проще повторно редактировать сложный экран с помощью SceneBuilder в целом, чем отслеживать проблемы с загрузкой, подобные этой. Призыв к действию: Диагностика при загрузке FXML -- FXML Lint будет почти обязательным требованием.


Контроллер, SimpleController.java:

  package ex.view.views;

  import java.net.URL;
  import java.util.ResourceBundle;
  import javafx.event.ActionEvent;
  import javafx.fxml.FXML;
  import javafx.fxml.Initializable;
  import javafx.scene.control.Label;

  public class SimpleController implements Initializable {

      @FXML
      private Label label;

      @FXML
      private void handleButtonAction(ActionEvent event) {
          System.out.println("You clicked me!");
          label.setText("Hello World!");
      }

      @Override
      public void initialize(URL url, ResourceBundle rb) {
          // TODO
      }    
  }

Неудачный FXML начал свою жизнь как один из архетипов Maven (я думаю), и этот файл работал нормально, пока я не переместил файлы FXML в папку и не загрузил их из InputStream.

Я отформатировал разметку AnchorPane в несколько строк для удобства чтения.

простой.fxml:

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

  <?import javafx.scene.control.Button?>
  <?import javafx.scene.control.Label?>
  <?import javafx.scene.layout.AnchorPane?>

  <AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" 
              xmlns="http://javafx.com/javafx/8.0.65" 
              xmlns:fx="http://javafx.com/fxml/1"
               fx:controller="ex.view.views.SimpleController">
      <children>
          <Button fx:id="button" layoutX="126" layoutY="90" text="Click Me!" />
          <Label fx:id="label" layoutX="126" layoutY="120" minHeight="16" minWidth="69" />
      </children>
  </AnchorPane>

Рабочая разметка FXML взята из образцов Netbeans 8.1.

Сцена.fxml:

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

  <?import java.lang.*?>
  <?import java.util.*?>
  <?import javafx.scene.*?>
  <?import javafx.scene.control.*?>
  <?import javafx.scene.layout.*?>

  <AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" 
              xmlns:fx="http://javafx.com/fxml" 
              fx:controller="ex.view.views.SimpleController">
      <children>
          <Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
          <Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
      </children>
  </AnchorPane>
person will    schedule 11.07.2016