web-dev-qa-db-fra.com

Comment ajouter une feuille de style CSS dans FXML

Je voudrais lier un fichier css à mon application. Dans mon fichier fxml, j'utilise ceci:

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

... et je peux voir un aperçu stylisé lorsque j'ouvre le fichier fxml dans scenebuilder. Mais lorsque j'essaie d'exécuter l'application, j'obtiens une erreur:

Java.net.MalformedURLException: pas de protocole: ../stylesheet1.css

Je l'ai donc testé de cette façon:

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

et maintenant c'est l'inverse - l'application démarre et applique le CSS, mais je ne vois pas l'aperçu dans scenebuilder. Le message d'erreur:

"Le fichier stylesheet1.css n'existe pas. Ressource stylesheet1.css introuvable."

Alors, comment puis-je joindre correctement le fichier CSS?


Eh bien, même si ma question n'a pas répondu pourquoi exactement cela ne fonctionne pas de la manière ci-dessus, j'ai trouvé une solution qui fonctionne pour moi. Dans mon FXML j'ai juste la ligne

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

donc Scenebuilder fonctionne avec ce CSS. Et dans ma classe principale, j'ai défini la feuille de style par programme:

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

Ce que j'ai trouvé une solution utilisable et fonctionnelle pour inclure le fichier css dans fxml, c'est ajouter stylesheets="@app/cssfilename.css" au nœud parent du fichier fxml comme pour le volet de pile

<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>
12
Mr.AshishGK

Voici une solution qui fonctionne dans l'environnement de développement, dans Scene Builder et dans un JAR packagé.

La structure des dossiers:

enter image description here

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:

enter image description here

Cela fonctionne à la fois dans l'environnement de développement et lorsque vous empaquetez le JAR (choisissez "Extraire les bibliothèques requises dans le JAR généré" dans Eclipse).

Capture d'écran (juste un bouton avec une icône chargée via css)

enter image description here

8
Roland

Si vous ne voulez pas le faire par programme, vous pouvez le faire en séparant le code et les ressources. J'ai une structure de projet Maven comme celle-ci, mais ce n'est pas une exigence.

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

Vous pouvez maintenant utiliser la feuille de style dans le .fxml

stylesheets="@stylesheet1.css"

ou en utilisant la balise stylesheets comme vous l'avez fait.

Il peut y avoir un avertissement dans SceneBuilder mais cela fonctionne.

3
DaRich