Как в JavaFX-приложениях, собираемых Gradle, указать относительный путь к FXML-файлу?

Пытаюсь загрузить TasksList.fxml в классе TasksListController:

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

this.rootElement = new FXMLLoader(TasksListController.class.getResource("TasksList.fxml")).load();

Из ошибки видно, что Gradle пытается искать это в build\resources:

Caused by: java.io.FileNotFoundException: D:\IntelliJ IDEA\Tutorials\JavaFX-ToDoList\build\resources\main\Presenter\Components\TaskList\TasksList.fxml

В этом ответе на англоязычном StackOverflow очень хорошо разжевано, как нужно подключать ресурсы, но увы, для Gradle этот ответ неактуален (когда Gradle нет, то class.getResource("TasksList.fxml") - путь относительно текущей директории с классом). Как же в Gradle достучаться до нужного файла?

Мой build.gradle

plugins {
  id 'application'
  id 'org.openjfx.javafxplugin' version '0.0.8'
}

group 'loc.training'
version '1.0-SNAPSHOT'

repositories {
  mavenCentral()
}

javafx {
  version = "13"
  modules = [ 'javafx.controls', 'javafx.fxml' ]
}

mainClassName = 'EntryPoint'

? Весь код приложения (репозиторий)

Недопустимые решения

Поместить TasksList.fxml в resources

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


Ответы (1 шт):

Автор решения: Andrey M

Как вариант:

  • поместить TaskCard.fxml и TaskList.fxml в src/main/resources
  • заменить в RootLayout.fxml:
<fx:include source="Presenter/Components/TaskList/TasksList.fxml" />

на

<fx:include source="TasksList.fxml" />

UPDATE: Другой вариант: добавить в build.gradle

sourceSets {
  main {
    resources {
      srcDirs "src/main/resources", "src/main/java"
    }
  }
}

UPDATE_2: Сразу оговорюсь: я не эксперт в gradle, практически им не пользуюсь и далее будет моя интерпретация.
sourceSet - наборы логически разделенных исходных файлов (код, ресурсы, зависимости), где по умолчанию уже присутствуют main и test с фильтрами по расширению (например включение только **/*.java для src/main/java). Чаще всего используется для разделения различных этапов тестирования (юнит-тесты отдельно от интеграционных, отдельно от системных) или выставления собственных фильтров на папки\файлы; например:

sourceSets {
  main {
    resources {
      srcDirs "src/main/resources", "src/main/java"
      // exclude '**/something/**'
      // include '**/something/**'
    }
  }
  integr_test {
    java {
      srcDirs "src/integr_test"
    }
  }
}

dependencies {
  integr_testImplementation('com.google.guava:guava:30.0-jre')
}
→ Ссылка