IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
logo

FAQ JavaFXConsultez toutes les FAQ

Nombre d'auteurs : 4, nombre de questions : 507, derni�re mise � jour : 2 novembre 2016  Ajouter une question

 

Cette FAQ a �t� r�alis�e � partir des questions fr�quemment pos�es sur le forum JavaFX de http://java.developpez.com ainsi que l'exp�rience personnelle des auteurs.

Nous tenons � souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne pr�tend pas non plus �tre compl�te. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant r�dacteur, lisez ceci.

Sur ce, nous vous souhaitons une bonne lecture.

SommaireCollections observables (9)
pr�c�dent sommaire suivant
 

JavaFX introduit une nouvelle API de collections : les collections observables. Ces collections �mettent des �v�nements quand leur contenu change, que des objets sont ajout�s, retir�s ou modifi�s dans la collection. Les classes de cette API sont situ�es dans le package javafx.collections.

Il existe quatre types de collections observables fournis par l'API JavaFX :

  • ObservableArray - une classe observable qui encapsule des tableaux d'entiers ou de flottants - JavaFX 8 ou ult�rieur�;
  • ObservableList<T> - les listes observables�;
  • ObservableMap<T> - les tables de hachage/dictionnaires observables�;
  • ObservableSet<T> - les ensembles observables.


L'API SceneGraph utilise la classe ObservableList de mani�re intensive ; il est donc conseill� de s'int�resser � leur fonctionnement pour mieux comprendre le fonctionnement des gestionnaires de mise en page, des listes, arbres et tables graphiques, etc.

� l'exception d'ObservableArray qui lui est propre, cette API reste compatible avec l'API standard de collections de Java ainsi qu'avec toutes les am�liorations introduites dans le JDK8 (streams).

Mis � jour le 10 septembre 2014 bouye

La classe utilitaire javafx.collections.FXCollections contient des m�thodes permettant de cr�er de nouvelles collections observables.

Par exemple :

Code Java : S�lectionner tout
final ObservableList<Person> people = FXCollections.observableArrayList();

Ce code cr�era une nouvelle liste observable vide.

Il est �galement possible de fournir des �l�ments permettant d�initialiser le contenu de la liste :

Code Java : S�lectionner tout
final ObservableList<Person> people = FXCollections.observableArrayList(person1, person2, person3);

En interne, la liste est stock�e en utilisant une instance de la classe java.util.ArrayList de l'API de collection standard Java.

Mis � jour le 10 septembre 2014 bouye

La classe utilitaire javafx.collections.FXCollections contient des m�thodes permettant d'empaqueter une collection Java standard en collection observable.

Par exemple :

Code Java : S�lectionner tout
1
2
3
4
final Map<<PhoneNumber, Person> phoneBook = new HashMap<>(); 
// Remplissage de l'annuaire. 
[...] 
final ObservableMap<PhoneNumber, Person> phoneBookObservable = FXCollections.observableMap(phoneBook);

Ici, notre table de hachage est d�sormais empaquet�e dans une table de hachage observable.

De la m�me mani�re, il est possible de cr�er des listes observables utilisant une instance de LinkedList comme stockage interne au lieu d'une instance de ArrayList. Par exemple :

Code Java : S�lectionner tout
final ObservableList<Car> carList = FXCollections.observableList(new LinkedList());

Note : il va de soi que pour pouvoir �mettre correctement des �v�nements en cas de modification, ce sont les versions observables des collections qui doivent �tre d�sormais manipul�es. Toute manipulation de la version non observable de la collection passera inaper�ue.

Mis � jour le 10 septembre 2014 bouye

Pour recevoir les notifications de modification d'une ObservableList<T>, il faut lui ajouter un �couteur de type javafx.collections.ListChangeListener<T> et traiter l'objet de type javafx.collections.ListChangeListener.Change<? extends T> pass� en param�tre de sa m�thode onChanged().

Commen�ons par cr�er une liste observable :

Code Java : S�lectionner tout
final ObservableList<String> names = FXCollections.observableArrayList("Andr�", "�lodie", "Jasmina", "Malik", "Val�rie", "Yvana");

Maintenant, nous allons lui ajouter un �couteur de type ListChangeListener:

Code Java : S�lectionner tout
1
2
3
4
5
6
7
names.addListener(new ListChangeListener<String>() { 
  
    @Override 
    public void onChanged(ListChangeListener.Change<? extends String> change) { 
        // Traitement des changements ici. 
    }            
});

Nous pouvons �galement faire la m�me chose en utilisant les expressions lambda du JDK8 :

Code Java : S�lectionner tout
1
2
3
names.addListener((ListChangeListener.Change<? extends String> change) -> {            
    // Traitement des changements ici. 
});

Ici, il est n�cessaire de sp�cifier le type de l'argument de l'expression lambda, car il existe �galement une variante de la m�thode addListener() acceptant un InvalidationListener dans la classe ObservableList. Sp�cifier le type permet de r�soudre l�ambig�it� sur la m�thode qui doit �tre invoqu�e.

Mis � jour le 10 septembre 2014 bouye

Pour am�liorer les performances et minimiser le nombre d��v�nements publi�s, l'objet change re�u dans la m�thode onChanged() d'un ListChangeListener est en fait un rapport agr�g� contenant les r�centes modifications sur la liste observable. Les diverses modifications devront �tre trait�es dans une boucle de style :

Code Java : S�lectionner tout
1
2
3
while(change.next()) { 
   // Traiter chaque changement s�par�ment ici. 
}

Il ne faut jamais invoquer de m�thodes de l'objet change sans avoir invoqu� sa m�thode next() au pr�alable !

Dans un objet de type ListChangeListener.Change, nous pouvons recevoir cinq types de notifications :

  • Remplacement : une ou plusieurs valeurs ont �t� remplac�es par d'autres ;
  • Permutation: une ou plusieurs valeurs ont �chang� leur place dans la liste avec d'autres (qui �taient �galement dans la liste) ;
  • Mise � jour : une ou plusieurs valeurs ont �t� modifi�es. Ce type de notification est optionnel et peut ne pas �tre pris en charge par tous les types de listes observables ;
  • Ajout : une ou plusieurs valeurs ont �t� ajout�es dans la liste ;
  • Suppression : une ou plusieurs valeurs ont �t� supprim�es dans la liste.


Ces types ne sont pas exclusifs : plusieurs types peuvent �tre actifs en m�me temps.

Ajoutons l��couteur suivant sur notre liste de noms :

Code Java : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
names.addListener((ListChangeListener.Change<? extends String> change) -> { 
    System.out.println("+Notification"); 
    while (change.next()) { 
        if (change.wasReplaced()) { 
            System.out.printf("++Remplacement %d %d", change.getFrom(), change.getTo()).println(); 
        } 
        if (change.wasPermutated()) { 
            System.out.printf("++Permutation %d %d", change.getFrom(), change.getTo()).println(); 
            for (int index = change.getFrom() ; index < change.getTo() ; index++) { 
                System.out.printf("%d -> %d", index, change.getPermutation(index)).println(); 
            } 
        } 
        if (change.wasUpdated()) { 
            System.out.printf("++Mise � jour %d %d", change.getFrom(), change.getTo()).println(); 
        } 
        if (change.wasAdded()) { 
            System.out.println("++Ajout"); 
            change.getAddedSubList().forEach(value -> System.out.printf("\"%s\" a �t� ajout�.", value).println()); 
        } 
        if (change.wasRemoved()) { 
            System.out.println("++Retrait"); 
            change.getRemoved().forEach(value -> System.out.printf("\"%s\" a �t� supprim�.", value).println()); 
        } 
    } 
    System.out.println(); 
});

Ajoutons maintenant quelques noms dans la liste :

Code Java : S�lectionner tout
names.addAll("Henri", "Oscar", "Manon");

La sortie de cette op�ration est :

Code : S�lectionner tout
1
2
3
4
5
+Notification 
++Ajout 
"Henri" a �t� ajout�. 
"Oscar" a �t� ajout�. 
"Manon" a �t� ajout�
Nous avons eu une notification d'ajout lors de cet �v�nement. La m�thode getAddedSubList() permet de retrouver toutes les valeurs qui ont �t� ajout�es dans la liste. Cette m�thode retourne une vue sur la liste interne.

Retirons maintenant des �l�ments de la liste :

Code Java : S�lectionner tout
names.removeAll("Andr�", "�lodie");

La sortie de cette op�ration est :

Code : S�lectionner tout
1
2
3
4
+Notification 
++Retrait 
"Andr�" a �t� supprim�. 
"�lodie" a �t� supprim�.
Nous avons eu une notification de retrait lors de cet �v�nement. La m�thode getRemoved() permet de retrouver toutes les valeurs qui ont �t� retir�es dans la liste.

Rempla�ons maintenant un �l�ment de la liste par un autre :

Code Java : S�lectionner tout
names.set(0, "Barbara");

La sortie de cette op�ration est :

Code : S�lectionner tout
1
2
3
4
5
6
+Notification 
++Remplacement 0 1 
++Ajout 
"Barbara" a �t� ajout�. 
++Retrait 
"Jasmina" a �t� supprim�.
Ici, nous avons non seulement un �v�nement de remplacement ("Barbara" remplace "Jasmina"), mais �galement un �v�nement d'ajout ("Barbara" a �t� ajout� dans la liste) et de retrait ("Jasmina" a �t� retir� de la liste). Nous savons �galement que la modification impacte l'intervalle d'indices [0, 1[, donc seule la premi�re valeur de la liste a �t� modifi�e.

Nous allons maintenant trier la liste :

Code Java : S�lectionner tout
FXCollections.sort(names);

La sortie de cette op�ration est :
Code : S�lectionner tout
1
2
3
4
5
6
7
8
9
+Notification 
++Permutation 0 7 
0 -> 0 
1 -> 2 
2 -> 5 
3 -> 6 
4 -> 1 
5 -> 4 
6 -> 3
Nous savons que la permutation a affect� l'ensemble des �l�ments compris entre les indices [0, 7[ de la liste et nous pouvons connaitre le nouvel indice de chaque valeur en appelant la m�thode getPermutation() de l'objet change et en passant son ancien indice en param�tre.

Mis � jour le 10 septembre 2014 bouye

� partir du JDK 8, il est possible de cr�er une liste observable automatiquement tri�e en empaquetant une liste observable source dans une instance de la classe javafx.collections.transformation.SortedList<T>.

Par exemple :

Code Java : S�lectionner tout
1
2
final ObservableList<String> names = FXCollections.observableArrayList("Yvana", "�lodie", "Andr�", "Jasmina", "Malik", "Val�rie"); 
final SortedList<String> sortedNames = new SortedList(names);

Ici le contenu de la nouvelle liste n'est initialement pas tri� et adopte donc le m�me ordre d��l�ments que dans la liste source.

Il est possible de changer l'ordre ou le crit�re du tri en sp�cifiant une instance de la classe java.util.Comparator dans la propri�t� comparator de la liste tri�e :

Code Java : S�lectionner tout
1
2
3
4
5
6
7
sortedNames.setComparator(new Comparator<String>(){ 
  
    @Override 
    public int compare(String o1, String o2) { 
        return o1.compareTo(o2); 
    }             
});

Ou :

Code Java : S�lectionner tout
sortedNames.setComparator(String::compareTo);


Ce qui nous donne :

Code : S�lectionner tout
[Andr�, Jasmina, Malik, Val�rie, Yvana, �lodie]

Ici, la liste tri�e contient donc les m�mes �l�ments que la liste source, mais tri�s dans un ordre lexicographique.

La liste sortedNames sera toujours tri�e, m�me si on ajoute, retire ou permute des �l�ments de la liste names. Tout changement sur la liste source est automatiquement r�percut� sur la liste tri�e. La liste tri�e �tant elle-m�me une liste observable, elle �mettra les �v�nements appropri�s en cas de modifications de la liste source qui ont des r�percussions sur son contenu.

Mis � jour le 8 octobre 2014 bouye

� partir du JDK 8, il est possible de cr�er une liste observable automatiquement filtr�e en empaquetant une liste observable dans une instance de la classe javafx.collections.transformation.FilteredList<T>.

Par exemple :

Code Java : S�lectionner tout
1
2
final ObservableList<String> names = FXCollections.observableArrayList("Yvana", "�lodie", "Andr�", "Jasmina", "Malik", "Val�rie"); 
final FilteredList<String> filteredNames = new FilteredList(names);

Ici, la liste filteredNames est initialement vide, car l'absence de filtre fait qu'elle rejette tous les �l�ments de la liste source names.

Il est possible de sp�cifier une instance de la classe java.util.function.Predicate dans la propri�t� predicate de la liste filtr�e pour rendre le filtrage op�rationnel :

Code Java : S�lectionner tout
1
2
3
4
5
6
7
filteredNames.setPredicate(new Predicate<String>() { 
  
    @Override 
    public boolean test(String value) { 
        return value.length() > 5; 
    } 
});

Ou :

Code Java : S�lectionner tout
filteredNames.setPredicate(value -> value.length() > 5);

Ce qui nous donne :

Code : S�lectionner tout
[�lodie, Jasmina, Val�rie]

Ici, seuls les noms dont la longueur d�passe cinq caract�res sont membres de la liste filtr�e.

La liste filteredNames sera toujours automatiquement filtr�e, m�me si on ajoute, retire ou permute des �l�ments de la liste names. Tout changement sur la liste source est automatiquement r�percut� sur la liste filtr�e. La liste filtr�e �tant elle-m�me une liste observable, elle �mettra les �v�nements appropri�s en cas de modifications de la liste source qui ont des r�percussions sur son contenu.

Mis � jour le 8 octobre 2014 bouye

Pour recevoir les notifications de modification d'une ObservableMap<K, V>, il faut lui ajouter un �couteur de type javafx.collections.MapChangeListener<K, V> et traiter l'objet de type javafx.collections.MapChangeListener.Change<? extends K, ? extends V> pass� en param�tre de sa m�thode onChanged().

Commen�ons par cr�er une liste observable :

Code Java : S�lectionner tout
1
2
3
4
5
6
7
final Map<Integer, String> source = new HashMap(); 
source.put(0, "Anthony"); 
source.put(1, "Antoinette"); 
source.put(2, "J�r�me"); 
source.put(3, "Karine"); 
source.put(4, "Patrick"); 
final ObservableMap<Integer, String> users = FXCollections.observableMap(source);

Maintenant, nous allons lui ajouter un �couteur de type ListChangeListener :

Code Java : S�lectionner tout
1
2
3
4
5
6
7
users.addListener(new MapChangeListener<Integer, String>() { 
  
    @Override 
    public void onChanged(MapChangeListener.Change<? extends Integer, ? extends String> change) { 
        // Traitement des changements ici. 
    } 
});

Nous pouvons �galement faire la m�me chose en utilisant les expressions lambda du JDK8 :

Code Java : S�lectionner tout
1
2
3
users.addListener((MapChangeListener.Change<? extends Integer, ? extends String> change) -> { 
    // Traitement des changements ici. 
});

Ici, il est n�cessaire de sp�cifier le type de l'argument de l'expression lambda, car il existe �galement une variante de la m�thode addListener() acceptant un InvalidationListener dans la classe MapList. Sp�cifier le type permet de r�soudre l�ambig�it� sur la m�thode qui doit �tre invoqu�e.

Mis � jour le 10 septembre 2014 bouye

La gestion des �v�nements sur une table de hachage observable est moins �volu�e que sur les listes observables. Ici l'objet change re�u dans la m�thode onChanged() d'un MapChangeListener contient une seule notification d��v�nement :

Dans un objet de type MapChangeListener.Change, nous pouvons recevoir deux types de notifications :

  • Ajout : une valeur a �t� ajout�e dans la table ;
  • Suppression : une valeur a �t� retir�e de la table.


Ces types ne sont pas exclusifs : plusieurs types peuvent �tre actifs en m�me temps.

Ajoutons l��couteur suivant sur notre table d'utilisateurs :

Code Java : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
users.addListener((MapChangeListener.Change<? extends Integer, ? extends String> change) -> { 
    System.out.println("+Notification"); 
    if (change.wasAdded()) {      
        System.out.printf("\"%s\" a �t� ajout�.", change.getValueAdded()).println(); 
    } 
    if (change.wasRemoved()) {                 
        System.out.printf("\"%s\" a �t� supprim�.", change.getValueRemoved()).println(); 
    } 
    System.out.println(); 
});

Ajoutons maintenant quelques noms dans la table :

Code Java : S�lectionner tout
1
2
users.put(5, "Ren�e"); 
users.put(6, "Herv�");

La sortie de ces op�rations est :

Code : S�lectionner tout
1
2
3
4
5
+Notification 
"Ren�e" a �t� ajout�. 
 
+Notification 
"Herv�" a �t� ajout�.
Ici, nous avons re�u une notification par ajout de valeur.

Retirons maintenant des �l�ments de table :

Code Java : S�lectionner tout
1
2
users.remove(0); 
users.remove(1);

La sortie de cette op�ration est :

Code : S�lectionner tout
1
2
3
4
5
+Notification 
"Anthony" a �t� supprim�. 
 
+Notification 
"Antoinette" a �t� supprim�.
Ici, nous avons �galement re�u une seule notification par retrait.

Rempla�ons maintenant un �l�ment de la table par un autre :

Code Java : S�lectionner tout
users.put(3, "Annie");

La sortie de cette op�ration est :

Code : S�lectionner tout
1
2
3
+Notification 
"Annie" a �t� ajout�. 
"Karine" a �t� supprim�.
Ici, nous avons re�u un �v�nement d'ajout ("Annie" a �t� ajout� dans la table) et un �v�nement de retrait ("Karine" a �t� retir� de la table).

Mis � jour le 10 septembre 2014 bouye

Proposer une nouvelle r�ponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plut�t sur le forum de la rubrique pour �a


R�ponse � la question

Liens sous la question
pr�c�dent sommaire suivant
 

Les sources pr�sent�es sur cette page sont libres de droits et vous pouvez les utiliser � votre convenance. Par contre, la page de pr�sentation constitue une �uvre intellectuelle prot�g�e par les droits d'auteur. Copyright � 2025 Developpez Developpez LLC. Tous droits r�serv�s Developpez LLC. Aucune reproduction, m�me partielle, ne peut �tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'� trois ans de prison et jusqu'� 300 000 � de dommages et int�r�ts.