Задача
Чтобы воспроизвести проблему и основываясь на комментариях к вопросу, требуется:
Основной класс
@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();
Этот пост стоит прочитать.