Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
3242 connectés 

  FORUM HardWare.fr
  Programmation
  Java

  Interface graphique et internationalisation

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Interface graphique et internationalisation

n°1483110
Corey83
Posté le 28-11-2006 à 16:11:52  profilanswer
 

Bonjour à tous,
 
Je suis en train (plutôt je commence) de développer une application en interface graphique (Java - Swing). Je rencontre tout d'abord quelques difficultés à bien construire mon code. Voilà un exemple de ce que j'ai fait :

Code :
  1. import javax.swing.JFrame;
  2. public class FenetrePrincipal{
  3. public static void main(String args[]){
  4.  JFrame frame = new JFrame("Fenêtre principal" );
  5.  new BarreMenu(frame);
  6.  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  7.  frame.setSize(800, 600);
  8.  frame.setVisible(true);
  9. }
  10. }
  11. import javax.swing.JFrame;
  12. import javax.swing.JMenu;
  13. import javax.swing.JMenuBar;
  14. import javax.swing.JMenuItem;
  15. import javax.swing.JSeparator;
  16. import javax.swing.KeyStroke;
  17. public class BarreMenu {
  18. final JFrame frame;
  19. public BarreMenu(JFrame frame){
  20.  this.frame = frame;
  21.  JMenuBar menuBar = new JMenuBar();
  22.  ajouterMenuFichier(menuBar);
  23.  frame.setJMenuBar(menuBar);
  24. }
  25. private void ajouterMenuFichier(JMenuBar menuBar){
  26.  JMenu menuFichier = new JMenu("Fichier" );
  27.  JMenuItem menuItemDeconnexion = new JMenuItem("Changer d'utilisateur..." );
  28.  JMenuItem menuItemQuitter = new JMenuItem("Quitter" );
  29.  menuItemQuitter.addActionListener(new ActionListener(){
  30.   public void actionPerformed(ActionEvent event){
  31.    frame.dispose();
  32.   }
  33.  });
  34.  menuItemDeconnexion.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, ActionEvent.CTRL_MASK));
  35.  menuItemQuitter.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));
  36.  menuFichier.add(menuItemDeconnexion);
  37.  menuFichier.add(menuItemQuitter);
  38.  menuBar.add(menuFichier);
  39. }
  40. }


 
Donc en fait comme c'est une "belle" (assez grosse) interface je vais découper la frame principale en sous-classes afin que ce soit plus "propre". Comme dans mon exemple ci-dessus une classe pour le menu.  
J'ai un peu de mal à bien structurer mon code parce que voilà ce que le prof (oui c'est un projet d'études) ne veut pas que l'on fasse dans notre code :
 
Java est un langage Objet, il est donc possible d'utiliser l'héritage.
 
Doit-on hériter par exemple de la classe JFrame ? NON !
 
ex à pas faire :  

Code :
  1. import javax.swing.*;
  2. public class MorphSwing2 extends JFrame {
  3. public MorphSwing2() {
  4.  super("MorphSwing2" );
  5.  JButton button=new JButton("Ok" );
  6.  setContentPane(button);
  7.  setSize(400,300);
  8.  setVisible(true);
  9. }
  10. public static void main(String[] args) {
  11.  new MorphSwing2();
  12. }
  13. }


 
mais

Code :
  1. import javax.swing.*;
  2. public class MorphSwing1 {
  3. public static void main(String[] args) {
  4.  JButton button=new JButton("Ok" );
  5.  JFrame frame=new JFrame("MorphSwing1" );
  6.  frame.setContentPane(button);
  7.  frame.setSize(400,300);
  8.  frame.setVisible(true);
  9. }
  10.  }


 
On hérite d'une classe si on veut en changer les fonctionnalités (i.e. redéfinir une méthode)
 
Il est possible de faire des fonctions pour rendre le code plus clair
 
Et enfin,  
Doit-on stocker les composants en tant qu'attributs de la classe ?
NON! Les composants sont déjà stockés dans leurs parents.
 
ex :

Code :
  1. import javax.swing.*;
  2. public class MorphSwing4 extends JFrame {
  3. private final JButton button; // idiot
  4. public MorphSwing4() {
  5.  super("MorphSwing2" );
  6.  button=new JButton("Ok" );
  7.  setContentPane(button);
  8. }
  9. public static void main(String[] args) {
  10.  JFrame frame=new MorphSwing4();
  11.  frame.setSize(400,300);
  12.  frame.setVisible(true);
  13. }
  14. }


 
Si des personnes pouvait me dire ce qu'il ne va pas dans mon code ou ce qu'il faudrait que j'améliore se serai vraiment sympa.
 
Sinon, je voudrais aussi intégrer la possibilité d'internationaliser mon appli donc j'ai trouvé ce code qu'il a l'aire pas mal :  

Code :
  1. import java.awt.event.ActionEvent;
  2. import java.awt.event.ActionListener;
  3. import java.util.Locale;
  4. import java.util.ResourceBundle;
  5. public class LanguageChooser implements ActionListener {
  6. // Nom du fichier properties (sans les codes ISO)
  7. private static final String LANGUAGE_FILE = "language";
  8. private static ResourceBundle resourceBundle;
  9. // La fenetre
  10. private MyFrame frame;
  11. public LanguageChooser(MyFrame aFrame) {
  12.  frame = aFrame;
  13.  resourceBundle = ResourceBundle.getBundle(LANGUAGE_FILE, Locale.getDefault());
  14. }
  15. // Methode appelee lorsqu’on selectionne un menu
  16. public void actionPerformed(ActionEvent arg0) {
  17.  // On a selectionne le menu anglais
  18.  if (arg0.getActionCommand().equals("menuEn" )) {
  19.  // On choisi le fichier anglais
  20.  resourceBundle = ResourceBundle.getBundle(LANGUAGE_FILE, Locale.US);
  21.  }
  22.  // Sinon on choisi le francais
  23.  else if (arg0.getActionCommand().equals("menuFr" )) {
  24.  // On choisi le francais
  25.  resourceBundle = ResourceBundle.getBundle(LANGUAGE_FILE, Locale.FRANCE);
  26.  }
  27.  //On modifie les labels avec la nouvelle langue
  28.  frame.paintLabelWithLanguage();
  29. }
  30. /*
  31. * Methode statique qui permet de recuperer un String du fichier de langue
  32. * en fonction de la cle passee en parametre
  33. */
  34. public static String getAnInternationalizeString(String key) {
  35.  // On retourne la valeur associee a la cle
  36.  return resourceBundle.getString(key);
  37. }
  38. }
  39. import javax.swing.*;
  40. public class MyFrame extends JFrame {
  41. // Déclaration des différents composants
  42. private JLabel labelHello;
  43. private JMenuBar menuBar;
  44. private JMenu menuLanguage;
  45. private JMenuItem menuFr;
  46. private JMenuItem menuEn;
  47. private LanguageChooser languageChooser;
  48. // Point d’entrée de l’application
  49. public static void main(String[] args) {
  50.  MyFrame fenetre = new MyFrame();
  51. }
  52. public MyFrame() {
  53.  // Initialisation standard
  54.  super("Application Internationale" );
  55.  setSize(300, 300);
  56.  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  57.  // Création du LanguageChooser
  58.  languageChooser = new LanguageChooser(this);
  59.  // Création du label
  60.  labelHello = new JLabel();
  61.  getContentPane().add(labelHello);
  62.  // Création de la barre de menu
  63.  menuBar = new JMenuBar();
  64.  menuLanguage = new JMenu();
  65.  menuFr = new JMenuItem("Francais" );
  66.  menuFr.setActionCommand("menuFr" );
  67.  menuFr.addActionListener(languageChooser);
  68.  menuLanguage.add(menuFr);
  69.  menuEn = new JMenuItem("English" );
  70.  menuEn.setActionCommand("menuEn" );
  71.  menuEn.addActionListener(languageChooser);
  72.  menuLanguage.add(menuEn);
  73.  menuBar.add(menuLanguage);
  74.  setJMenuBar(menuBar);
  75.  // On initailise les valeurs des labels, menus
  76.  paintLabelWithLanguage();
  77.  // On affiche la fenêtre
  78.  setVisible(true);
  79. }
  80. /*
  81. * Méthode qui initialise le texte des différents labels et menus en
  82. * fonction de la langue
  83. */
  84. protected void paintLabelWithLanguage() {
  85.  menuLanguage.setText(LanguageChooser.getAnInternationalizeString("menuLanguage" ));
  86.  labelHello.setText(LanguageChooser.getAnInternationalizeString("labelHello" ));
  87. }
  88. }


Mais voilà j'ai du mal à l'intégrer dans mon code afin que les conditions du prof soient respectées et que je puisse l'utiliser sur différent de la fenêtre (menu, calendrier, panel central, pop-up, ...). Si vous avez des aidés elles sont les bienvenues.
 
Merci d'avance à tous

mood
Publicité
Posté le 28-11-2006 à 16:11:52  profilanswer
 

n°1485253
doctib
Posté le 01-12-2006 à 22:49:14  profilanswer
 

Pourrais tu être un peut plus clair s'il te plaît...
 
pourquoi ne peux tu te créer une classe qui utlise l'héritage ex:
 

Code :
  1. //les imports qui vont bien :)
  2. public class MaFentre extends JFrame{
  3. private JPanel pnlCentre;
  4. private JMenuBar mb;
  5. private JDialog d;
  6. //et tout les composant graphique que tu as... en private
  7. //maintenant les méthode qui vont bien :)
  8. /**
  9. *constructeur de MaFenetre
  10. */
  11. public MaFenetre(){
  12. super();
  13. //initialisation de la fenetre
  14. this.getContentPane().add(this.getPnlCentre(), BorderLayout.CENTRE);
  15. this.setMenuBar(this.getMb());
  16. this.getListeners();
  17. }
  18. /**
  19. *construction de ton panneau centre
  20. */
  21. public JPanel getPnlCentre(){
  22. //test la non nullité du JPanel puis ajoute ce que tu as besoin
  23. }
  24. /**
  25. *construction de la bar de menu
  26. */
  27. public JPanel getMb(){
  28. //test la non nullité du JMenuBar puis ajoute ce que tu as besoin
  29. }
  30. /**
  31. *Construction des listeners
  32. */
  33. public void constructListeners(){
  34. //utilise la méthode de ton choix, je te recommande l'utilisation de classe anonyme
  35. }
  36. }


 
 
 
pour l'internationnalisation... pour faire simple :p
 
tu vas avoir plusieurs fichiers (fr_FR, en_US, en_EN) avec les même tag, mais des mesages différents
exemple, le tag out:
out           = quitter (fr_FR)
out           = exist (en_EN)
out           = quit (en_US)
 
ensuite dant ton programme tu vas spécifier quel tag tu veux utiliser... (par exemple out).
 
mais comment savoir dans quel langue tu va l'exprimer?? (fr_FR, en_US.... et plein d'autre)
grace à la classe ResourceBundle (la région dans laquel tu te trouve, par défaut ou celle ou tu aimerais te trouver)
 
il faudrat aussi spécifier le fichier que tu veux utiliser...
 
mais ça c'est une autre histoire :)
 
je te conseil d'aller voir là pour plus d'info: www.infini-fr.com
 
pour résumer

Code :
  1. { // tout ça dans ton  code internationnalisé
  2. /*Locale : cette classe permet de définir un objet de définition de la langue et du pays pris en compte. On peut obtenir un objet Locale par défaut en saisissant Locale.getDefault();*/
  3. private static Locale locale               = null;
  4. private static ResourceBundle bundle = null;
  5.  
  6. //pour spécifier la région         
  7. locale = new Locale("en","US" );
  8. //pour spécifier quel fichier tu utilise
  9. bundle = ResourceBundle.getBundle("Fichierdeprop", locale);
  10. //tu récupère la valeur de out dans le fichier: Fichierdeprop_en_US.properties
  11. String quit = bundle.getString("out" );


 
voilà voilà
 
si tu as des question n'hésite pas :p

Message cité 1 fois
Message édité par doctib le 01-12-2006 à 23:18:02
n°1486871
Corey83
Posté le 06-12-2006 à 00:28:30  profilanswer
 

doctib a écrit :

Pourrais tu être un peut plus clair s'il te plaît...
pourquoi ne peux tu te créer une classe qui utlise l'héritage...

Bah en fait c'est le prof qui le dit texto dans son cours "Java est un langage Objet, il est donc possible d'utiliser l'héritage. Doit-on hériter par exemple de la classe JFrame ? NON !".  
 
Sinon, j'ai un peu de mal à internationaliser mon appli. En faite le choix de la langue se fait au travers d'une fenêtre de préférences (qui utilisera un fichier preferences.conf). Une fois la langue changée dans cette fenêtre, l'internationalisation de l'appli (que les boutons, menus, labels et certaines cellules de JTables) doit se faire dynaniquement.  
Dans l'exemple que j'ai mis dans mon post il fait ça en dure :

Code :
  1. /** Méthode qui initialise le texte des différents labels et menus en     
  2. * fonction de la langue     
  3. */   
  4. protected void paintLabelWithLanguage() {       
  5.        menuLanguage.setText(LanguageChooser.getAnInternationalizeString("menuLanguage" ));       
  6.        labelHello.setText(LanguageChooser.getAnInternationalizeString("labelHello" ));   
  7. }


Mais voilà le prof ne veut pas aussi que l'on stocke les composants en tant qu'attributs de la classe du moins "on peux faire mieux que les stocker dans des champs".
Je ne sais pas trop comment faire ça proprement et que ça internationalise toute mon appli classe par classe (vues).

n°1488816
Corey83
Posté le 08-12-2006 à 18:15:36  profilanswer
 

doctib t'as pas une idée ou une suggestion à mon problème ?

n°1489386
doctib
Posté le 11-12-2006 à 09:51:02  profilanswer
 

as tu regarder ce que j'ai mis???
 
il faut en fait utiliser la commande:

Code :
  1. menuLanguage.setText(bundle.getString("menulangague" );
  2. // et tu va récupérer toute les propriétés ainsi :)


mais comment savoir quelle propriété récuppérer? tu vas pouvoir choisir cela en fonction de ton objet:

Code :
  1. //tu spécifie ton langage et ta région  
  2. locale = new Locale("en","US" );
  3. //tu spécifie le fichier et le langage que tu veux
  4. ResourceBundle.getBundle("fichierDeProp", locale);
  5. //tu dois avoir un fichier fichierDeProp_en_US.properties
  6. //tu en aura autant que tu as de langage différents dans ton appli


 
regards le liens que j'ai donnée plus haut, vers www.infini-fr.com, il y a un exemple détaillé :)

n°1490222
Corey83
Posté le 12-12-2006 à 14:00:54  profilanswer
 

doctib a écrit :

as tu regarder ce que j'ai mis???
 
il faut en fait utiliser la commande:

Code :
  1. menuLanguage.setText(bundle.getString("menulangague" );
  2. // et tu va récupérer toute les propriétés ainsi :)


mais comment savoir quelle propriété récuppérer? tu vas pouvoir choisir cela en fonction de ton objet:

Code :
  1. //tu spécifie ton langage et ta région  
  2. locale = new Locale("en","US" );
  3. //tu spécifie le fichier et le langage que tu veux
  4. ResourceBundle.getBundle("fichierDeProp", locale);
  5. //tu dois avoir un fichier fichierDeProp_en_US.properties
  6. //tu en aura autant que tu as de langage différents dans ton appli


 
regards le liens que j'ai donnée plus haut, vers www.infini-fr.com, il y a un exemple détaillé :)


Oui j'ai regardé ce que tu as mis et aussi le site www.infini-fr.com.
Mais en fait ta solution (ci-dessous) ne marche que si je déclare les composants de la frame en tant qu'attributs de la classe. :

Code :
  1. menuLanguage.setText(bundle.getString("menulangague" );


Mais notre prof ne veut que l'on stocke les composants en tant qu'attributs de la classe.
Donc ce que j'ai fait c'est que dans les méthodes qui créent les composants je leur ai associé des actionCommand (avec setActionCommand(String)) et je le récupère avec getActionCommand(). Mais ça ne marche pas pour les labels d'une part.
Et de deux je suis obligé de récupérer les composants du menu (dans mon expemple de mon début de post) puis descendre afin de récupérer les menuItem afin de changer leur labels, en utilsant 2 for imbriqués.
Donc en fait je ne sais pas trop comment faire ça proprement et que ça internationalise toute mon appli classe par classe.
 

n°1493930
moustik510
Enfin en travaux !
Posté le 20-12-2006 à 10:09:40  profilanswer
 

Corey83 a écrit :

Java est un langage Objet, il est donc possible d'utiliser l'héritage.
 
Doit-on hériter par exemple de la classe JFrame ? NON !


Comme quoi les profs vous forment à leur façon de coder. Moi j'avais pas eu le même cours ... Son argument se défend mais de là à interdire le extends JFrame ... Une classe A doit héritée d'une classe B que si elle modifie les propriétés de la classe B ? Et si la classe A est une classe B améliorée (je sais je m'exprime mal en POO) ? Moi je ne vois pas rien de mal à faire un "class Chien extends Animal" ... Mais bon ... si on fait pas comme le prof ...  :ange:

Corey83 a écrit :

Et enfin,  
Doit-on stocker les composants en tant qu'attributs de la classe ?
NON! Les composants sont déjà stockés dans leurs parents.
 
ex :
[cpp]import javax.swing.*;
 
public class MorphSwing4 extends JFrame {
 
 private final JButton button; // idiot


Imaginons qu'après une action X tu aies besoin de modifier le texte de ton bouton.
-Avec la méthode qui ne plait pas à ton prof, tu fais bouton.setText("Nouvelle action !" );
-Avec sa méthode ... tu vas t'amuser à chercher dans le JFrame.getComponents() et tester dans la liste de retour si c'est bien ton bouton ?  :ouch:
 
EDIT : je sais ça ne répond pas à ta question ... mais j'avais envie de réagir aux impératifs de ton profs. dsl


Message édité par moustik510 le 20-12-2006 à 10:11:00
n°1499230
angelx24
Posté le 05-01-2007 à 11:30:40  profilanswer
 

Tout d'abord, afin d'avoir un code propre et pro, utilise le mvc (modèle vue controleur) pour les interface graphique.
 
- une classe disons launcher qui créer une classe dérivé de JFrame pour l'interface et qui ne possède que le menu et la gestion du layout et et une instance des classes dérivées de panel.
 
- des classes dérivées de panel pour les interfaces implémentant Observer car elles vont observé un model de donnée de ton appli.
 
- Un model de donnée dérivé d'Observable qui servira a manipuler tes données.
 
- Une classe controleur dérivé qui gérera les boutons.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Java

  Interface graphique et internationalisation

 

Sujets relatifs
Problème affichage graphiqueMéthodes virtuelles, création d'interface.
User Interface ProcessUtilisation de UIA (User Interface Application Block)
[Java] Interface Graphique : pb setLocation & setSizeClasse abstraite implémentant une interface
erreur dans un programme graphiqueInterface graphique
Plus de sujets relatifs à : Interface graphique et internationalisation


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR