Plusieurs fenetres [java]

Résolu/Fermé
honrisse Messages postés 22 Date d'inscription samedi 25 juillet 2009 Statut Membre Dernière intervention 19 mars 2011 - 16 avril 2010 à 09:12
honrisse Messages postés 22 Date d'inscription samedi 25 juillet 2009 Statut Membre Dernière intervention 19 mars 2011 - 24 avril 2010 à 08:45
Bonjour,

Je débute sous Java et j'aimerais avoir : une première fenetre où l'utilisateur saisi le nombre de joueurs et valide.
La première fenetre se ferme et une deuxième fenetre s'affiche où il doit rentrer le nom et d'autres caracteristiques du premier joueur. Il valide et s'affiche autant que nécessaire cette fenetre pour rentrer les noms des différents joueurs spécifiés.

Je ne sais utiliser que les Frame, Panel et companie.

Comment faire s'afficher un nombre spécifié de fenetres qui s'ouvrent/ ferment au fur et à mesure?
Une idée?
Merci.


A voir également:

4 réponses

kij_82 Messages postés 4089 Date d'inscription jeudi 7 avril 2005 Statut Contributeur Dernière intervention 30 septembre 2013 857
16 avril 2010 à 10:20
Bonjour,

Ton problème ne semble pas du à la non connaissance des Frames, Panel, etc (ou du moins ce n'est pas le premier aspect) mais surtout à un manque de recul pour concevoir correctement ton application.

Pour ce que tu souhaites, tu devras mettre en place une classe principale chargée:
- de lancer une première fenêtre comprenant les champs pour demander le nombre de joueur ainsi qu'un bouton de validation. Il faudra bien entendu récupérer ce nombre de joueur et le retourner (plus ou moins) à ta classe principale.
- puis de boucler sur le nombre de joueur saisie (boucle for de 0 à NbJoueur). Au sein de cette boucle, pour chaque occurrence, tu lance une fenêtre chargée de récupérer les informations d'un joueur (champs de saisie, etc.) Pour stocker ces informations, le mieux sera de faire une classe Joueur, chargée de représenter un joueur et ayant les propriétés nécessaire pour stocker chaque information relative à un joueur. Ta classe principale comprendra donc elle, une propriété de type tableau au sein de laquelle tu stockera les objets Joueur ainsi créé un à un.

A partir de cette conception, tu peux alors voir plus ou moins la structure de tes classses:

- 1 classe Main
- 1 classe graphique de type fenêtre pour la récupération du nombre de joueurs
- 1 classe graphique de type fenêtre pour récupérer les informations d'un joueur (sera instanciée ou lancée plusieurs fois)
- 1 classe de type "bean" pour stocker les informations d'un joueur

Ceci te permet d'avoir une vue globale de ce que tu as à créer, tu peux bien entendu étoffer avec de nouvelle classe Java si tu t'aperçois en cours de route que tu as certains autre besoin qui change quelque peu la conception.

Pour ce qui est ensuite de la partie technique, tu n'as qu'à tout simplement apprendre avec des tutoriaux que tu trouvera sur ce site, ou via Google et d'autres sites, il n'y a pas de mystères, il faut apprendre et mettre en pratique au besoin pour cerner le concepte des applications graphiques et ainsi pouvoir par la suite faire ce dont tu as envie dans ton projet.

Si à l'avenir tu as fais du code ou conçu quelque chose mais que tu bloque à un endroit, tu pourras toujours venir poser tes questions (avec les détails / codes existants) pour que l'on puisse t'aider.

Bonne chance dans ton apprentissage.
0
honrisse Messages postés 22 Date d'inscription samedi 25 juillet 2009 Statut Membre Dernière intervention 19 mars 2011 11
Modifié par honrisse le 17/04/2010 à 01:23
Merci de votre réponse.

J'ai une classe Controleur, une classe FenetreInit et une autre FenetreInfoJoueur.
J'arrive à afficher la première fenetre qui sert à rentrer le nombres de joueurs et à récupérer le nombre de joueur. Quand on valide, une deuxième fenetre s'affiche sauf que si la personne ferme la première fenetre les deux fenetres se ferment.
Comment y remédier?

J'aimerais afficher une info quand l'utilisateur rentre une donnée erronée : pour l'instant j'affiche un texte dans la fenetre même mais j'aimerais qu'une fenetre d'avertissement s'ouvre. Pb comment faire pour que la fenetre se ferme quand il clique sur OK mais que les autres fenetres restent ouvertes?

Ma solution pour ouvrir nb fenetres d'info pour nb joueurs ne semblent pas optimales. J'ai une variable qui stocke le nb de joueur dans le controleur et une autre qui stocke le joueur courant. J'incrémente le courant dans le constructeur de la fenetre joueur et j'ouvre une nouvelle fenetre dans le actionListener du bouton OK du joueur. Est ce une bonne idée?

Notez que j'ai d'autres classes qui correspondent à l'application du jeu et que je n'ai gardé que le graphique.

EDIT:
j'ai rajouté une classe fenetreError qui est appelée par le controleur quand il récupère des valeurs incorrectes. Pour fermer une fenetre j'utilise setVisible(false). Ca marche mais est ce qu'il y un autre moyen?
Par contre si l'utilisateur ferme la fenetre d'erreur au lieu de cliquer sur OK toutes les fenetres se ferment. Comment faire pour ne fermer que la fenetre d'erreur?
J'aimerais aussi afficher une barre horizontale pour saisir le nombre de joueurs au lieu d'un JTextField, ça me permet d'etre sur que l'utilisateur rentre une valeur correcte sans faire des tests.
Quelle classe utiliser?
Merci

Voila le code :

import java.lang.String;

public class ControleurMonde {

//Attributs :
private static ControleurMonde instanceControleur = null;
protected int nbJoueur1;
protected int nbJoueur2;
protected int nbJoueur3;
protected int courantJoueur1;
public boolean initOK;


//Constructeur :
public ControleurMonde ()
{
nbJoueur1 = 0;
nbJoueur2 = 0;
nbJoueur3 = 0;
courantJoueur1 = 0;
initOK = false;
}

public static ControleurMonde getInstance(){
if(instanceControleur == null) {
instanceControleur = new ControleurMonde();
}
return instanceControleur;
}

//Methodes :

public void jouer(){
FenetreInit fInit = new FenetreInit();
}

public void recupererInfoInit(FenetreInit f){
if(f.getNbJoueur1() == -1 || f.getNbJoueur2() == -1 || f.getNbJoueur3() == -1){
f.setStatut("Erreur ! Veuillez resaisir");
}else{
nbJoueur1 = f.getNbJoueur1();
nbJoueur2 = f.getNbJoueur2();
nbJoueur3 = f.getNbJoueur3();
System.out.println("nbJoueur1 = "+nbJoueur1+"\nnbJoueur2 = "+nbJoueur2+"\nnbJoueur3 = "+nbJoueur3+"\n");
initOK = true;
}
}

public void recupererInfoJoueur(FenetreInfoJoueur f){
if(f.getForceJoueur() == -1 ){
f.setStatut("Erreur ! Veuillez resaisir");
}else{

}
}

public static void main(String[] args) {
// TODO Auto-generated method stub
ControleurMonde.getInstance().jouer();
}

}






import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class FenetreInit extends JFrame{

private static final long serialVersionUID = 1L;
//Attributs :
private JTextField nbJoueurs1;
private JTextField nbJoueurs2;
private JTextField nbJoueurs3;
private Container c;
private FenetreInit instance;
private JLabel statut;



//Constructeur :
public FenetreInit()
{
super("Initialisation du jeu");
instance = this;

initComposant();
this.setVisible(true);
this.pack();
}



//Methodes :
private void initComposant(){
c = getContentPane();
setDefaultCloseOperation(EXIT_ON_CLOSE);

JPanel registrationPanel = new JPanel();
registrationPanel.setPreferredSize(new Dimension(400,300));
registrationPanel.setLayout(new GridLayout(5,2));

registrationPanel.add(new JLabel("Nombre de joueur type1 : "));
nbJoueurs1 = new JTextField("0");
registrationPanel.add(nbJoueurs1);

registrationPanel.add(new JLabel("Nombre de joueur type2 : "));
nbJoueurs2 = new JTextField("0");
registrationPanel.add(nbJoueurs2);

registrationPanel.add(new JLabel("Nombre de joueur type3 : "));
nbJoueurs3 = new JTextField("0");
registrationPanel.add(nbJoueurs3);

registrationPanel.add(new JLabel("Statut : "));
registrationPanel.add( statut = new JLabel("Rentrez les infos et validez !"));


JButton okButton = new JButton("Ok");
registrationPanel.add(okButton);
okButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
ControleurMonde.getInstance().recupererInfoInit(instance);
if(ControleurMonde.getInstance().initOK){
FenetreInfoJoueur fJoueur = new FenetreInfoJoueur(ControleurMonde.getInstance().courantJoueur1+1);
}
}
});

JButton resetButton = new JButton("Reset");
resetButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
nbJoueurs1.setText("0");
nbJoueurs2.setText("0");
nbJoueurs3.setText("0");
}
});
registrationPanel.add(resetButton);

c.add(registrationPanel);
}


public int getNbJoueur1(){
String s = nbJoueurs1.getText();

try{
int nb = Integer.parseInt(s);
return nb;
}catch(java.lang.NumberFormatException e){
return -1;
}
}

public int getNbJoueur2(){
String s = nbJoueurs2.getText();

try{
int nb = Integer.parseInt(s);
return nb;
}catch(java.lang.NumberFormatException e){
return -1;
}
}

public int getNbJoueur3(){
String s = nbJoueurs3.getText();

try{
int nb = Integer.parseInt(s);
return nb;
}catch(java.lang.NumberFormatException e){
return -1;
}
}


public void setStatut(String s){
statut.setText(s);
}


public static void main(String[] args) {
// TODO Auto-generated method stub

FenetreInit f = new FenetreInit();
}

}






import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class FenetreInfoJoueur extends JFrame{

private static final long serialVersionUID = 1L;
//Attributs :
private JTextField nom;
private JTextField force;
private Container c;
private FenetreInfoJoueur instance;
private JLabel statut;



//Constructeur :
public FenetreInfoJoueur(int nb)
{
super("Initialisation des paramètres du joueur numéro : "+String.valueOf(nb));
instance = this;
ControleurMonde.getInstance().courantJoueur1++;
initComposant();
this.setVisible(true);
this.pack();
}



//Methodes :
private void initComposant(){
c = getContentPane();
setDefaultCloseOperation(EXIT_ON_CLOSE);

JPanel registrationPanel = new JPanel();
registrationPanel.setPreferredSize(new Dimension(500,500));
registrationPanel.setLayout(new GridLayout(4,2));

registrationPanel.add(new JLabel("Nom du joueur : ")); //JLabel = ajouter champ texte
nom = new JTextField("Victor");
registrationPanel.add(nom);

registrationPanel.add(new JLabel("Force du joueur : "));
force = new JTextField("0");
registrationPanel.add(force);


registrationPanel.add(new JLabel("Statut : "));
registrationPanel.add( statut = new JLabel("Rentrez les infos et validez !"));


JButton okButton = new JButton("Ok");
registrationPanel.add(okButton);
okButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
ControleurMonde.getInstance().recupererInfoJoueur(instance);
if(ControleurMonde.getInstance().courantJoueur1 != ControleurMonde.getInstance().nbJoueur1+1){
FenetreInfoJoueur f = new FenetreInfoJoueur(ControleurMonde.getInstance().courantJoueur1++);
}

}
});

JButton resetButton = new JButton("Reset");
resetButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
nom.setText("");
force.setText("0");
}
});
registrationPanel.add(resetButton);

c.add(registrationPanel);
}


public String getJoueur(){
return nom.getText();
}


public int getForceJoueur(){
String s = force.getText();

try{
int nb = Integer.parseInt(s);
return nb;
}catch(java.lang.NumberFormatException e){
return -1;
}
}


public void setStatut(String s){
statut.setText(s);
}


public static void main(String[] args) {
// TODO Auto-generated method stub

FenetreInfoJoueur f = new FenetreInfoJoueur(1);
}

}
0
kij_82 Messages postés 4089 Date d'inscription jeudi 7 avril 2005 Statut Contributeur Dernière intervention 30 septembre 2013 857
19 avril 2010 à 10:49
Re,

J'ai parcouru ton code rapidement, mais une première chose : tu semble avoir voulu faire un singleton sur ta classe 1 (celle du controleur)
Pourquoi pas, mais c'est "mal fait", il manque une synchronisation sur un objet pour être sur qu'une même instance de ta classe ne soit pas créer en deux exemplaire au même moment.

Enfin, vu que tu ne travaille pas avec les threads, ça ne dérange en rien, c'est surtout d'un point de vue programmation propre.

Par contre, autant je veux bien que tu aie des propriétés de classes "instance" pour ton controleur que tu instancie comme un singleton (via getInstance), autant pour les autres classes, c'est strictement inutile.

Supprime les propriétés 'instance' des autres classes, et tout ce qui y fait référence, ça ne te servira à rien.

Pour répondre à ta question du "pourquoi toutes mes fenêtres se ferment lorsque je ferme la fenêtre d'erreur", je n'ai pas encore trop regardé, mais certainement qu'il y a quelque chose de mal fait dans tes codes.
Normalement, tu dois avoir une classe principales (que tu lance via un Main), et c'est elle qui possède une propriété pour chaque "fenêtre" que tu es susceptible de lancer. Par exemple, une propriété pour ta fenêtre d'erreur, avec une méthode qui permet de créer / initialiser cette fenêtre, une autre pour la fermer depuis ton programme principal (sous certaines conditions). Idem pour les autres types de fenêtre.
Ensuite, pour chaque fenêtre, à toi d'y attacher des écouteurs d'évènements au cas où l'utilisateur ferme ces fenêtres, pour que le programme principale controle ce qui a été renseigné, et ce qui est manquant, de sorte à afficher la fenêtre d'erreur et éventuellement relancé les fenêtres des saisies, etc.

J'ai un problème avec mon Eclipse sur ma machine actuellement, donc je ne peux pas programme et donc pas regarder / te faire des exemples. Si je résouds mon truc je tacherai de te montrer un code un peu plus "ordonné".

0
honrisse Messages postés 22 Date d'inscription samedi 25 juillet 2009 Statut Membre Dernière intervention 19 mars 2011 11
Modifié par honrisse le 24/04/2010 à 08:46
Je répond un peu tard, je ne pensais pas avoir de nouvelle réponse.
J'ai quasi terminé mon projet.

Pour ce qui était du problème de fermeture des fenetres, c'est simple il suffit tout simplement de mettre
setDefaultCloseOperation(EXIT_ON_CLOSE); ou
setDefaultCloseOperation(HIDE_ON_CLOSE);
suivant les cas.

Ma classe Controle est en singleton car il ne doit y avoir qu'un controle et ca me permet d'éviter de le passer en paramètres dans les classes des autres packages.
J'utilise un thread pour lancer le jeu mais à l'intérieur du run() je met des synchronized(this) je ne sais pas si c'est correcte.

Par contre c'est vrai que le code n'est pas propre même s'il n'y a pas de "mauvais code" que les professionnels détestent je pense.
0