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 :

Changer tous les textes à partir d'un objet Properties


Sujet :

JavaFX

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 57
    Points : 93
    Points
    93
    Par défaut Changer tous les textes à partir d'un objet Properties
    Bonjour,

    J'entreprends de faire une application permettant à l'utilisateur, entre autres choses, de choisir la langue des textes, qui doivent changer instantanément en conséquence. J'ai donc utilisé des fichiers .properties comme cela semble naturel. Cela étant, je me trouve face à un problème : l'initialisation se passe bien, il me suffit de changer la valeur d'une des propriétés pour changer tous les textes, mais je me trouve un peu bloqué pour le faire après cette phase d'initialisation.

    En effet, tous mes textes sont stockés dans un objet Properties que je peux charger à loisir depuis des fichiers de langue, mais je suis peu familier du binding vue/modèle JavaFX et je ne crois pas que cela puisse se faire directement avec un objet Properties.

    Dois-je moi-même faire une classe qui enveloppe un objet Properties (appelons-la ObservableProperties) et propose des méthodes du genre getObservableValue(String key) et implémente Observable ? L'idée que j'avais, c'était que ObservableProperties instancie et renvoie une ObservableStringValue quand on appelle la méthode que j'ai citée si cette clé est demandé pour la première fois, sinon il renvoie l'objet précédemment instancié. Quand l'utilisateur demande à changer de langue, la classe qui enveloppe l'objet Properties le met à jour puis prévient modifie les ObservableStringValue en conséquence (stockées dans une Map<String,ObservableStringValue>). Ca vous semble raisonnable ou il y a mieux et plus simple avec JavaFX ?

    Merci d'avance pour votre aide !

  2. #2
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 57
    Points : 93
    Points
    93
    Par défaut
    J'ai tenté ceci, mais ça ne fonctionne pas. Les valeurs des StringProperty sont bien mises à jour mais les éléments de l'interface avec qui je les ai bindées ne réagissent pas.

    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
     
    package utils;
     
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.Reader;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Properties;
    import javafx.beans.property.StringProperty;
    import javafx.beans.property.StringPropertyBase;
     
    public class ObservableProperties extends Properties {
    	private final Map<String,StringProperty> properties = new HashMap<>();
     
    	public StringProperty getObservableProperty(String key) {
    		if (!containsKey(key))
    			throw new IllegalArgumentException("No such property : " + key);
    		return properties.get(key);
    	}
     
    	@Override
    	public Object setProperty(String key, String value) {
    		Object result = super.setProperty(key,value);
    		updateProperty(key,value);
    		return result;
    	}
     
    	@Override
    	public void load(Reader reader) throws IOException {
    		super.load(reader);
    		refresh();
    	}
     
    	@Override
    	public void load(InputStream fis) throws IOException {
    		super.load(fis);
    		refresh();
    	}
     
    	@Override
    	public void loadFromXML(InputStream fis) throws IOException {
    		super.loadFromXML(fis);
    		refresh();
    	}
     
    	private void refresh() {
    		for (Map.Entry<Object,Object> entry : entrySet()) {
    			String key   = entry.getKey().toString();
    			String value = entry.getValue().toString();
    			updateProperty(key,value);
    			System.out.println("Key : " + key + ", value : " + properties.get(key).getValue());
    		}
    	}
     
    	private void updateProperty(String key, String value) {
    		if (!contains(key))
    			properties.put(key,new ObservableProperty(this,key,value));
    		else 
    			properties.get(key).setValue(value);
    	}
     
    	private class ObservableProperty extends StringPropertyBase {
    		private final ObservableProperties	bean;
    		private final String				name;
     
    		public ObservableProperty(ObservableProperties bean, String name, String value) {
    			this.bean = bean;
    			this.name = name;
    			setValue(value);
    		}
     
    		@Override
    		public Object getBean() {
    			return bean;
    		}
     
    		@Override
    		public String getName() {
    			return name;
    		}	
    	}
    }
    Voilà un exemple de code où je fais un binding :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    //strings est un attribut de type ObservableProperties et il est initialisé juste après les préférences générales
    MenuItem newScene  = new MenuItem(strings.getProperty("newScene"));
    menuFile.getItems().add(newScene);
    newScene.textProperty().bind(strings.getObservableProperty("newScene"));
    Et enfin, à titre indicatif, le code qui est exécuté quand l'utilisateur demande à changer de langue :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    private void loadLocalizedTexts(String lang) {
            try (InputStreamReader isr = new InputStreamReader(getClass().getResourceAsStream(lang))) {
    			strings.load(isr);
    			isr.close();
    		} catch (IOException e) {
    			System.out.println("Error while retrieving the application texts and descriptions");
    			e.printStackTrace();
    		}
    	}
    }

    EDIT : bon ba c'était ma faute, j'ai mis !contains(key) à la place de !containsKey(key) dans la méthode updateProperty, du coup mes StringProperty étaient réinstanciées à chaque appel... Par ailleurs initialement même si containsKey(key) est vérifié, ça ne veut pas dire que properties.containsKey(key) l'est, alors il faut remplacer le test par :

    !properties.containsKey(key)

  3. #3
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    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 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Je te propose tout simplement de créer un nouveau binding de bas niveau.
    Voici un exemple pour les labels simple qu'on peut facilement étendre pour les labels composés en passant plus de valeurs ou de propriétés en arguments.
    Je tape le code de mémoire donc il faudra vérifier que ça compile correctement.

    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
    public final I18NBinding extends StringBinding {
     
      private final ObservableValue<Locale> observableLocale;
      private final final String labelKey;
     
      // Passer le bunble en paramètre si besoin.
      public I18NBinding(ObservableValue<Locale> observableLocale, final String labelKey) {
        super();
        if (observableLocale == null) {
          throw new IllegalArgumentException("observableLocale cannot be null");
        }
        if (labelKey== null) {
          throw new IllegalArgumentException("labelKey cannot be null");
        }
        this.observableLocale = observableLocale;
        this.labelKey = labelKey;
        bind(observableLocale);
      }
     
      @Override
      public void dispose() {
        unbind(observableLocale);
      }
     
      @Override
      protected String computeValue() {
         final Locale locale = observableLocale.getValue();
         // Récupérer la valeur depuis le bundle etc...
         String result = ...
         return result;
      }
    }
    Et plus loin dans le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    label.textProperty.bind(new I18NBinding(localeProperty(), "HELLO_WORLD_LABEL"));
    Ici dès que la propriété qui contient la locale du programme ou du controle change, le texte du label est recalculé et affiché à la valeur de la nouvelle langue.
    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

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

Discussions similaires

  1. Changer tous les noms des variables
    Par Imfafa dans le forum SAS Base
    Réponses: 8
    Dernier message: 09/05/2011, 12h10
  2. Réponses: 4
    Dernier message: 06/03/2009, 16h39
  3. changer tous les couleurs de l application
    Par capello123 dans le forum MFC
    Réponses: 2
    Dernier message: 25/05/2007, 15h15
  4. Réponses: 3
    Dernier message: 20/03/2007, 07h26
  5. [C#] Comment changer tous les btn d un coup
    Par Le Basque dans le forum Windows Forms
    Réponses: 8
    Dernier message: 13/01/2005, 18h21

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