Les Vues en Ntro et JavaFx #
Les fichiers d’une Vue #
-
Il y a trois fichiers à fournir pour créer une vue:
-
un fichier
.xml
au format FXML (obligatoire) -
un fichier
.css
(optionnel) -
un fichier
.properties
qui contient des traductions (optionnel) -
Le format FXML est spécifique à JavaFx
-
en FXML, on peut décrire la vue avec des balises, un peu comme en HTML
-
p.ex. pour ajouter un bouton:
<Button> </Button>
-
Le
.css
permet de modifier l’apparence des éléments affichés (comme en HTML) -
Le fichier
.properties
contient du texte à afficher -
des fichiers
.properties
additionnels permettent de supporter d’autres langues
Exemples de fichiers FXML #
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.StackPane?>
<StackPane xmlns:fx="http://javafx.com/fxml"
fx:controller="pong.frontal.vues.VueRacine">
</StackPane>
- La première ligne est obligatoire
<?xml version="1.0" encoding="UTF-8"?>
- Ensuite, il faut importer chaque balise qu’on utilise
<?import javafx.scene.layout.StackPane?>
-
(comme si on importait une classe)
-
La première balise doit avoir les attributs
-
xmlns:fx
<StackPane xmlns:fx="http://javafx.com/fxml"
- (c’est comme ça qu’on indique qu’il s’agit de FXML)
-
fx:controller
fx:controller="pong.frontal.vues.VueRacine">
- où on déclare la classe Java de la Vue
- (ce que JavaFx nomme
controller
,Ntro
appelle plutôt la Vue)
- (ce que JavaFx nomme
- où on déclare la classe Java de la Vue
- Autre exemple:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>
<VBox xmlns:fx="http://javafx.com/fxml"
fx:controller="pong.frontal.vues.VueFileAttente">
<Button></Button>
</VBox>
-
On voit que dans la balise racine
VBox
, y a une baliseButton
-
En fait, on doit tout mettre dans la balise racine
-
(ou dans une balise qui est dans la balise racine)
-
(ou dans une balise qui est dans une balise qui est dans la balise racine)
-
(etc.)
Structure d’une Vue en FXML #
-
Chaque balise correspond à un noeud (un élément graphique)
-
Certains noeuds sont des éléments simple (p.ex. un Bouton)
-
D’autres noeuds sont des conteneurs
- un conteneur est une région rectangulaire qui contient des noeuds
-
Le conteneur est le parent et les noeuds contenus sont les enfants du conteneur
- un enfant est soit un élément ou un autre conteneur
-
Chaque conteneur est responsable de:
- placer chaque enfants dans l’espace
- calculer la taille de chaque enfant
- (en fonction p.ex. de propriétés comme
-fx-min-width
et-fx-max-width
)
- (en fonction p.ex. de propriétés comme
Exemples de conteneurs JavaFx #
-
- affiche un seul enfant et lui donne toute l’espace
- NOTES:
- en fait le
StackPane
affiche un avant-plan et un ou des arrières plans - on va l’utiliser uniquement pour l’avant-plan (un seul enfant)
- en fait le
-
- place ses enfants du haut vers le bas, verticalement
-
Il y a en plein d’autre
- voir la liste des sous-classes de
Pane
- voir la liste des sous-classes de
Quelles sont les balises valides? #
-
Chaque classe graphique JavaFx est une balise
- P.ex. la classe
Button
du paquetjavafx.scene.control
- (et plusieurs autres classes du paquet
javafx.scene
)
- P.ex. la classe
-
On peut créer une balise personalisée en héritant d’une classe graphique
- P.ex.
class MonBouton extends Button
va créer la balise<MonBouton>
- P.ex.
-
Une bonne façon d’explorer le FXML est d’utiliser l’outil SceneBuilder
- C’est un outil graphique pour créer des Vues en FXML
- L’outil sauvegarde en
.fxml
- On peut alors inspecter les balises utilisées
-
ATTENTION
- il faut utiliser l’extension
.fxml
pour utiliser SceneBuilder - l’outil SceneBuilder a aussi tendance à générer du
.xml
touffu - SVP ne pas utiliser ce
.xml
directement dans votre projet
- il faut utiliser l’extension
Le CSS en JavaFx #
-
Comme pour HTML, le CSS de JavaFx a les notions de
- sélecteur, p.ex:
#id
et.class
- propriétés, p.ex.
-fx-backgroundcolor:gray
- sélecteur, p.ex:
-
ATTENTION
- Les propriétés CSS ne sont pas les mêmes qu’en HTML
- En JavaFx, les propriétés commencent par
-fx-
- Voici le guide complet du CSS en JavaFX
- En JavaFx, les propriétés commencent par
- Les propriétés CSS ne sont pas les mêmes qu’en HTML
-
Pour utiliser le CSS, il faut ajouter des attributs aux balises
id
pour l’identifiant CSSstyleClass
pour spécifier la class CSS (et nonclass
)
-
Par exemple
<VBox xmlns:fx="http://javafx.com/fxml" fx:controller="pong.frontal.vues.VueFileAttente" styleClass="conteneur" id="vue-file-attente"> <Button styleClass="gros-bouton" id="bouton-s-inscrire"> </Button> </VBox>
-
Finalement, il faut déclarer votre CSS dans le Frontal
public class FrontalPong implements FrontendFx {
@Override
public void registerViews(ViewRegistrarFx registrar) {
registrar.registerStylesheet("/style/dev.css");
//registrar.registerStylesheet("/style/prod.css");
}
}
Les traductions en JavaFx #
-
Un fichier
.properties
contient des paires variable/valeur de la formesInscrire=S'inscrire retour=Retour
- NOTES:
- la variable est avant le
=
(p.ex.sInscrire
etretour
) - la valeur est après le
=
(sans"
)
- la variable est avant le
- NOTES:
-
On peut utiliser ce texte en FXML avec
%variable
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.layout.VBox?> <?import javafx.scene.control.Button?> <VBox xmlns:fx="http://javafx.com/fxml" fx:controller="pong.frontal.vues.VueFileAttente"> <Button text="%sInscrire"> </Button> </VBox>
-
Il faut déclarer des fichier
.properties
dans le Frontal:public class FrontalPong implements FrontendFx { @Override public void registerViews(ViewRegistrarFx registrar) { // Langue par défaut registrar.registerDefaultLocale(Ntro.buildLocale("fr")); // Traductions registrar.registerTranslations(Ntro.buildLocale("fr"), "/traductions/fr.properties"); registrar.registerTranslations(Ntro.buildLocale("en"), "/traductions/en.properties"); } }
Déclarer des Vues en Ntro #
-
Créer d’abord une classe qui hérite de
ViewFx
public class VueRacine extends ViewFx { @Override public void initialize() { } }
- NOTES:
- la méthode
initialize
est requise - on va l’utiliser dans le module 4
- la méthode
- NOTES:
-
Déclarer la Vue dans le Frontal
import pong.frontal.vues.VueRacine; public class FrontalPong implements FrontendFx { @Override public void registerViews(ViewRegistrarFx registrar) { registrar.registerView(VueRacine.class, "/vues/racine.xml"); } }
-
S’assurer que l’attribut
fx:controller
est correct:fx:controller="pong.frontal.vues.VueRacine">
-
doit être le nom complet de la classe, comme dans un
import
import pong.frontal.vues.VueRacine;
-
-
(Optionnel) on peut aussi déclarer un fichier CSS
registrar.registerStylesheet("/style/dev.css");
-
(Optionnel) on peut aussi déclarer des traductions
registrar.registerTranslations(Ntro.buildLocale("fr"), "/traductions/fr.properties"); registrar.registerTranslations(Ntro.buildLocale("en"), "/traductions/en.properties");
Charger une Vue avec une tâche viewLoader(...)
#
-
S’assurer d’enregistrer la Vue dans le Frontal
registrar.registerView(VueRacine.class, "/vues/racine.xml");
-
Une fois la vue enregistrée,
Ntro
va créer la tâcheviewLoader(VueRacine.class)
-
Ensuite, on peut utiliser la tâche dans le graphe de tâches
Créer une Vue avec une tâche create(...)
#
-
On a besoin d’un objet
ViewLoader<VueRacine>
pour créer la Vue -
On ajoute une dépendance à une tâche
viewLoader(VueRacine.class)
tasks.task(create(VueRacine.class)) .waitsFor(viewLoader(VueRacine.class)) .executesAndReturnsValue(inputs -> { ViewLoader<VueRacine> viewLoader = inputs.get(viewLoader(VueRacine.class)); VueRacine vueRacine = viewLoader.createView(); return vueRacine; });
- NOTES:
- une tâche de type
create(...)
retourne un résultat - comme la tâche est de type
create(VueRacine.class)
, il faut retourner un objet de typeVueRacine
- une tâche de type
- NOTES:
Afficher la Vue racine en Ntro #
-
La Vue racine s’affiche à même la fenêtre
-
On ajoute une dépendance à la tâche
window()
tasks.task("installerVueRacine") .waitsFor(window()) .waitsFor(created(VueRacine.class)) .executes(inputs -> { VueRacine vueRacine = inputs.get(created(VueRacine.class)); Window window = inputs.get(window()); window.installRootView(vueRacine); });
Afficher une page en Ntro #
-
Une page (ou sous-vue) va s’afficher à l’intérieur de la
VueRacine
-
Dans la
VueRacine
, on a besoin d’une méthode qui installe une sous-vuepublic class VueRacine extends ViewFx { public void afficherSousVue(ViewFx sousVue) { Pane racineSousVue = sousVue.rootNode(); rootNode().getChildren().clear(); rootNode().getChildren().add(racineSousVue); } }
- NOTES:
rootNode()
retourne la conteneur racine (ou balise racine) de la vue- notre
VueRacine
place la sous-vue directement à la racine
- NOTES:
-
Ensuite, on a une tâche pour afficher la page
tasks.task("installerVueFileAttente") .waitsFor(created(VueRacine.class)) .waitsFor(created(VueFileAttente.class)) .executes(inputs -> { VueRacine vueRacine = inputs.get(created(VueRacine.class)); VueFileAttente vueFileAttente = inputs.get(created(VueFileAttente.class)); vueRacine.afficherSousVue(vueFileAttente); });
Ou avec des groupes de tâches, comme dans le tutoriel: