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

Langage Java Discussion :

Fichiers langues: Classe abstraite / interface ou autre?


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2005
    Messages : 65
    Par défaut Fichiers langues: Classe abstraite / interface ou autre?
    Bonjour à tous,

    Je dois réaliser une application de traitement d'image en java pour l'école.

    J'avais pris soin de faire une classe "Config" avec des variables statiques pour l'utilisation de l'application. Elle contient notamment les messages "texte" de l'applic ("ok", "Etes vous sur de vouloir quitter l'application sans sauver?"...).

    Voici un exemple très concis du fichier (écrit rapidement...):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public class Config {
    ...
    public static final String NO_FILE_FOUND_MESSAGE = "Le fichier a ete supprime entre temps ou est verrouille par une autre application!";
    public static final String NO_FILE_FOUND_TITRE = "Erreur: fichier introuvable";
     
    public static final String UNVALID_FILE_MESSAGE = "Le fichier n'a pas pu etre ouvert car il n'est pas une image valide.";
    public static final String UNVALID_FILE_TITRE = "Erreur: fichier invalide";
    ...
     
    public static final int MAX_APPLICATION_WIDTH = 950;
    public static final int MAX_APPLICATION_HEIGHT = 700;
    ...
    J'aurais aimé permettre à l'application de devenir multilangue.

    J'avais d'abord pensé à faire une classe abstraite "Config".
    Deux sous-classe auraient été: "Config_FR" et "Config_ENG".

    La classe config aurait eu la forme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public abstract class Config {
    ...
    public String NO_FILE_FOUND_MESSAGE;
    public String NO_FILE_FOUND_TITRE;
     
    public String UNVALID_FILE_MESSAGE;
    public String UNVALID_FILE_TITRE;
    ...
     
    public int MAX_APPLICATION_WIDTH = 950;
    public int MAX_APPLICATION_HEIGHT = 700;
    ...
    Et la nouvelle Config_FR (idem pour _ENG...)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public class Config_FR extends Config {
    ...
    public String NO_FILE_FOUND_MESSAGE="blablabla en FR";
    public String NO_FILE_FOUND_TITRE="blablabla en FR";
     
    public String UNVALID_FILE_MESSAGE="blablabla en FR";
    public String UNVALID_FILE_TITRE="blablabla en FR";
    ...
    Je pensais compter sur 2 choses:
    -Un élément non défini dans une classe abstraite, doit l'être dans sa sous classe. Je n'aurais donc pas défini les variables "texte" dans "Config" qui aurait du être redéfinie dans les sous classes des 2 langues.
    -Un élément déjà défini ne doit pas être redéfini dans les sous classe (mais pourrait l'être): Les variables du type "taille de l'applic" qui ne change pas d'une langue a l'autre auraient été définie dans la classe abstraite.

    Malheureusement ça ne marche pas. J'ai une valeur null pour les deux affichages:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Config c = new Config_FR();
    System.out.println(c.TOO_HEAVY_PICTURES_MESSAGE);
    //L'utilisateur switch en anglais...
    c = new Config_ENG();
    System.out.println(c.TOO_HEAVY_PICTURES_MESSAGE);
    J'en conclu qu'il va chercher la variable de Config et que les 2 points que j'ai énuméré quelques lignes plus haut ne s'appliquent qu'aux méthodes d'une classe abstraite. (?). Je trouve que des GET pour récupérer toutes cette tonne de variable est assez lourd, et visuellement moins "agréable" à lire dans le code.

    J'ai essayé une interface, mais les variables doivent être déclarée dans une l'interface.

    Bref, avant de m'éparpiller complètement dans une mauvaise conception (si c'est pas déjà fait ), j'aurais bien aimé avoir une aide pour concevoir une petite application multilangue.
    Est-ce que la classe abstraite et les sous classe spécifique a chaque langue étaient une bonne idée? Si oui, comment faire?
    Sinon y a t'il des méthodes plus élégante?

    Merci d'avance!

    EDIT: Il est interdit d'utiliser des librairies externes au JDK. J'avais pensé à de l'XML mais bon ca risque d'être un peu lourd

  2. #2
    Membre expérimenté Avatar de mOuLi
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2008
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2008
    Messages : 170
    Par défaut
    Le JDK offre des classes pour gérer le "multi-linguisme", il faut regarder du côté de java.util.ResourceBundle (prise en compte des libellés à partir de fichier properties) ou java.util.ListResourceBundle (basé sur des collections Java).

  3. #3
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Ce comportement est normal puisqu'il n'y a pas d'héritage sur les attributs. Donc l'attribut NO_FILE_FOUND_MESSAGE de ta classe Config est différent de l'attribut NO_FILE_FOUND_MESSAGE de ta classe Config_FR, etc.

    Et comme dans ton code tu utilises toujours sur une instance de Config, le lien vers la classe fille ne se fait pas...



    Si tu veux vraiment continuer dans cette solution, il te faudra passer par des méthodes abstraite, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    abstract class Config {
     
    	public abstract String getNoFileFoundMessage();
     
    	// ...
     
    }
    Mais je te déconseille fortement de faire cela, car ta classe va évoluer avec ton application, et le nombre de méthode va augmenter : il faudra que toutes les classes soient à jour sous peine de générer une exception à l'exécution car les nouvelles méthodes n'ont pas été redéfinies




    Pour gérer cela, il existe un système de ResourceBundle très simple à mettre en oeuvre :
    1. Tu crées un package qui contiendra tes ressources. Ce sera com.monsite.monappli.i18n dans mon exemple.
    2. Dans ce package tu crées une classe qui te servira d'accès aux données, via des méthodes static :
      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
      package com.monsite.monappli.i18n;
      import java.util.Locale;
      import java.util.MissingResourceException;
      import java.util.ResourceBundle;
       
      public final class Config {
      	/** Nom de base des fichiers *.properties (package + nom). */
      	private static final String NAME = "com.monsite.monappli.i18n.config";
      	/** L'instance du ResourceBundle en cours d'utilisation. */
      	private static ResourceBundle BUNDLE = ResourceBundle.getBundle(NAME);
       
       
      	/** Méthode permettant de changer la locale (en changeant le ResourceBundle) */
      	public static void setLocale(Locale locale) {
      		BUNDLE = ResourceBundle.getBundle(NAME, locale);
      	}
       
      	/** Méthode permettant de retrouver la valeur d'une clef */
      	public static String getString(String key) {
      		try {
      			return BUNDLE.getString(key);
      		} catch (MissingResourceException e) {
      			// Si la clef n'existe pas, on retourne une valeur permettant de l'indiquer :
      			return "!!!" + key + "!!!";
      		}
      	}
      }
      Il suffit ensuite d'utiliser la méthode getString() pour retrouver la valeur associée à une clef :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      String message = Config.getString("NO_FILE_FOUND_MESSAGE");
    3. Enfin, la dernière étape consiste à créer dans ce package des fichier properties contenant les couples clef/valeurs, par exemple :
      Code X : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      NO_FILE_FOUND_MESSAGE = Le fichier a ete supprime entre temps ou est verrouille par une autre application!
      NO_FILE_FOUND_TITRE = Erreur: fichier introuvable
          
      UNVALID_FILE_MESSAGE = Le fichier n'a pas pu etre ouvert car il n'est pas une image valide.
      UNVALID_FILE_TITRE = Erreur: fichier invalide
       
      MAX_APPLICATION_WIDTH = 950;
      MAX_APPLICATION_HEIGHT = 700;

      Ces fichiers doivent être nommé en respectant la convention des fichiers properties : name_language_country_variant.properties (où name provient de ce que tu as indiqué dans le code, et où les éléments variant/country/language sont optionnel dans cet ordre).

      En gros Tu créeras un fichier config_fr_FR.properties pour les spécificités franco-française, config_fr_CH.properties pour les suisses francophone, config_en_UK.properties pour l'anglais, config_en_US.properties pour l'anglais américain...
      Tu peux également utilisé config_fr.properties pour les propriétés communes à tous les francophones, et config_en.properties pour les anglophones.
      Enfin config.properties te permettra de définir des valeurs communes à tous.


    Lorsque tu recherches une clef, elle est recherchée dans chacun des properties correspondant, du plus précis au moins précis. Par exemple si tu es en fr_FR, les valeurs de config_fr_FR.properties auront la priorité sur config_fr.properties, qui lui même aura la priorité sur config.properties...

    La variante permet de rajouter un niveau supplémentaire, et n'est utilisé que très rarement dans certaines langues avec de fortes disparités...



    a++

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2005
    Messages : 65
    Par défaut
    Merci à vous deux pour vos réponses.
    En particulier, merci à adiGuba pour l'exemple détailler

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

Discussions similaires

  1. Classe Abstraite / Interface
    Par Mornor dans le forum Général Java
    Réponses: 6
    Dernier message: 08/12/2013, 15h19
  2. Classe abstraite ? Interface ?
    Par Gaetch dans le forum Modélisation
    Réponses: 1
    Dernier message: 17/10/2010, 19h45
  3. Réponses: 2
    Dernier message: 27/05/2010, 13h35
  4. Réponses: 9
    Dernier message: 21/01/2008, 11h26
  5. Classe Abstraite, Interface....
    Par greatdonking dans le forum Langage
    Réponses: 6
    Dernier message: 07/11/2005, 16h19

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