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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaFX Discussion :

Mise à jour Key dans une ObservableMap => CheckBoxListCell


Sujet :

JavaFX

  1. #1
    Membre du Club
    Homme Profil pro
    Ingénieur projet
    Inscrit en
    Juin 2014
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur projet
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2014
    Messages : 46
    Points : 43
    Points
    43
    Par défaut Mise à jour Key dans une ObservableMap => CheckBoxListCell
    Bonjour,
    Je rencontre quelques difficultés dans la mise en place d'une liste d’éléments avec un affichage sous forme de CheckBoxListCell.
    En m'inspirant de l'excellent tutoriel de Mr Bouyé sur L'API Cell de javaFX (c'est pas juste pour espérer une réponse, je le pense sincèrement, ), j'ai utilisé une ObservableMap pour lier les choix fais par l’utilisateur aux éléments contenus dans une liste.
    Pour une meilleure compréhension j'ai mis le code utilisé pour réaliser les tests à la fin de mon message.

    Les éléments affichés dans la ListView sont de type Compose, et sont stockés initialement dans une liste observable 'nodeList'. Chaque élément de cette liste est ajouté à la liste ObservableMap 'itemBooleanMap' qui est utilisée pour la ListView.

    J'ai deux questions :
    • Dans la listView, j'affiche une propriété de la classe Compose (le nom de mon composé). Lorsque je mets à jour cette propriété dans un élément de la liste de Compose 'nodeList', cette modification n'est pas propagée à l'ObservableMap. Il ne semble pas y avoir de méthode pour apporter des modifications à une clé.
      Je ne sais pas quelle méthode est la meilleur répercuter la modification de la propriété du Composé à la clé contenue dans l'ObservableMap. J'ai bien pensé à supprimer cette clé et à en créer une nouvelle mais je trouve ça un peu brutal. D'autant plus que je souhaite conserver la propriété de sélection qui implique d'autres modifications dans la version complète de mon code.
      Auriez-vous des pistes pour cela ?
    • Lorsque les éléments sont ajoutés à la liste ObservableMap, l'ordre des éléments n'est pas forcément celui de la liste de départ. Auriez-vous une explication, et éventuellement une technique pour conserver cet ordre.

    Merci d'avance.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
     
    public class testListView extends Application{
     
    	private ObservableList <Compose> nodeList = FXCollections.observableArrayList();
     
    	private final ObservableMap<Compose, BooleanProperty> itemBooleanMap = FXCollections.observableHashMap();
     
    	ListView<Compose> listView = new ListView<Compose>(); 
     
     
    	@Override
    	public void start(Stage primaryStage) throws Exception {
     
    		// Permet de récupérer la propriété JavaFX associée à chaque clé.
    		final Callback<Compose, ObservableValue<Boolean>> propertyAccessor = (Compose key) -> itemBooleanMap.get(key);
    		// Permet d'afficher un label qui porte le nom du réacteur dans chaque cellule de la liste.
    		final StringConverter<Compose> labelConverter = new StringConverter<Compose>() {
    			@Override
    			public String toString(Compose t) {
    				return t.getNomCompose().get();
    			}
     
    			// On n'utilise pas cette méthode.
    			@Override
    			public Compose fromString(String string) {
    				throw new UnsupportedOperationException("Not supported yet."); 
    			}
    		};
     
    		listView.setCellFactory(CheckBoxListCell.forListView(propertyAccessor, labelConverter));
     
    		nodeList.addListener((javafx.collections.ListChangeListener.Change<? extends Compose> c) -> {
    			while (c.next()) {
    				if (c.wasAdded()) {
    					for (Compose p : c.getAddedSubList()) {
    						itemBooleanMap.put(p, new SimpleBooleanProperty());
    					}
    				}
    				if (c.wasRemoved()) {
    					for (Compose p : c.getRemoved()) {
    						itemBooleanMap.remove(p);
    					}
    				}
    			}
    		});
     
     
    		nodeList.add(new Compose("Compose.1"));
    		nodeList.add(new Compose("Compose.2"));
    		nodeList.add(new Compose("Compose.3"));
    		nodeList.add(new Compose("Compose.4"));
     
     
    		listView.getItems().addAll(itemBooleanMap.keySet());
     
    		Button renameItemButton = new Button("Rename first Item");
    		renameItemButton.setOnAction((event) -> {
    			nodeList.get(0).setNomCompose("test");
    			System.out.println("Name of the first compose : "+ nodeList.get(0).getNomCompose().get());
    		});
     
    		final VBox vBox = new VBox();
    		vBox.getChildren().add(listView);
    		vBox.getChildren().add(renameItemButton);
    		final Scene scene = new Scene(vBox);
    		primaryStage.setScene(scene);
    		primaryStage.show();
    	}
     
    	public static void main(String[] args) {
    		launch(args);
    	}
     
     
     
     
    	/**
             * Décalaration de la classe Compose utilisée pour réaliser ce test.
             *
             */
     
    	public class Compose {
     
    		/**************************************************************************
                     * 
                     * Décalaration des champs privés
                     * 
                     **************************************************************************/
     
    		private StringProperty  nomCompose  = new SimpleStringProperty(); // Nom du composé
     
     
    		/**************************************************************************
                     * 
                     * Constructeur
                     * 
                     **************************************************************************/
     
    		public Compose(String nom){
    			this.nomCompose = new SimpleStringProperty(nom);
    		}
     
     
    		/**************************************************************************
                     * 
                     * Propriétés (Getters / Setters)
                     * 
                     **************************************************************************/
     
    		public StringProperty getNomCompose() {
    			return nomCompose;
    		}
     
    		public void setNomCompose(String nomCompose) {
    			this.nomCompose.set(nomCompose);
    		}
     
    		public StringProperty nomComposeProperty() {
    			return nomCompose;
    		}
    	}
     
    }

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 838
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 838
    Points : 22 846
    Points
    22 846
    Billets dans le blog
    51
    Par défaut
    Alors quelques petits soucis de base :
    • Le nom de la classe commence par une minuscule au lieu d'une majuscule comme dans les conventions Java.
    • La méthode Compose.getNomCompose() retourne une StringProperty au lieu d'une String.


    Le deboggage ou l'ajout d'une impression montre que la méthode StringConverter.toString() n'est jamais reinvoquée lorsque le nom du compose change ce qui explique le manque de rafraîchissement de la liste. Perso je gerera ca comme ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    27
    28
    29
    30
    31
    32
    33
    //listView.setCellFactory(CheckBoxListCell.forListView(propertyAccessor, labelConverter));
    listView.setCellFactory(listView -> new ComposeListCell());
     
    private class ComposeListCell extends CheckBoxListCell<Compose> implements ChangeListener<String> {
     
            public ComposeListCell() {
                super(itemBooleanMap::get);
            }
     
            private Compose oldCompose;
     
            @Override
            public void updateItem(Compose item, boolean empty) {
                super.updateItem(item, empty);
                if (oldCompose != null && oldCompose != item) {
    //                textProperty().unbind();
    //                setText(null);
                    oldCompose.nomComposeProperty().removeListener(this);
                    setText(null);
                }
                oldCompose = item;
                if (oldCompose != null) {
    //                textProperty().bind(oldCompose.nomComposeProperty());
                    oldCompose.nomComposeProperty().addListener(this);
                    setText(oldCompose.getNomCompose().get());
                }
            }
     
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                setText(newValue);
            }
        }
    Le binding en commentaire était ma 1ere idée mais en fait l'appel a super.udateItem() fait un setText() et donc l'ensemble levait une exception. D’où le fait que je suis passé par un ChangeListener a la place.

    De base dans l'API les map (tous comme les sets) ne sont pas ordonnées ni ne conservent l'ordre d'insertion, sauf implémentation particulière (ici LinkedHashMap) qui sont de fait plus gourmandes en ressources que l’implémentation basique. Tu voudras peut-être créer ta map en faisant itemBooleanMap = FXCollections.observableMap(new LinkedHashMap()); et voir si l'ordre est alors préservé.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Membre du Club
    Homme Profil pro
    Ingénieur projet
    Inscrit en
    Juin 2014
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur projet
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2014
    Messages : 46
    Points : 43
    Points
    43
    Par défaut
    Merci beaucoup pour ces réponses, je n'y avait pas pensé, mais effectivement, créer une classe 'ComposeListCell' est une très bonne alternative.
    Encore merci pour votre contribution active à ce forum.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] Mise à jour IE dans une applcation en C#
    Par mecyber25 dans le forum Windows Forms
    Réponses: 6
    Dernier message: 05/09/2017, 10h08
  2. Mise à jour JCombobox dans une JTable
    Par badich dans le forum Composants
    Réponses: 3
    Dernier message: 12/06/2013, 12h25
  3. Mise à jour dynamique d'une image dans une JSP
    Par zomurn dans le forum Servlets/JSP
    Réponses: 6
    Dernier message: 23/12/2011, 15h01
  4. [Débutant] Mise à jour graphique dans une autre figure que la principale
    Par Luis Vieira da Silva dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 26/06/2009, 13h04
  5. Requete De Mise A Jour Inseree Dans Une Macro
    Par tereda dans le forum Access
    Réponses: 1
    Dernier message: 10/05/2006, 13h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo