Problème fondamental

Pasokoniidesuka Messages postés 20 Date d'inscription mercredi 21 juillet 2010 Statut Membre Dernière intervention 17 janvier 2012 - 22 févr. 2011 à 04:47
Pasokoniidesuka Messages postés 20 Date d'inscription mercredi 21 juillet 2010 Statut Membre Dernière intervention 17 janvier 2012 - 22 févr. 2011 à 21:40
Bonjour,
je viens demander vos lumières parce que je me mélange un peu les pinceaux.
C'est peut-être un topic pour les courageux parce que ça risque d'être un peu long. Désolé.

Je débute en Java et je cherche à apprivoiser Swing, au moins le minimum syndical. Rien de mieux que de faire une petite appli "ébauche" pour tester.

Alors pour le moment l'appli est super simple sur le concept : L'appli tourne autour d'une classe Personne (pour le moment concernant qu'une seule instance). Un JFrame et un menu dans lequel une option intéressante fait apparaître un JDialog qui lui affiche des JTextField notamment.

Alors pour créer une telle boite de dialogue aussi simple soit-elle il existe plusieurs méthodes. Celle que j'aurais utilisé personnellement c'est celle qui consiste à considérer chaque contrôle comme un attribut de la classe. J'ai pu voir ça et là des exemples où l'on réutilise une variable pour créer de nouveaux objets du même type.
Exemple de la méthode 1
private JLabel labelNom =   new JLabel("Nom");
private JLabel labelPrenom = new JLabel("Prénom");
...
// Ajout au conteneur
add(labelNom);
add(labelPrenom);

Exemple de la méthode 2
private JLabel label;
label = new JLabel("Nom");
add(label);
label = new JLabel("Prénom");
add(label);


Quelque soit le contrôle il est effectivement créé et ajouté au conteneur et dans le cas des label ça peut passer vu qu'en général on ne les touches plus mais si je veux agir sur un contrôle il me faut bien un "point d'accès" vers lui. Si je veux par exemple mettre à jour le texte du label, dans la première méthode je connais les points d'accès (les variables labelNom et labelPrenom) mais dans le second cas comment fait-on pour accéder à un contrôle puisque la variable label fait référence au dernier objet créé si je ne trompe pas ?
Visual Editor utilise encore une autre manière de faire avec des fonctions pour créer les contrôles mais bon passons...

Maintenant j'arrive afficher et cacher une fenêtre mais ne peut-on pas libérer les ressources ? Il y a bien dispose mais si je l'utilise la fenêtre ne s'affiche qu'une seule fois. (oui c'est ma faute j'ai codé comme un pied mais c'est pas pour rien que je viens poser des questions ici)
Autre souci maintenant c'est au niveau de la conception de l'application.
Alors j'ai mon Dialogue qui contient les données d'une instance de la classe Personne. Pour le moment ce que j'ai pensé faire c'est ajouter une instance de la classe dans la classe qui définit le JDialog mais maintenant si je veux utiliser les données ailleurs, comment je fais ? L'instance prend son origine dans le JDialog, si je ne me trompe pas les autres ne le voient pas si je libère les ressources du JDialog (et dans le cas contraire un assesseur suffit-il ?)
N'y a t-il pas un moyen de dire un truc genre " Hey ho je suis une instance de la classe Personne donc j'existe et vous pouvez tous appeler getNom() et ses copines d'où que vous soyez ! " de telle sorte que par exemple sur une autre fenêtre on puisse accéder aux données de l'instance de classe Personne et qu'on fasse des traitements.
Où instancier la classe Personne dans mon code ?

Ensuite pour gérer les actions des menus, boutons, etc... comment on centralise tout ça ?

Si vous avez eu le courage de lire jusqu'ici vous avez sûrement compris qu'il s'agit d'un gros topic "Conseils pour la conception d'appli avec Swing" qui repose sur une appli ébauche simple. Bref dites moi ce qui ne va pas, ce qu'il faudrait changer dans ma méthodologie.

Toutes les classes ne sont pas utiles à la compréhension de la question donc je vous met le détail des packages et quelques sources pour vous permettre d'avoir une idée plus claire du problème.

Détail des packages :
entities:
-Personne
gui:
-DialoguePersonne
-MainGui
gui.menu:
-MainMenuBar
-MenuFichier
-MenuAide
main:
-MonMain

Classe MenuFichier :
package gui.menu;

import gui.DialogPersonne;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JDialog;
import javax.swing.JMenu;
import javax.swing.JMenuItem;

@SuppressWarnings("serial")
public class MenuFichier extends JMenu implements ActionListener {
JMenuItem item;
JDialog dialog;

public MenuFichier() {
this("Fichier");
}

public MenuFichier(String text) {
setText(text);

item   = new JMenuItem("Définir les détails");
item.addActionListener(this);
add(item);
item =  new JMenuItem("Quitter");
item.addActionListener(this);
add(item);		
}

@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand() == "Définir les détails") {
if (null == dialog) {
dialog = new DialogPersonne();
}
((DialogPersonne) dialog).afficher();
}
if (e.getActionCommand() == "Quitter") {
System.exit(0);
}
}


}

Classe Personne :
package entities;

public class Personne {

/////// Attributs ///////
private String nom;
private String prenom;
private int sexe;
private int age;
private String nationalite;
private int num;

/////// Constructeurs ///////
public Personne() {
this("","",0,0,"",0);
}

public Personne (String nom, String prenom) {
this();
this.nom  = nom;
this.prenom =  prenom;
}

public Personne (String nom, String prenom, int sexe, int age, String nationalite, int num) {
this.nom = nom;
this.prenom = prenom;
this.sexe = sexe;
this.age = age;
this.nationalite = nationalite;
this.num = num;
}
/////// Accesseurs et Modificateurs ///////

/**
 * @return the nom
 */
public String getNom() {
return nom;
}

/**
 * @param nom the nom to set
 */
public void setNom(String nom) {
this.nom = nom;
}

/**
 * @return the prenom
 */
public String getPrenom() {
return prenom;
}

/**
 * @param prenom the prenom to set
 */
public void setPrenom(String prenom) {
this.prenom = prenom;
}

/**
 * @return the sexe
 */
public int getSexe() {
return sexe;
}

/**
 * @param sexe the sexe to set
 */
public void setSexe(int sexe) {
this.sexe = sexe;
}

/**
 * @return the age
 */
public int getAge() {
return age;
}

/**
 * @param age the age to set
 */
public void setAge(int age) {
this.age = age;
}

/**
 * @return the nationalite
 */
public String getNationalite() {
return nationalite;
}

/**
 * @param nationalite the nationalite to set
 */
public void setNationalite(String nationalite) {
this.nationalite = nationalite;
}

/**
 * @return the num
 */
public int getNum() {
return num;
}

/**
 * @param num the num to set
 */
public void setNum(int num) {
this.num = num;
}

/////// Méthodes ///////
}

Classe DialoguePersonne :
package gui;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import java.text.ParseException;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JTextField;

import entities.Personne;

@SuppressWarnings("serial")
public class DialogPersonne extends JDialog {
private JLabel label;
private JTextField field;
private JButton btn;
private Personne pers;
private NumberFormat nbForm;

public DialogPersonne() {
setSize(320, 480);
setTitle("Infos Personne");
setLayout(new FlowLayout());
setModal(true);

nbForm  = NumberFormat.getInstance();

label = new JLabel("Nom:");
add(label);
field = new JTextField();
field.setColumns(20);
field.setName("Nom");
add(field);

label = new JLabel("Prénom:");
add(label);
field = new JTextField();
field.setColumns(20);
field.setName("Prenom");
add(field);

label = new JLabel("Nationalité:");
add(label);
field = new JTextField();
field.setColumns(20);
add(field);

label = new JLabel("Age:");
add(label);
field = new JTextField();
field.setColumns(3);
field.setOpaque(false);
add(field);

btn = new JButton("Appliquer");
btn.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
appliquer();
}
});
add(btn);

pers = new Personne();
}

public void afficher() {
setVisible(true);
}

public void cacher() {
setVisible(false);
}

public void appliquer() {
// Ce code est évidemment illogique et il souligne bien le problème :
// Comment accéder aux valeurs des != JTextField !?
pers.setNom(field.getText());
pers.setPrenom(field.getText());
pers.setNationalite(field.getText());
try {
pers.setSexe(nbForm.parse(field.getText()).intValue());
pers.setAge(nbForm.parse(field.getText()).intValue());
pers.setNum(nbForm.parse(field.getText()).intValue());
} catch (ParseException e) {
System.err.println(e.getMessage());
}
}
}


Voilà.
C'est un peu long et j'espère qu'on prendra le temps de développer ces questions. Si quelque chose mérite selon vous précision, n'hésitez pas à demander. C'est le B.A.-BA de la prog graphique mais je voudrais comprendre ces quelques points pour continuer à avancer.

2 réponses

cs_jojolemariole Messages postés 519 Date d'inscription mercredi 21 mars 2007 Statut Membre Dernière intervention 19 décembre 2016 25
22 févr. 2011 à 17:52
Si je veux par exemple mettre à jour le texte du label, dans la première méthode je connais les points d'accès (les variables labelNom et labelPrenom) mais dans le second cas comment fait-on pour accéder à un contrôle puisque la variable label fait référence au dernier objet créé si je ne trompe pas ?


La première méthode est largement préférable et du coup ta méthode appliquer() serait enfantine à coder. Pour quelle raison es-tu parti sur la deuxième???

Maintenant j'arrive afficher et cacher une fenêtre mais ne peut-on pas libérer les ressources ? Il y a bien dispose mais si je l'utilise la fenêtre ne s'affiche qu'une seule fois. (oui c'est ma faute j'ai codé comme un pied mais c'est pas pour rien que je viens poser des questions ici)


Personnellement, j'utilise dispose pour fermer définitivement mes fenêtres et libérer les ressources. En général j'utilise plutôt setVisible(false / true) pour manipuler les fenêtres secondaires destinées à être ouvertes plusieurs fois. Ça ne prend pas une quantité de ressources démesurée selon moi.

Pour séparer la personne du dialogue "personne", je procède ainsi :

Je rajoute un attribut à la classe de contrôle pour pointer sur la classe de présentation (vue, dialogue, gui, comme tu veux).

En gros :

Personne personne = new Personne("jojo", "le mariole", 24);
DialoguePersonne dialoguePersonne = personne.getDialogue();
dialogue.setVisible(true);
...
dialogue.setVisible(false);


Et le constructeur de Personne ressemblerait à ça

public Personne(String prenom, String nom, int age) {

this.prenom = prenom;
this.nom = nom;
this.age = age;

/*
* comme tu le vois, la classe de dialogue peut avoir une reference sur la classe de controle, ca peut etre utile pour gerer les evenements utilisateur
*/

dialogue = new DialoguePersonne(this);

}
0
Pasokoniidesuka Messages postés 20 Date d'inscription mercredi 21 juillet 2010 Statut Membre Dernière intervention 17 janvier 2012
22 févr. 2011 à 21:40
Merci pour ta réponse.

Alors l'histoire de la seconde méthode lors de mes recherches sur Swing j'ai vu de petits exemples où on réutilise la même variable pour créer plusieurs objets. Je suis tout à fait d'accord avec toi et comme je l'avais dit c'est la méthode que l’emploierais aussi personnellement mais je suis curieux de savoir si il existe un moyen de contrôler ces objets de cette manière là. Malheureusement ce point n'a pas été soulevé donc je suis curieux de savoir. Je pense que c'est possible et ça me semble intéressant mais je n'ai rien trouvé dessus.

Pour la seconde partie je vois que tu sembles utiliser le pattern MVC. J'ai personnellement un peu de mal à le digérer mais à terme c'est sur que je finirais par l'adopter (le jour où je le comprendrais bien). Dans ma façon de faire je ne crois pas qu'il y ait d'équivalent au contrôleur.
0
Rejoignez-nous