web-dev-qa-db-fra.com

Définition de feuilles de style de manière déclarative dans FXML

En HTML, nous sommes habitués aux finesses de pouvoir définir des feuilles de style par programme comme

<link rel="stylesheet" ... >

Mais les exemples de définition des feuilles de style que j’ai trouvés pour JavaFX nécessitent la définition de feuilles de style par programmation, comme

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

Est-il possible de définir des feuilles de style dans FXML de la même manière que dans HTML?

16
Chui Tey

Vous pouvez définir des feuilles de style sur les nœuds parents en utilisant:

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

Les éléments et attributs utilisables dans FXML étant dérivés de l'API Java publique JavaFX, vous pouvez également affecter des feuilles de style à un nœud parent à l'aide d'un élément de feuilles de style FXML (ou de manière interchangeable d'un attribut). Comme tous les conteneurs étendent Parent, vous pouvez définir une ou plusieurs feuilles de style personnalisées sur tout conteneur référencé dans FXML:

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import Java.net.URL?>
   ....
<?scenebuilder-stylesheet fruitcombo.css?>

<AnchorPane prefHeight="205.0" prefWidth="168.0"
   styleClass="layout"
   fx:controller="fruit.FruitComboController"
   xmlns:fx="http://javafx.com/fxml">
   <children>
      ....
   </children>
   <stylesheets>
      <URL value="@fruitcombo.css" />
   </stylesheets>
</AnchorPane>

Voir le fichier fxml dans cet exemple pour obtenir un exemple exécutable complet de référencement d'un fichier css à partir d'un fichier fxml.

Il y a un couple de Nice pour avoir des fonctionnalités dans le code ci-dessus:

Le préfixe étrange @ dans l'URL des feuilles de style n'est pas strictement nécessaire, mais peut être utilisé pour tirer parti de la résolution location de JavaFX . "L'opérateur de résolution d'emplacement (représenté par un préfixe" @ "à la valeur d'attribut) est utilisé pour spécifier qu'une valeur d'attribut doit être traitée comme un emplacement relatif au fichier actuel plutôt qu'une simple chaîne."

La ligne suivante n'est pas obligatoire au moment de l'exécution, mais elle est utilisée par l'outil SceneBuilder pour localiser la feuille de style CSS requise lors de la conception, si vous utilisez cet outil:

<?scenebuilder-stylesheet fruitcombo.css?>

Mise à jour concernant le commentaire

Avertissement: il s’agit de FXML 1.0, il ne fonctionne pas en 2.0, javafx.fxml.LoadException: l’URL n’est pas un type valide.

Ce commentaire est un peu incorrect je pense. Pour autant que je sache, il n’existe actuellement pas de FXML 2.0.

La raison pour laquelle le commentateur a reçu une exception LoadException est que l'extrait de code indicatif de cet article n'importait pas la classe Java.net.URL dans le document FXML. J'ai mis à jour l'extrait de code pour inclure l'importation Java.net.URL et en ajouter d'autres Ellipsis .... afin de clarifier l'objet de l'extrait. Un Ellipsis signifie "une série de points qui indiquent généralement l'omission intentionnelle d'un mot, d'une phrase ou d'une section entière d'un texte sans en altérer le sens original". 

Pour mieux comprendre cette réponse, il est suggéré de compiler et d’exécuter l’exemple de code lié.

Avertissement contre l'utilisation des fonctions de chargement InputStream dans FXMLLoader

Je conseille vivement de construire un nouveau FXMLLoader avec un emplacement plutôt que d'utiliser la fonction FXMLLoader.load (InputStream) . Lorsque la fonction load () statique est utilisée, les références d'emplacement relatif ne peuvent pas être résolues car il n'y a pas d'emplacement de base pour le fichier FXML.

C'est-à-dire, ne faites pas:

 InputStream input = this.getClass().getResourceAsStream("layout.fxml");
 FXMLLoader loader = new FXMLLoader.load(input);
 Parent content = loader.load();

Au lieu de faire:

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

Oui, voir par exemple les exemples 4 à 8 de ce tutoriel , en appliquant l'attribut suivant à un nœud:

stylesheets="fxmlexample/Login.css"

par exemple.

<GridPane stylesheets="fxmlexample/Login.css">
13
assylias

Si vous allez utiliser fxml avec JavaFX, vous devrez prendre un certain temps pour télécharger et utiliser SceneBuilder. Une fois que vous faites cela, l'utilisation de feuilles de style css devient simple. Bien sûr, utilisez NetBeans car avec SceneBuilder en cours d'exécution, l'ouverture du fichier dxml préconfiguré dans l'application NetBeans dxml warmplate provoque son ouverture automatique pour modification dans SceneBuilder. Une fois que vous avez extrait tout le StackPlane, le bouton, l'étiquette et les contrôles et les conteneurs de votre choix, ajoutez simplement la feuille de style directement à SceneBuilder. Dans le menu principal, sous Aperçu, vous pouvez sélectionner un menu pour les feuilles de style CSS. En le sélectionnant, un sous-menu vous permettra de charger un fichier de feuille de style.

Une fois que le fichier est chargé, les contrôles montreront que leur apparence est conforme aux règles de la feuille de style. Ils ne montreront cet aspect que si vous les sélectionnez dans la section Propriétés de SceneBuilder et déclarez que cette feuille de style est appliquée à ce contrôle. Ensuite, le style montrera quand l'application s'exécute.

0
Hal