Подключенные стили в Scene Builder не найдены во время выполнения - PullRequest
0 голосов
/ 15 ноября 2018

Я создаю Pane в Scene Builder для Java 8. Мои файлы .css хранятся в /rescouces/css/app.css.Я подключаю таблицу стилей в Scene Builder и все в порядке.Но после запуска приложения я получаю исключение с ошибкой: Caused by: javafx.fxml.LoadException: Invalid resource: /../style/app.css not found on the classpath.

Как это исправить?Мне нужно каждый раз переименовывать путь к css в .fxml?

enter image description here

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="912.0" prefWidth="1368.0" styleClass="app" stylesheets="@/style/app.css" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.mypod.tablet.controller.MainController">
    <children>
        <AnchorPane fx:id="contentPane" layoutX="248.0" layoutY="138.0" stylesheets="@/style/content.css" AnchorPane.bottomAnchor="94.0" AnchorPane.leftAnchor="250.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="115.0">
            <styleClass>
                <String fx:value="block" />
                <String fx:value="content-block" />
            </styleClass>
        </AnchorPane>
    </children>
</AnchorPane>

Загрузить fxml:

FXMLLoader loader = new FXMLLoader();

this.primaryStage.setScene(new Scene(loader.load(Util.getResource("/fxml/main.fxml"))));

1 Ответ

0 голосов
/ 23 ноября 2018

Задача

Чтобы воспроизвести проблему и основываясь на комментариях к вопросу, требуется:

Основной класс

@Override
public void start(Stage stage) throws Exception {
    FXMLLoader loader = new FXMLLoader();
    Parent root = loader.load(MainApp.class.getClassLoader().getResourceAsStream("fxml/scene.fxml"));

    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.show();
}

FXML в src/main/resources/fxml/scene.fxml:

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane id="AnchorPane" stylesheets="@../styles/styles.css" prefHeight="200" prefWidth="320" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
    <children>
        <Button fx:id="button" text="Click Me!" />
    </children>
</AnchorPane>

CSS в src/main/resources/styles/styles.css

.button {
    -fx-font-size: 2em;
}

Проект выполняется, но выдается эта ошибка:

null/../styles/styles.css
com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
WARNING: Resource "../styles/styles.css" not found.

При ручном редактировании файла FXML и удалении родительских точек:

stylesheets="@/styles/styles.css"

, кажется, решает проблему и работает нормально без предупреждения, это мешает Scene Builder найти файл css, так что это не должно быть сделано.

Решение

  • Использование getResourceAsStream для извлечения файла FXML не рекомендуется, просто используйте getResource().

Это работает:

FXMLLoader loader = new FXMLLoader();
Parent root = loader.load(MainApp.class.getClassLoader().getResource("fxml/scene.fxml"));
  • Использование пустого конструктора FXMLLoader не рекомендуется, вместо этого используйте статический метод load.

Это работает:

Parent root = FXMLLoader.load(MainApp.class.getClassLoader().getResource("fxml/scene.fxml"));
  • Наконец, нет необходимости в загрузчике классов.Загрузчик классов основан на потоке, и он не знает о классе, из которого вы его извлекаете, и пытается найти его из пакета "fxml/scene.fxml".С другой стороны, Class.getResource() основывается на URL и ищет ресурс относительно класса, поэтому вам нужно указать путь к корню проекта "/fxml/scene.fxml".

Вот как это следует называть:

Parent root = FXMLLoader.load(MainApp.class.getResource("/fxml/scene.fxml"));

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

FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("/fxml/scene.fxml"));
// YourController controller = (YourController) loader.getController();
Parent root = loader.load();

Этот пост стоит прочитать.

...