How to add a CSS stylesheet in FXML

不打扰是莪最后的温柔 提交于 2019-12-17 16:27:59

问题


I'd like to link a css file to my application. In my fxml file I use this:

  <stylesheets>
    <URL value="@../stylesheet1.css" />
  </stylesheets>

...and I can see a styled preview when I open the fxml file in scenebuilder. But when I try to run the application I get an error:

java.net.MalformedURLException: no protocol: ../stylesheet1.css

So I tested it this way:

<stylesheets>
    <String fx:value="stylesheet1.css" />
</stylesheets>

and now it's other way round - the application starts and applies the css, but I don't see the preview in scenebuilder. The error message:

"The file stylesheet1.css doesn't exist. Resource stylesheet1.css not found."

So how do I attach the css file properly?


Well, although my question wasn't answered why exactly it doesn't work the above way, I found a solution that works for me. In my FXML I have just the line

<?scenebuilder-stylesheet ../stylesheet1.css?>

so Scenebuilder works with that css. And in my main class I set the stylesheet programmatically:

Scene scene = new Scene(root);
String css = this.getClass().getResource("../stylesheet1.css").toExternalForm(); 
scene.getStylesheets().add(css);

回答1:


What I found usable and working solution to include css file in fxml is add stylesheets="@app/cssfilename.css" to the parent node of the fxml file just as for stack pane

<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.fxml.SettingsController" stylesheets="@app/cssfilepath.css">

......
.....
.....
</StackPane>



回答2:


Here's a solution that works in the development environment, in Scene Builder and in a packaged JAR.

The folder structure:

Main.java:

package application;

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


public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {

            FXMLLoader loader = new FXMLLoader(Main.class.getResource("view/RootLayout.fxml"));
            AnchorPane rootLayout = (AnchorPane) loader.load();

            Scene scene = new Scene(rootLayout, 400, 400);
            scene.getStylesheets().add(getClass().getResource("css/application.css").toExternalForm());

            primaryStage.setScene(scene);
            primaryStage.show();

        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

RootLayout.fxml:

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

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.view.RootLayoutController">
   <children>
      <Pane layoutX="0.0" layoutY="0.0" prefHeight="200.0" prefWidth="200.0">
         <children>
            <Button fx:id="sunButton" layoutX="74.0" layoutY="88.0" mnemonicParsing="false" onAction="#handleSunButtonClick" styleClass="sun-button" stylesheets="@../css/toolbar.css" text="Button" />
         </children>
      </Pane>
   </children>
</AnchorPane>

RootLayoutController.java:

package application.view;

import javafx.fxml.FXML;
import javafx.scene.control.Button;

public class RootLayoutController {


    @FXML
    Button sunButton;

    @FXML
    public void handleSunButtonClick() {
        System.out.println( "Button clicked");
    }
}

toolbar.css:

.sun-button {
  -fx-graphic: url('./icons/sun.png');
}

application.css:

.root {
    -fx-background-color:lightgray;
}

sun.png:

This works in both the development environment and when you package the JAR (choose "Extract required libraries into generated JAR" in Eclipse).

Screenshot (just a button with an icon loaded via css)




回答3:


If you don't want to do it programmatically, you can do it by separating code and resources. I have a Maven project structure like this, but this is not a requirement.

src/main/java/${packageName}
    MainWindow.fxml
src/main/resources/${packageName}
    stylesheet1.css

Now you can use the stylesheet in the .fxml

stylesheets="@stylesheet1.css"

or by using the stylesheets tag as you did.

There may be a warning in SceneBuilder but it works.




回答4:


If you re using SceneBuilder as the original questioner is, just add the css style sheet to SceneBuilder. Under Preview, select the item relating to style sheets and a submenu will provide an item to add a css style sheet. Beware though, as the style will show up on the controls in the work area and the SceneBuilder preview but will not show when the application is run. You still have to select each control and select the style sheet under that control's ;properties before the control will show the style when the application is run.

I would further suggest that if Nathan Tuggy has nothing more intelligent to add than his rather childish comment that he should return to his customary regimen of autoeroticism and video games.



来源:https://stackoverflow.com/questions/23975897/how-to-add-a-css-stylesheet-in-fxml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!