在FXML中以声明方式设置样式表

Chu*_*Tey 17 css java javafx-2

在HTML中,我们习惯于能够以编程方式设置样式表

<link rel="stylesheet" ... >
Run Code Online (Sandbox Code Playgroud)

但是我为JavaFX设置样式表的例子需要以编程方式设置样式表,比如

scene.getStylesheets().add("/resources/shell.css");
Run Code Online (Sandbox Code Playgroud)

是否可以在FXML中设置样式表,类似于在HTML中完成的样式?

jew*_*sea 18

您可以使用以下命令在父节点上设置样式表:

parent.getStylesheets().add("/resources/shell.css");
Run Code Online (Sandbox Code Playgroud)

因为FXML中可用的元素和属性是从公共JavaFX Java API派生的,所以您还可以使用FXML样式表元素(或可互换的属性)将样式表分配给父节点.由于所有容器都扩展了Parent,您可以在FXML中引用的任何容器上设置一个或多个自定义样式表:

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import java.net.URL?>
   ....
<?scenebuilder-stylesheet fruitcombo.css?>

<AnchorPane prefHeight="205.0" prefWidth="168.0"
   styleClass="layout"
   fx:controller="fruit.FruitComboController"
   xmlns:fx="http://javafx.com/fxml">
   <children>
      ....
   </children>
   <stylesheets>
      <URL value="@fruitcombo.css" />
   </stylesheets>
</AnchorPane>
Run Code Online (Sandbox Code Playgroud)

有关从fxml文件引用css文件的完整可执行示例,请参阅此示例中的fxml文件.

上面的代码中有几个很好的功能:

@样式表URL中的奇怪前缀不是严格需要的,但可用于利用JavaFX的位置分辨率."位置解析运算符(由属性值的"@"前缀表示)用于指定属性值应被视为相对于当前文件的位置,而不是简单的字符串."

运行时不需要以下行,但如果您使用该工具,SceneBuilder工具将使用它来在设计时找到所需的css样式表:

<?scenebuilder-stylesheet fruitcombo.css?>
Run Code Online (Sandbox Code Playgroud)

关于评论的更新

警告:它是FXML 1.0,它在2.0中不起作用,javafx.fxml.LoadException:URL不是有效类型.

我认为这个评论有点不正确.据我所知,目前没有FXML 2.0这样的东西.

评论者收到LoadException的原因是因为这篇文章中的指示性片段没有将该java.net.URL类导入FXML文档.我更新了代码段以包含java.net.URL导入并添加了一些省略号....以阐明代码段的意图.一个省略号的意思是"一系列的点通常表示一个单词,句子,或从文本整段的故意遗漏而不改变了原有的意义."

为了最好地理解这个答案,建议编译并运行链接的示例代码.

警告不要在FXMLLoader中使用InputStream加载函数

我强烈建议用一个位置构建一个新的FXMLLoader,而不是使用FXMLLoader.load(InputStream)函数.当使用静态load()函数时,无法解析相对位置引用,因为FXML文件没有基本位置.

即,不要这样做:

 InputStream input = this.getClass().getResourceAsStream("layout.fxml");
 FXMLLoader loader = new FXMLLoader.load(input);
 Parent content = loader.load();
Run Code Online (Sandbox Code Playgroud)

相反:

 String url = this.getClass().getResource("layout.fxml").toExternalForm();
 FXMLLoader loader = new FXMLLoader(url);
 Parent content = loader.load();  
Run Code Online (Sandbox Code Playgroud)


ass*_*ias 13

是的,通过将以下属性应用于节点,请参阅本教程的示例4-8 :

stylesheets="fxmlexample/Login.css"
Run Code Online (Sandbox Code Playgroud)

例如

<GridPane stylesheets="fxmlexample/Login.css">
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢它比 `&lt;stylesheets&gt;&lt;/stylesheets&gt;` 方法更简洁(并且更容易找到,因为它必须在开始标签中)。 (2认同)