Mis à jour le 30/04/2018
  • 40 heures
  • Difficile

Ce cours est visible gratuitement en ligne.

Ce cours existe en livre papier.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Introduction et installation des outils

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Java FX n'est pas une nouveauté à part entière mais c'est, depuis Java 8, la bibliothèque de référence pour tout ce qui concerne les interfaces graphiques. Elle fonctionne légèrement différemment de Swing que nous avons vu pr écédemment mais elle respecte les paradigme de programmation événementielle que vous connaissez bien maintenant (des composants qui s'enchevêtre avec des écouteurs d'événements pour gérer les action à faire, etc).
Cette bibliothèque sera traitée d'une autre manière dans cette partie. Nous n'allons pas taper tout le code nécessaire au fonctionnement d'une application Java FX mais nous allons utiliser un outil qui permet de créer des interfaces très simplement et qui a le mérite de vous montrer tout ce qu'il est possible de faire sur les différents composants Java FX. Les plus curieux d'entre vous pourront tout de même modifier le code directement mais ce n'est pas une nécessité. Maintenant que vous maîtrisez la programmation événementielle, il vous suffira de modifier les propriétés ou actions selon vos besoins en cherchant ce qu'il est possible de faire.
Nous allons utiliser un fil conducteur pour cette partie : une application qui permet de visualiser des personnes et leurs données, c'est une application simple et didactique qui vous permettra de voir pas mal de choses. Si vous vous sentez d'attaque, commençons.

Pour la création d'interface graphique avec Java FX, nous allons nous reposer sur un outil externe qui s'appelle SceneBuilder ainsi qu'un plugin Eclipse qui va permettre d'appeler automatiquement cet outil lorsque nous en aurons besoin. Ceci va permettre de faire un tour d'horizon de Java FX rapidement et vous donner l'occasion de créer simplement des interfaces riches.

Java FX, kesako ?

Comme je vous le disais, Java FX est maintenant la bibliothèque de référence pour construire des interfaces graphique et ce depuis Java 8 : on parle d'ailleurs de Java FX 8. Cette bibliothèque propose beaucoup de composants graphiques qui nous simplifie grandement la vie comme :

  • Les  DatePicker  qui permet de récupérer facilement un objet  LocalDate  .

  • Les  TreeTableView  qui combine les  TableView  et des  TreeView  , donc des tableaux et des arbres.

  • Les  TextFlow  qui supporte du texte riche.

  • Des composants 2D et 3D.

  • et bien d'autres encore.

Java FX a même la possibilité d'inclure des composants Swing en son sein mais là ou Java FX prend tout son sens c'est que cette bibliothèque a été faite pour supporter toutes les nouveautés de Java 8 (nouvelle API date, les streams, les lambdas, …).
Java FX permet, tout comme Swing, de créer des interfaces graphiques en codant directement avec les objets présent dans le JDK, cependant il permet également d'utiliser un fichier  FXML  . Ces fichiers servent à décrire notre interface et répondent à certaines règles que nous aurons tout le loisir de découvrir. Java FX permet également de gérer l'apparence de nos IHM via des fichiers  CSS  (Cascading Style Sheet), tout comme dans une page HTML, ce qui est vraiment très pratique.

Installation

Java FX est déjà présent dans la dernière version du JDK, nous avons juste a installer nos outils pour nous simplifier la vie et nous pourrons commencer sereinement.

Je vous invite donc à télécharger l'outil SceneBuilder, disponible à cette adresse : http://gluonhq.com/products/scene-builder/
Vous pouvez télécharger la version JAR exécutable (elle fonctionne très bien) mais il ne sera pas possible de lier Eclipse avec cette outil, je vous invite donc à télécharger la version installable. Lors de son installation, notez bien le chemin ou l'outil sera mis car nous aurons de cette information pour Eclipse : chez moi, l'outil c'est installé ici «   C:\Users\cysboy\AppData\Local\SceneBuilder\SceneBuilder.exe  »
Nous n'allons pas le lancer tout de suite, nous allons au préalable installer le plugin Eclipse dont nous allons avoir besoin. Pour ce faire, allez dans le menu «  Help  > Install new software   », faite une recherche d'outil disponible dans la fenêtre qui c'est ouverte et recherchez ceci :

Installation du plugin Eclipse
Installation du plugin Eclipse

Si Eclipse veut redémarrer une nouvelle fois, laissez-le faire. Nous sommes maintenant fin prêt pour développer des applications Java FX.
Si vous avez plusieurs JDK d'installé sur votre machine, je vous recommande de vérifier, toujours dans le préférences d'Eclipse, le JDK par défaut dans le sous-menu «  Java > Installed JREs   » ainsi que l'option «  Compiler compliance level   » dans le sous menu «  Java > Compiler   » qui doivent utiliser à minima le JDK 1.8.

Un nouveau projet Java FX

Notre plugin, en plus de faire le lien avec SceneBuilder, nous permet de créer un nouveau projet de type Java FX, ce qui n'était pas possible avant. Allez dans le menu «  File > New > Other   » et sélectionnez «  Java FX Project  », nommez votre projet et cliquez sur finish.
Normalement, dans le dossier «  src   » d'Eclipse, vous devriez avoir un package nommé « application » contenant deux fichiers : un fichier Main.java et un fichier application.css. Vous pouvez y jeter un œil si vous le souhaitez et même lancer l'application : vous aurez une fenêtre vide qui va s'afficher, rien de plus. Comme je vous le disais plus tôt, nous avons deux façons de faire :
coder directement en Java, comme nous l'avons fait avec Swing ;
utiliser un fichier  FXML  et  SceneBuilder  .
Vu que nous allons utiliser la deuxième méthode, je vous invite à supprimer le package « application ». Nous allons créer trois packages afin d'essayer de respecter le pattern MVC. Je vous propose de faire une application qui va permettre de visualiser des informations sur des personnes. Nous allons donc avoir besoin de trois packages (  model/view  et  controler  ), chez moi j'ai fait les packages suivant :   fr.testfx.personnes.model  ,   fr.testfx.personnes.view  ,  fr.testfx.personnes.controler  .

Ceci fait, je vous invite à créer un fichier  FXML  dans le package  fr.testfx.personnes.view  en faisant un clic droit sur le package puis «   New > Other > New FXML Document  ». Personnellement, je l'ai appelé «  PersonView   », ce qui a donc générer le fichier   PersonView.fxml  dans mon package. Il comporte certains informations de base dont un import : oui, si vous modifiez ce fichier manuellement vous aurez a gérer les imports nécessaires à votre projet. Nous, par contre, nous allons déléguer cette tâche à SceneBuilder qui n'est finalement qu'un éditeur de fichier FXML. Faites maintenant un clic-droit sur votre fichier FXML et choisissez l'option « Open with SceneBuilder » : vous arrivez maintenant sur cet outil avec une scène principale vide, enfin, pas tout à fait.

L'interface de SceneBuilder
L'interface de SceneBuilder

En haut à gauche, vous l'aurez sans doute deviné, vous avez tous les composants graphiques disponible dans Java FX (et ils sont nombreux). Juste en dessous, vous avez un onglet « Hierarchy » qui représente la hiérarchie des composants graphiques présents dans votre application. Pour le moment, il n'y a qu'un objet  AnchorPane  qui est un conteneur (vous connaissez...). Lorsqu'on clique sur ce composant, l'onglet de droite se charge avec toutes les propriétés qu'accepte ce composant, comme son opacité, s'il est visible etc. Je vous invite dès à présent à lui spécifier une taille dans l'onglet « Layout » en renseignant les champs « Pref Width et Pref Height ». Je lui ai donner une largeur de 500 et une hauteur de 200 mais vous pouvez adapter. Enregistrez les modifications retournez dans Eclipse et vérifiez le contenu du fichier  JXML   : il a été modifié automatiquement.

Encapsulation de fichier FXML

Nous avons maintenant une base de travail. Nous allons continuer en créant notre IHM qui nous suivra tout au long de cette partie. Retournez dans l'outil SceneBuilder pour ajouter de nouveau composants. L'ajout se fait très simplement par glissé/déposé dans la zone centrale mais vous pouvez rectifier la hiérarchie dans l'onglet portant le même nom.
Ajouter un  SplitPane  horizontal dans la zone en faisant un glissé/déposé. Celui-ci est posé dans le conteneur  AnchorPane  comme le montre la figure ci-dessous :

Ajout d'un SpliPane dans notre IHM
Ajout d'un SpliPane dans notre IHM

Lorsque vous cliquez sur l'objet  SplitPane  dans l'onglet «Hierarchy » vous pouvez voir que sa taille n'est pas vraiment adapté. Vous pouvez faire un clic-droit sur cet objet dans l'onglet « Hierarchy » et choisir l'option « Fit to Parent » : maintenant notre  SplitPane  prend toute la place disponible dans son conteneur parent.
Ce que nous allons ajouter maintenant est un tableau qui prendra toute la place dans la partie gauche de notre  SplitPane  . Pour faire cela, nous allons faire un glissé/déposé du composant  TableView  qui se trouve dans la partie « Controls » de SceneBuilder à l'endroit souhaité. Vous pouvez vous rendre compte que la disposition n'est pas idéal encore une fois. Afin que notre composant puisse être correctement dimensionné, refaite la même manipulation que pour notre  SplitPane  , clic-droit puis « Fit to parent » dans l'onglet « Hierarchy ». Vous pouvez également procéder différemment, en modifiant les propriété d'ancre du tableau via l'onglet « Layout » du composant :

Donner la taille maximale à un composant
Donner la taille maximale à un composant

Si vous renseignez la valeur zéro au quatre coins cela aura le même effet que la manipulation précédente : en fait un  AnchorPane  permet de définir ou se positionne le composant de façon relative. Vous pouvez donc gérer des marges etc. Nous utiliserons cette propriété lorsque nous ajouterons des composants dans l'encart de droite.

Vous pouvez maintenant modifier le nom de chaque colonne en déroulant l'objet  TableView  et en changeant la propriété de chaque colonne dans l'onglet « Property » une par une comme dans la figure suivante :

Renomer les colonnes de notre tableau
Renommer les colonnes de notre tableau

Je pense que vous commencé à voir comment nous allons travailler avec Java FX : tout (ou presque) se fera ici, en modifiant des propriétés d'objets tel que les agencements, leurs noms, leurs tailles, etc. Je décris un peu avec des captures d'écrans pour le moment mais je vais vite accélérer la cadences.
À ce stade, je vous invite à voir ce que tout ceci donne avec un aperçu : allez dans le menu « Preview » et choisissez « Show preview in window » ou utilisez le raccourcis CTRL + P.
Le rendu est vraiment sympa et en quelques clics seulement ! Par contre, notre tableau ne prend pas vraiment toute la taille de notre conteneur de gauche : les colonnes ont une taille qui ne change pas avec le redimensionnement. L'objet prend bien tout l'espace mais pas les colonnes : si vous regardez dans les propriétés de votre objet  TableView  , donc en haut à gauche de SceneBuilder (après avoir sélectionné le bon objet dans l'onglet « Hierarchy ») vous apercevrez une propriété qui se nomme « Column Resize Policy » et qui permet de dire à notre composant que les colonnes prendront tout l'espace disponible en choisissant l'option « constrained-resize » : je vous invite donc à modifier cette valeur.
Si vous vous demandez à quoi sert une propriété, vous pouvez cliquer sur le nom de chacune et la page JavaDoc du site d'Oracle s'ouvrira comme par magie !

Maintenant, pour vous montrer la simplicité de cette outil et la rapidité avec laquelle nous pouvons faire des interfaces graphiques complexes nous allons utiliser la partie de droite de notre IHM pour afficher les informations des nos personnes (nom, prénom, sexe, date de naissance, photo). Nous allons utiliser différents conteneurs pour que ce soit bien propre : un  BorderPane  . Voici comment nous allons agencer ceci :

  • un  Label  qui contiendra un titre dans la partie  TOP  du  BorderPane  ;

  • un  GridPane  sur quatre ligne et deux colonnes qui contiendra nos informations textuelles dans la partie gauche ;

  • un conteneur ButtonBar dans la partie inférieur qui , lui, va contenir deux boutons.

Ce genre de choses étaient assez rébarbatives à faire directement en Java avec Swing mais, avec SceneBuilder et Java FX c'est très simple.

Commencez par positionner un  BorderPane  dans la partie droite de l'IHM et ajuster sa taille au contenu (comme précédemment). Ensuite, vous n'avez qu'à déplacer les différents composants sur les parties du  BorderPane  qui vont les contenir et les ajuster. Pour faire ceci, vous pouvez directement déposé les composants dans l'onglet « Hierarchy » , sur le bon endroit du  BorderPane  (  TOP  ,  BOTTOM  ,  LEFT  ,  RIGHT  ,  CENTER  ). Commencez par déposé un  Label  dans la partie  TOP  et modifiez ses propriétés pour qu'il soit aligné à gauche et que son intitulé soit « Informations » : vous savez faire. Continuez En déposant un  ButtonBar  dans la partie  BOTTOM  qui devrait prendre naturellement tout l'espace disponible. Ce composant est créé avec un bouton par défaut, ajoutez-y un deuxième bouton et nommez-les respectivement « Supprimer » et « Editer » en les alignant à droite. La touche finale sera notre  GridPane  à déposer dans la partie  CENTER  du  BorderPane  . Ce composant s'affiche par défaut avec trois lignes et deux colonnes, or nous avons de quatre lignes. Pour en ajouter une, il suffit de sélectionner une ligne en cliquant dessus puis de faire un clic droit et d'ajouter une nouvelle ligne (en dessous ou au dessus, peu importe) comme ceci :

Ajouter une ligne dans un GridPane
Ajouter une ligne dans un GridPane

Maintenant, ajoutez des Label dans chaque cellule, nommez-les et, pour que vos Labels prennent bien tout l'espace offert par votre conteneur, vous devrez régler leurs propriétés « Max Height » et « Max Width » à la valeur «  MAX_VALUE  ». Lancez la prévisualisation et vous devriez obtenir ceci :

Premier rendu de notre application

Et voici à quoi ressemble notre hiérarchie :

Hiérarchie de l'application
Hiérarchie de l'application

Nous avons une belle IHM en quelques clics de souris, mais une véritable IHM n'existe pas sans bar de menu... Nous allons en ajouter une mais, afin de vous montrer les possibilité de Java FX, nous allons la faire dans un nouveau fichier  FXML  , ainsi, nous aurons l'occasion de voir comment découper une IHM en plusieurs fichiers et les utiliser.

Utiliser plusieurs fichiers FXML

Dans le même package que précédemment, dans Eclipse, créez un nouveau fichier  FXML  qui contiendra , lui, notre conteneur principal ainsi que la barre de menu. Une précision toutefois, vous pouvez spécifier quel type de conteneur principal sera dans la partie d'IHM que vous allez faire. Par défaut il s'agit d'un  AnchorPane  mais ici nous allons utiliser un  BorderPane  pour des raisons évidentes.

Choix du conteneur par défaut pour notre nouveau fichier FXML
Choix du conteneur par défaut pour notre nouveau fichier FXML

Une fois ceci fait, ajouter une barre de menu dans la partie supérieure de votre conteneur. Cet objet s'affiche avec, par défaut, trois points de menu : modifiez son contenu afin d'avoir un menu fichier et deux  MenuItem  , « Nouveau » et « Quitter », comme ceci :

Ajout de deux points de menu
Ajout de deux points de menu

Bon, nous avons nos deux fichier  FXML  , il ne reste maintenant qu'à les lier ensemble afin que notre conteneur principal contienne notre partie visualisation de données. Pour faire cela, nous allons utiliser Eclipse et taper du code directement dans une classe Java : rappelez-vous, SceneBuilder n'est qu'un éditeur  FXML  . Notre plugin Eclipse va nous simplifier la tâche. Après avoir bien sauvegardé vos projets dans SceneBuilder, retournez dans Eclipse et, dans le package  fr.testfx.personnes  créez une nouvelle classes principale Java FX en faisant « New > Other > Java FX > Classes > Java FX Main Classes ». Si vous ne voyez pas ce package parce que celui-ci est vide, vous pouvez modifier la façon dont les package sont présenté dans un projet en utilisant le petit triangle en haut à droite de la vue puis en sélectionnant une vue de package hiérarchique, comme ceci :

Changer le type de vue de notre projet
Changer le type de vue de notre projet

Vous vous retrouvez alors avec un code minimal qui ne fait rien du tout... Nous allons donc lié et afficher tout ce que nous avons fait jusque là. Voici le code modifié de la classe que nous venons de créer :

package fr.testfx.personnes;

import java.io.IOException;

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

public class MainClass extends Application {

	//Nous créons des variable de classes afin de pouvoir y accéder partout
	//Ceci afin de pouvoir y positionner les éléments que nous avons fait
	//Il y a un BorderPane car le conteneur principal de notre IHM
	//est un BorderPane, nous reparlerons de l'objet Stage
	private Stage stagePrincipal;
	private BorderPane conteneurPrincipal;
	
	@Override
	public void start(Stage primaryStage) {
		stagePrincipal = primaryStage;
		//Ca ne vous rappelle pas une JFrame ?
		stagePrincipal.setTitle("Application de gestion de personnes");
		
		//Nous allons utiliser nos fichier FXML dans ces deux méthodes
		initialisationConteneurPrincipal();
		initialisationContenu();
	}

	private void initialisationConteneurPrincipal() {
		//On créé un chargeur de FXML
		FXMLLoader loader = new FXMLLoader();
		//On lui spécifie le chemin relatif à notre classe
		//du fichier FXML a charger : dans le sous-dossier view
		loader.setLocation(MainClass.class.getResource("view/ConteneurPrincipal.fxml"));
		try {
			//Le chargement nous donne notre conteneur
			conteneurPrincipal = (BorderPane) loader.load();
			//On définit une scène principale avec notre conteneur
			Scene scene = new Scene(conteneurPrincipal);
			//Que nous affectons à notre Stage
			stagePrincipal.setScene(scene);
			//Pour l'afficher
			stagePrincipal.show();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void initialisationContenu() {
		FXMLLoader loader = new FXMLLoader();
		loader.setLocation(MainClass.class.getResource("view/PersonView.fxml"));
		try {
			//Nous récupérons notre conteneur qui contiendra les données
			//Pour rappel, c'est un AnchorPane...
			AnchorPane conteneurPersonne = (AnchorPane) loader.load();
			//Qui nous ajoutons à notre conteneur principal
			//Au centre, puisque'il s'agit d'un BorderPane
			conteneurPrincipal.setCenter(conteneurPersonne);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		launch(args);
	}
}

Etant familier de la programmation événementielle, vous avez du comprendre une grande partie de ce code, notamment grâce aux commentaires. Vous devez vous apercevoir que tout ceci ressemble grandement à tout ce que nous avons fait avec Swing : des conteneurs qui en contiennent d'autres qui eux mêmes ont des composants avec des propriétés le tout agencer avec des gestionnaires de disposition (  Layout  ). Je vais tout de même vous donner quelques explications.
Vous avez dû vous rendre compte que notre classe était hérité de la classe Application et que celle-ci contenait, avant modification, deux méthodes : c'est la structure de base d'une application Java FX. Ce qu'il faut surtout retenir c'est qu'une application Java FX se structure en  Stage  et en  Scene  ,  Scene  qui contiendra des composants. Un objet  Stage  est un peu l'équivalent d'un objet  JFrame  , c'est lui qui aura les boutons de fenêtre classique, le titre, etc. La  Scene  est le conteneur principal où nous pourrons insérer des composants ou groupe de composants : ça rappelle vraiment  Swing  n'est-ce pas. Donc ce que nous avons fait c'est définir une fenêtre (Stage), son conteneur principal (notre  BorderPane  avec la barre de menu) et nous avons spécifier qu'il y aurait des composants au centre de cet objet (l'IHM que nous avons fait au tout début). Voici un schéma provenant du site d'Oracle vous représentant cette hiérarchie :

Hiérarchie d'une application Java FX
Hiérarchie d'une application Java FX

Vous retrouvez bien tout ce que je vous ai dit. Et, oui, tout comme avec  Swing  , vous pouvez mettre à jour ou alors complètement modifier la scène d'un stage. Par contre, pensez à vérifier que le chemin vers vos fichiers  FXML  sont bons... Sinon gare à l'exception ! Bref, nous arrivons à la fin de cette loooooongue présentation et vous devriez avoir ceci en lançant votre programme depuis Eclipse :

Premier lancement de votre application
Premier lancement de votre application

Maintenant que la prise en main de SceneBuilder est faite, j'irai un peu plus vite dans la définition des propriétés et de certaines options. Il est temps de passer à l'étape suivante et faire en sorte que notre application sache gérer des données.

En résumé

  • Java FX est maintenant l'API officiel des interfaces graphiques pour Java depuis Java 8.

  • Il est possible de développer une application en utilisant un fichier XML de déclaration (  FXML  ).

  • L'outil SceneBuilder permet de manipuler et d'éditer les fichiers  FXML  .

  • La hiérarchie d'une application Java FX est relativement simple : un  Stage  qui contient une  Scene  qui contient des composants.

  • Dans SceneBuilder il est possible d'éditer quasiment toutes les propriétés d'un composant.

  • Un plugin Eclipse est nécessaire pour fait le lien entre Eclipse et SceneBuilder.

Exemple de certificat de réussite
Exemple de certificat de réussite