在运行时找不到 Scene Builder 中的连接样式
Connected styles in Scene Builder is not found in runtime
我在 Scene Builder 中为 Java 创建了 Pane
8。我的 .css
文件存储在 /rescouces/css/app.css
中。我在 Scene Builder
中连接样式表,一切正常。但是在我启动我的应用程序后,出现错误异常:
Caused by: javafx.fxml.LoadException: Invalid resource: /../style/app.css not found on the classpath
.
如何解决这个问题?我每次都需要在 .fxml
?
中将路径重命名为 css
<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"))));
问题
为了重现问题,并根据问题的评论,这是必需的:
主要class
@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();
}
src/main/resources/fxml/scene.fxml
下的 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"));
- 终于不用classloader了。 class 加载程序是基于流的,它不知道您从中检索它的 class 并尝试从包
"fxml/scene.fxml"
中定位。另一方面,Class.getResource()
是基于 URL 的,它查找相对于 class 的资源,因此您需要将路径设置为项目的根目录 "/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();
这篇post值得一读。
我在 Scene Builder 中为 Java 创建了 Pane
8。我的 .css
文件存储在 /rescouces/css/app.css
中。我在 Scene Builder
中连接样式表,一切正常。但是在我启动我的应用程序后,出现错误异常:
Caused by: javafx.fxml.LoadException: Invalid resource: /../style/app.css not found on the classpath
.
如何解决这个问题?我每次都需要在 .fxml
?
css
<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"))));
问题
为了重现问题,并根据问题的评论,这是必需的:
主要class
@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();
}
src/main/resources/fxml/scene.fxml
下的 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"));
- 终于不用classloader了。 class 加载程序是基于流的,它不知道您从中检索它的 class 并尝试从包
"fxml/scene.fxml"
中定位。另一方面,Class.getResource()
是基于 URL 的,它查找相对于 class 的资源,因此您需要将路径设置为项目的根目录"/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();
这篇post值得一读。