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

API standards et tierces Java Discussion :

besoin d'un conseil : système de traduction


Sujet :

API standards et tierces Java

  1. #1
    Membre régulier Avatar de Merfolk
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    170
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 170
    Points : 113
    Points
    113
    Par défaut besoin d'un conseil : système de traduction
    Bonjour, voilà mon petit soucis

    je dois améliorer une application java et en faire du multilangue.
    J'ai prévu de mettre tous les labels dans une fichier genre

    1;Fichier;File
    2;Sauvegarder;Save

    etc.

    et de faire une classe "Traducteur", qui aurait une méthode static de type
    "getText(int codeTexte)"
    pour éviter de devoir instancier un objet et le passer à toutes les classes ce qui serait très embetant.

    Mais j'ai 2 problèmes du coup :

    - comment lire "au début" dans le fichier et le charger en mémoire, sachant que je n'ai pa d'instance de l'objet ?

    - pareil, je pense lire la "langue courante" dans un fichier ini.
    Mais je ne veux lire le fichier à chaque appel de la méthode..

    qqn a une bonne idée ?

    merci
    Chasseur de bug en activité
    L'erreur est humaine, mais pour vraiment foutre le bordel, on a besoin d'un ordinateur

  2. #2
    Membre émérite Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Points : 2 370
    Points
    2 370
    Par défaut
    Je n'ai pas vu où était le problème ??? Tu créés une classe static qui contient des variables static. Au début de ton programme tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Traducteur.load(monFichier);
    et ensuite de n'IMPORTE OU dans ton programme, dans toutes les classes, tu peux faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Traducteur.getText(int codeTexte);
    exemple :
    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
     
    public class Traducteur
    {
    private static String[][] termes;
    public (static) void load(String nomFichier)
    {
      ...
      termes = new String[3][100]; // 3 langues, 100 termes max
     ...
    }
     
    public (static) String getText(int langue, int terme)
    {
       return termes[langue][terme];
    }
     
    }
    Bon gaffe aux gestions d'erreur, objet non null etc.
    Il vaut mieux monopoliser son intelligence sur des bêtises que sa bêtise sur des choses intelligentes.

  3. #3
    Rédacteur
    Avatar de bigboomshakala
    Homme Profil pro
    Consultant Web .NET
    Inscrit en
    Avril 2004
    Messages
    2 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant Web .NET
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2004
    Messages : 2 077
    Points : 2 757
    Points
    2 757
    Par défaut
    salut

    pour l'internationalisation (localisation), java dispose des outils nécessaires. pas besoin de réinventer la roue

    voir du côté des classes Locale, ResourceBundle du package Java.util

  4. #4
    Membre régulier Avatar de Merfolk
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    170
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 170
    Points : 113
    Points
    113
    Par défaut
    ah, ok

    je pensais que les variables static devaient tout le temps être des constantes. Désolé & merci !!


    bigboom : franchement, je preferre faire une simple méthode qui prendra 6 lignes de codes plutôt que de devoir mettre en place X mécanismes style "je crée un objet ressource, je le referre etc.". Enfin moi ça me parait 200 * plus compliqué

    non ?
    Chasseur de bug en activité
    L'erreur est humaine, mais pour vraiment foutre le bordel, on a besoin d'un ordinateur

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Localisation élégante ;)
    C'est super simple à mettre en place, ça se fait en moins de dix minutes !
    Voilà ma classe statique :

    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
     
    import java.util.Locale;
    import java.util.MissingResourceException;
    import java.util.ResourceBundle;
    import java.util.Vector;
     
    public class lang {
    	private static final String BUNDLE_NAME = "messages"; //$NON-NLS-1$
    	private static ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME, Locale.getDefault());
     
    	public static String getString(String key) {
    		try {
    			return RESOURCE_BUNDLE.getString(key);
    		} catch (MissingResourceException e) {
    			return '!' + key + '!';
    		}
    	}
     
    	public static void setLangue(String p_code) {
    		RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME, new Locale(p_code));
    	}
     
    	public static Vector getListeLangues() {
    		// ???
    	}
    }
    BUNDLE_NAME est le radical commun du nom des fichiers de traduction
    RESOURCE_BUNDLE est l'objet qui pointe sur les bonnes ressources, chargées a partir du bon fichier. (Déterminé en lui passant un objet Locale qui contient le code langue). La méthode statique setLangue permet de modifier le contenu de cet objet. La langue par défaut est celle du système.
    Tout ce qu'il faut faire c'est créer ses fichiers messages_xx.properties, où xx est le code de la langue (fr pour français et en pour anglais). messages.properties est le fichier par défaut si le bon n'est pas trouvé.
    Dans ces fichiers, il suffit de faire une correspondance key=value.
    Ensuite dans ton programme tu appelle (Comme ce que tu voulais) lang.getString("key") et c'est bon !

    Bon, je venais pas faire l'altruiste sur le Forum. J'ai un soucis. Vous l'avez vu, ma méthode getListeLangues() est vide et pour cause. J'aimerais qu'elle me retourne dans un vecteur la liste des langues effectivement disponibles (Et non pas la liste des locales supportées par le système). L'idéal serait qu'elle liste mes fichiers message_xx.properties et qu'elle extraie pour chacun le couple lang.Name=Nom_humain_de_la_Langue. De cette façon, le simple ajout d'un fichier de traduction serait directement pris en compte dans le programme, sans compilation supplémentaire et surtout sans que l'éventuel traducteur n'ai à patouiller le code.
    Si quelqu'un à ma solution, c'est cool !

    Yorunokoe..

  6. #6
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 845
    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 845
    Points : 22 850
    Points
    22 850
    Billets dans le blog
    51
    Par défaut
    J'ai fait qq chose comme ça, qui marche dans le cadre de mon projet (à simplifier et améliorer dans ton cas) :

    Note : dans mon cas resourceID correspond au type de ressources i18n que je lis (string, images, icones, sons, fichiers d'aide...) c'est donc la racine du nom du fichiers .properties. set c'est un répertoire de stockage différent (un général un par application).

    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
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
     
      /** Gets available locales for given resource and set.
       * @param resourceID The resource ID.
       * @param set The resource set.
       * @return An array of <code>Locale</code> instance, never <code>null</code>.
       * @since 2.9
       */
      public Locale[] getAvailableLocales(String resourceID, String set) {
        if ( (resourceID == null) || (resourceID.trim().length() == 0)) {
          resourceID = ResourceConstants.STRING_RESOURCE;
        }
        if ( (set == null) || (set.trim().length() == 0)) {
          set = DEFAULT_SET;
        }
        String bundlePath = ResourceConstants.RESOURCES_PATH + set + ResourceConstants.FILE_SEPARATOR;
        final String basePrefix = bundlePath + resourceID;
        final String baseSuffix = ".properties";
        String baseFile = basePrefix + baseSuffix;
        URL url = getClass().getClassLoader().getResource(baseFile);
        System.out.println(bundlePath + " => " + url);
        Locale[] result = null;
        // We have a hold on a base translation file.
        if (url != null) {
          java.util.List<Locale> localeList = null;
          String filePath = url.toString();
          //System.out.println("The file path is " + filePath);
          java.util.List<String> filenameList = null;
          boolean useJar = false;
          ////////////////////////////////
          // We are currently accessing a JAR file.
          if (filePath.startsWith("jar:")) {
            useJar = true;
            // Beware of different protocols and platforms.
            // Works under Windows.
            /** @todo  Should be tested on Linux, Mac and Java Web Start ASAP. */
            /** @todo test, test and test !*/
            filePath = filePath.replaceFirst("jar:file:/", "");
            int index = filePath.indexOf("!");
            filePath = filePath.substring(0, index);
            //System.out.println("Trying to open " + filePath + " as a JAR");
            try {
              JarFile jar = new JarFile(filePath);
              // Unfortunatly it seems it's impossible to get the content of a directory in a JAR.
              // As of NOW we scan through the entire list of entries.
              // It seems to be reasonably fast though.
              Enumeration<JarEntry> entries = jar.entries();
              while (entries.hasMoreElements()) {
                JarEntry entry = entries.nextElement();
                String entryName = entry.getName();
                if (entryName.contains(basePrefix) && entryName.endsWith(baseSuffix)) {
                  if (filenameList == null) {
                    filenameList = new LinkedList<String>();
                  }
                  filenameList.add(entryName);
                  //System.out.printf("%s, directory %b\n", entry.getName(), entry.isDirectory());
                }
              }
            }
            catch (IOException ioe) {
              ioe.printStackTrace();
            }
          }
          ////////////////////////////////
          // We are currently accessing a directory.
          else {
            File hostDirectory = new File(url.getFile()).getParentFile();
            if ( (hostDirectory != null)) { //&& (hostDirectory.isDirectory())) {
              //System.out.printf("File %s (%s), exist %b, directory %b, readable %b\n", hostDirectory, url.toString(), hostDirectory.exists(), hostDirectory.isDirectory(), hostDirectory.canRead());
              final String resourceName = resourceID;
              FileFilter filter = new FileFilter() {
                /** {@inheritDoc}
                 */
                public boolean accept(File pathname) {
                  String path = pathname.getName();
                  return (path.startsWith(resourceName) && path.endsWith(baseSuffix));
                }
              };
              File[] files = hostDirectory.listFiles(filter);
              if (files != null) {
                filenameList = new LinkedList<String>();
                for (File file : files) {
                  filenameList.add(file.getName());
                }
              }
            }
          }
          ////////////////////////////////
          // Create locales from the filenames.
          if ( (filenameList != null) && (filenameList.size() > 0)) {
            localeList = new LinkedList<Locale>();
            for (String name : filenameList) {
              if (useJar) {
                name = name.replaceAll(basePrefix, "");
              }
              else {
                name = name.replaceAll(resourceID, "");
              }
              name = name.replaceAll(baseSuffix, "");
              if (name.startsWith("_")) {
                name = name.substring(1);
              }
              Locale locale = ResourceConstants.DEFAULT_LOCALE;
              if (name.length() > 0) {
                String language = "";
                String country = "";
                String variant = "";
                StringTokenizer tokenizer = new StringTokenizer(name, "_");
                if (tokenizer.countTokens() >= 1) {
                  language = tokenizer.nextToken();
                }
                if (tokenizer.countTokens() >= 1) {
                  country = tokenizer.nextToken();
                }
                if (tokenizer.countTokens() >= 1) {
                  variant = tokenizer.nextToken();
                }
                locale = new Locale(language, country, variant);
              }
              if (!localeList.contains(locale)) {
                //System.out.println("Found locale " + locale);
                localeList.add(locale);
              }
            }
            ////////////////////////////////
            // Transform into array.
            result = new Locale[localeList.size()];
            result = localeList.toArray(result);
            localeList.clear();
          }
        }
        ////////////////////////////////
        // Could not get locales from file inspection, return locales supported by the JVM.
        // This operation can take a long time to execute.
        if (result == null) {
          result = Locale.getAvailableLocales();
        }
        return result;
      }
    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

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Ok, merci beaucoup !

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

Discussions similaires

  1. Besoin de quelques conseils pour un script java
    Par poussin544 dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 02/03/2006, 10h41
  2. [iText] besoin d'un conseil
    Par Alec6 dans le forum Documents
    Réponses: 4
    Dernier message: 12/10/2005, 06h56
  3. Game design [Besoin d'aide, conseils....]
    Par poussinphp dans le forum Langage
    Réponses: 23
    Dernier message: 24/09/2005, 09h16
  4. Besoin d'un conseil pour une sélection Access/fichier
    Par Oluha dans le forum Bases de données
    Réponses: 1
    Dernier message: 20/03/2005, 19h10

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