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

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

 

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

 scene.getStylesheets().add("/resources/shell.css"); 

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

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

 parent.getStylesheets().add("/resources/shell.css"); 

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

    ....    ....      

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

在上面的代码中有几个很好的function:

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

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

  

关于评论的更新

警告:它是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(); 

相反:

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

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

 stylesheets="fxmlexample/Login.css" 

例如

  

如果您要在JavaFX中使用fxml,则需要一些时间来下载并使用SceneBuilder。 一旦你这样做,使用css样式表变得简单。 当然,使用NetBeans,因为在SceneBuilder运行时,在NetBeans dxml样板应用程序中打开预构建的dxml文件会导致它在SceneBuilder中自动打开以进行编辑。 一旦你撕掉所有StackPlane,按钮和标签并放入你真正想要的控件和容器,只需将样式表直接添加到SceneBuilder即可。 在主菜单中的“预览”下,有一个CSS样式表的菜单选项。 选择它会弹出一个子菜单,可以加载样式表文件。

加载文件后,控件将显示为根据样式表中的规则进行换肤,直到您在SceneBuilder的属性部分中选择每个控件并将该样式表声明为应用于该控件时,它们才会显示该外观。 然后样式将在应用程序运行时显示。