JavaFX加载样式表

时间:2014-11-11 21:00:42

标签: java css javafx stylesheet

JavaFX有一个添加到控制器的方法:
public void initialize(URL url, ResourceBundle rb)

这似乎在将任何控件添加到场景之前运行,因为当我将其添加到它时:

@Override
public void initialize(URL url, ResourceBundle rb){
    String treeItemCss = getClass().getResource("/media/css/TreeItem.css").getPath();
    main.getScene().getStylesheets().add(treeItemCss);
}

CSS:

.tree-cell{
    -fx-indent: 100;
    -fx-underline: true;
}

我从这个方法中收到错误:getStylesheets()。但是,如果我将其移至OnAction并执行该操作,则不会出现错误。

所以我的问题是,是否有一个方法在所有控件添加到场景后运行,或者是一种将css添加到从用户操作创建的项目的好方法,例如按钮单击?

1 个答案:

答案 0 :(得分:1)

initialize()方法在FXMLLoader load()方法的末尾运行。由于在完成之前你没有得到对FXML根的引用,所以在那之后你很可能无法将它添加到场景中。

你可以:

在应用程序代码中将css添加到Scene中。即您可以在某处创建FXMLLoader,致电load(),然后将结果添加到Scene。只需在场景中设置css文件,或者:

将css样式表添加到根节点而不是场景(假设mainParent):

public void initialize() {
    String treeItemCss = ... ;
    main.getStylesheets().add(treeItemCss);
}

或:

观察Scene属性并在样式表更改为非空值时添加样式表:

public void initialize() {
    String treeItemCss = ... ;
    main.sceneProperty().addListener((obs, oldScene, newScene) -> {
        if (newScene != null) {
            newScene.getStylesheets().add(treeItemCss);
        }
    });
}

更新以下是演示第二个选项的完整示例。一切都在"应用程序"包:

Main.java:

package application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;


public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            BorderPane root = FXMLLoader.load(getClass().getResource("Main.fxml"));
            Scene scene = new Scene(root,400,400);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Main.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.TreeView?>
<?import javafx.scene.control.TreeItem?>

<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController" fx:id="root">
    <center>
    <TreeView>
        <root>
            <TreeItem value="Root">
                <children>
                    <TreeItem value="One"/>
                    <TreeItem value="Two"/>
                    <TreeItem value="Three"/>
                </children>
            </TreeItem>
        </root>
    </TreeView>
    </center>
</BorderPane>

MainController.java:

package application;

import javafx.fxml.FXML;
import javafx.scene.layout.BorderPane;

public class MainController {
    @FXML
    private BorderPane root ;

    public void initialize() {
        root.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
    }
}

application.css:

.tree-cell{
    -fx-indent: 100;
    -fx-underline: true;
}

请注意,您可以使用

直接在FXML文件中添加样式表
<BorderPane xmlns:fx="..." fx:controller="..." stylesheets="@application.css">

然后完全从控制器逻辑中省略它。