JavaFX无法加载样式表:rootPane.getStylesheets()。add(url.toString());导致NullPointerException

时间:2017-02-09 15:07:29

标签: java css url javafx

我正在尝试使用控制器initialize方法中的以下代码加载CSS样式表:

public class Controller implements Initializable {

    @FXML BorderPane rootPane;
    @FXML TextField txtTest;
    @FXML Button btnSayHey;
    @FXML Button btnLookMa;

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        String styleFile = "res/striped-progress.css";
        URL url = getClass().getResource(styleFile);
        rootPane.getStylesheets().add(url.toString());

    }
}

然而,在启动应用程序时,会抛出javafx.fxml.LoadException并查看堆栈跟踪,我可以看到

rootPane.getStylesheets().add(url.toString());

导致NullPointerException。我的开始方法如下:

@Override
public void start(Stage primaryStage) throws Exception {


    String sceneFile = "scripts/DEV/PLAYGROUND/STYLES/res/MainView.fxml";
    Parent root = null;
    URL    url  = null;

    try
    {
        url = new File(sceneFile).toURI().toURL();
        root = FXMLLoader.load( url );
        System.out.println( "  fxmlResource = " + sceneFile );
    }
    catch ( Exception ex )
    {
        System.out.println( "Exception on FXMLLoader.load()" );
        System.out.println( "  * url: " + url );
        System.out.println( "  * " + ex );
        System.out.println( "    ----------------------------------------\n" );
        throw ex;
    }

    BorderPane page = (BorderPane) root;
    Scene scene = new Scene(page);
    primaryStage.setScene(scene);
    primaryStage.setTitle("SampleCSS App - v1.0");
    primaryStage.show();
}

控制台堆栈跟踪在这里:

    Exception on FXMLLoader.load()
  * url: file:/C:/rangedb/workspaces/UKRangeDBdemo/app_RVSW/scripts/DEV/PLAYGROUND/STYLES/res/MainView.fxml
  * javafx.fxml.LoadException: 
/C:/rangedb/workspaces/UKRangeDBdemo/app_RVSW/scripts/DEV/PLAYGROUND/STYLES/res/MainView.fxml

    ----------------------------------------

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:363)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:303)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:875)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$147(LauncherImpl.java:157)
    at com.sun.javafx.application.LauncherImpl$$Lambda$49/1545327692.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javafx.fxml.LoadException: 
/C:/rangedb/workspaces/UKRangeDBdemo/app_RVSW/scripts/DEV/PLAYGROUND/STYLES/res/MainView.fxml

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2595)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2573)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2435)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3208)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3169)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3142)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3118)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3098)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3091)
    at DEV.PLAYGROUND.STYLES.ExternalStylesSample.start(ExternalStylesSample.java:79)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821)
    at com.sun.javafx.application.LauncherImpl$$Lambda$52/897256917.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323)
    at com.sun.javafx.application.PlatformImpl$$Lambda$45/661672156.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
    at com.sun.javafx.application.PlatformImpl$$Lambda$48/1517660793.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
    at com.sun.javafx.application.PlatformImpl$$Lambda$47/128893786.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$141(WinApplication.java:102)
    at com.sun.glass.ui.win.WinApplication$$Lambda$38/1349277854.run(Unknown Source)
    ... 1 more
Caused by: java.lang.NullPointerException
    at DEV.PLAYGROUND.STYLES.Controller.initialize(Controller.java:49)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2542)
    ... 22 more
Exception running application DEV.PLAYGROUND.STYLES.ExternalStylesSample

您会注意到只是评论/删除该行 rootPane.getStylesheets().add(url.toString());中的initialize()会导致所有错误消失,但这不会加载CSS样式表。

更新

根据James_D的建议添加包结构: package structure, my package is called 'STYLES'

1 个答案:

答案 0 :(得分:0)

(感谢James_D的评论,我设法解决了自己的问题。所以这里......)

NullPointerException是由于我没有初始化MainView.fxml文件中的BorderPane对象造成的。将fxml文件中fx:id的{​​{1}}设置为BorderPane后(注意:此名称设置为rootPane,因为在我的rootPane中,我有一个Controller注入字段:

@FXML

进行此更改后,几乎所有错误都消失了。除了以下运行时警告:

@FXML Parent rootPane;

虽然CSS在运行时被应用于我的控件。事实证明,可以在“特权”中加载样式表。简单地在com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged INFO: Could not find stylesheet: file:/C:/rangedb/workspaces/UKRangeDBdemo/app_RVSW/res/striped-progress.css 对象上使用toExternalForm()的方式:

URL

换句话说,我将上面的代码行改为:

getClass().getResource("res/striped-progress.css")

rootPane.getStylesheets().add(getClass().getResource("res/striped-progress.css").toExternalForm()); 会返回toExternalForm()对象的String表示,但我不确定为什么不使用它会导致警告并使用它不会。无论哪种方式,它都有效。