Graphics JPanel plusieurs cercles
Fermé
Étienne9
Messages postés
1022
Date d'inscription
mardi 1 mars 2011
Statut
Membre
Dernière intervention
10 mai 2015
-
Modifié par Étienne9 le 18/06/2013 à 10:01
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 - 21 juin 2013 à 15:35
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 - 21 juin 2013 à 15:35
A voir également:
- Graphics JPanel plusieurs cercles
- Intel hd graphics family - Forum Carte graphique
- Intel hd graphics 4600 - Forum Carte graphique
- Intel(R) HD Graphics 4600 ✓ - Forum Audio
- Intel hd graphics 4000 - Forum Jeux vidéo
- Intel uhd graphics avis jeux - Forum Matériel & Système
9 réponses
Étienne9
Messages postés
1022
Date d'inscription
mardi 1 mars 2011
Statut
Membre
Dernière intervention
10 mai 2015
49
18 juin 2013 à 13:45
18 juin 2013 à 13:45
Bonjour à tous,
Je me suis rapproché encore plus de la vérité mais j'ai un léger soucis technique de réglage, je n'arrive pas à régler...
Quelqu'un peut m'aider s'il vous plaît ?
Je me suis rapproché encore plus de la vérité mais j'ai un léger soucis technique de réglage, je n'arrive pas à régler...
import java.awt.Color; import java.awt.Graphics; import java.lang.Math.*; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import java.lang.String; public class Round extends JPanel { private int nb; private int taille; private int CentreCercle; private Couple tab[][]; private int ecartEntreDeuxCercles; public void refresh() { repaint(); } public void initAB(Couple tab[][]) { for (int i=0;i<tab.length;i++) { for (int j=0;j<tab[i].length;j++) { tab[i][j] = new Couple("A " + i + " " + j,"B " + i + " " + j); } } } public void setA(int a, int b, String s) { tab[a][b].setA(s); } public void setB(int a, int b, String s) { tab[a][b].setB(s); } public int getTaille() { return taille; } public Round(int taille,int nbCercles) { super(true); setSize(taille,taille); this.taille = taille; this.nb = nbCercles; tab = new Couple[4][nbCercles]; } public void paint(Graphics g) { super.paint(g); int gris=200; // couleur gris le plus loin du centre qui diminuera int ecartCouleur=20; // entre deux couleurs int marge=1; // marge autour du plus grand cercle int hautgauche=marge; setBackground(new Color(225,225,225)); initAB(tab); this.CentreCercle = (int)(taille/2); if (nb >= 1) { this.ecartEntreDeuxCercles = (int)(((taille-2*marge)/nb)/2); int nbEc=2; for (int i=nb;i>=1;i--) { g.setColor(new Color(gris,gris,gris)); g.fillOval(hautgauche,hautgauche,taille-2*marge-((nbEc-2)*ecartEntreDeuxCercles),taille-2*marge-((nbEc-2)*ecartEntreDeuxCercles)); nbEc=nbEc+2; hautgauche = hautgauche+ecartEntreDeuxCercles; gris = gris - ecartCouleur; } } } }
Quelqu'un peut m'aider s'il vous plaît ?
KX
Messages postés
16733
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
31 janvier 2024
3 014
18 juin 2013 à 18:38
18 juin 2013 à 18:38
Et c'est quoi le "léger soucis technique de réglage" ?
Si c'est la cible qui n'est pas tout à fait dans le cadre, c'est un problème dans ta classe de Test, donc ce n'est pas très grave...
PS. N'oublie pas d'arrêter le programme lorsque tu fermes ta fenêtre, sinon il ne s'arrêtera jamais...
Si c'est la cible qui n'est pas tout à fait dans le cadre, c'est un problème dans ta classe de Test, donc ce n'est pas très grave...
jframe.setSize(affichage.getTaille()+18,affichage.getTaille()+40);
PS. N'oublie pas d'arrêter le programme lorsque tu fermes ta fenêtre, sinon il ne s'arrêtera jamais...
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Étienne9
Messages postés
1022
Date d'inscription
mardi 1 mars 2011
Statut
Membre
Dernière intervention
10 mai 2015
49
18 juin 2013 à 22:51
18 juin 2013 à 22:51
Bonsoir,
Merci beaucoup KX.
Par contre, comment faire de façon simple, des diagonales mais uniquement dans mes cercles ?
Merci beaucoup KX.
Par contre, comment faire de façon simple, des diagonales mais uniquement dans mes cercles ?
Étienne9
Messages postés
1022
Date d'inscription
mardi 1 mars 2011
Statut
Membre
Dernière intervention
10 mai 2015
49
Modifié par Étienne9 le 18/06/2013 à 23:37
Modifié par Étienne9 le 18/06/2013 à 23:37
Re,
J'ai tenté de faire l'affichage mais c'est vrai que tab[0][0] c'est la même chose que tab[1][0] et c'est pareil que tab[2][0] qui est pareil aussi que tab[3][0].
J'ai considéré pour régler le problème que seul [0][0] peut amener au centre pour éviter les redondances de données.
J'ai écris alors la suite pour le drawString mais j'ai plein d'erreurs, des EventQueue, Event DispatchThread, JComponent paint Children etc....
Voilà mon code :
Avez-vous une idée de là où ça peut venir s'il vous plaît ?
Le for(int i=0;i<4;i++) correpond à écrire les données dans chaque quartier.
PS: Le deuxième drawString il aurait fallu que je mette le JTextField à la place de mettre en chaîne de caractère mais j'aurai bien aimé savoir comment faire.
Merci beaucoup d'avance :)
J'ai tenté de faire l'affichage mais c'est vrai que tab[0][0] c'est la même chose que tab[1][0] et c'est pareil que tab[2][0] qui est pareil aussi que tab[3][0].
J'ai considéré pour régler le problème que seul [0][0] peut amener au centre pour éviter les redondances de données.
J'ai écris alors la suite pour le drawString mais j'ai plein d'erreurs, des EventQueue, Event DispatchThread, JComponent paint Children etc....
Voilà mon code :
int x; int y; int pasX; int pasY; int debut; for (int i=0;i<4;i++) { x=CentreCercle; y=CentreCercle; pasX=0; pasY=0; debut=1; if (i == 0) { debut=0; pasY=-ecartEntreDeuxCercles; } else { if (i == 1) { pasX=ecartEntreDeuxCercles; x = x+pasX; } else { if (i == 2) { pasY=ecartEntreDeuxCercles; y=y+pasY; } else { pasX=-ecartEntreDeuxCercles; x=x+pasX; } } } while (debut <= nb) { g.drawString(tab[i][debut].getA(),x,y); g.drawString(tab[i][debut].getB(),x,y+10); x = x+pasX; y = y+paxY; debut=debut+1; } }
Avez-vous une idée de là où ça peut venir s'il vous plaît ?
Le for(int i=0;i<4;i++) correpond à écrire les données dans chaque quartier.
PS: Le deuxième drawString il aurait fallu que je mette le JTextField à la place de mettre en chaîne de caractère mais j'aurai bien aimé savoir comment faire.
Merci beaucoup d'avance :)
Étienne9
Messages postés
1022
Date d'inscription
mardi 1 mars 2011
Statut
Membre
Dernière intervention
10 mai 2015
49
19 juin 2013 à 08:28
19 juin 2013 à 08:28
Bonjour,
J'ai oublié de vous demander aussi : au début je voulais faire une fonction mais le soucis c'est que je n'ai pas Graphics g. Je peux le passer en paramètre ou pas ?
J'ai oublié de vous demander aussi : au début je voulais faire une fonction mais le soucis c'est que je n'ai pas Graphics g. Je peux le passer en paramètre ou pas ?
KX
Messages postés
16733
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
31 janvier 2024
3 014
19 juin 2013 à 18:51
19 juin 2013 à 18:51
Tu n'as pas précisé où tu mettais ce code, alors logiquement je l'ai mis dans paint.
Dans ce cas effectivement, tu peux faire une méthode qui prend en paramètre g, c'est même beaucoup mieux ainsi.
Pour toutes les erreurs que tu as à l'exécution, ce n'en est qu'une en fait, mais comme Swing utilise beaucoup de méthodes imbriquées ça fait une trace très longues, mais seules les premières lignes sont intéressantes à regarder pour déboguer :
En fait l'erreur est dans getB(), car la méthode getName() renvoie null, tu as surement confondu avec la méthode getText().
Après tu as encore une erreur :
Là le problème c'est ta boucle while, car tu fais un test <=nb alors que ce devrait être <nb.
Remarque : ici une boucle for serait bien plus jolie.
À partir de là ça fonctionne, mais je ne suis pas sûr que le texte soit au bon endroit, tu régleras x et y si nécessaire selon ce que tu veux...
Pour les diagonales, c'est assez simple, il suffit de tracer deux lignes droites qui se croisent.
Dans ce cas effectivement, tu peux faire une méthode qui prend en paramètre g, c'est même beaucoup mieux ainsi.
Pour toutes les erreurs que tu as à l'exécution, ce n'en est qu'une en fait, mais comme Swing utilise beaucoup de méthodes imbriquées ça fait une trace très longues, mais seules les premières lignes sont intéressantes à regarder pour déboguer :
java.lang.NullPointerException: String is null at g.drawString(tab[i][debut].getB(),x,y+10);
En fait l'erreur est dans getB(), car la méthode getName() renvoie null, tu as surement confondu avec la méthode getText().
public String getB() { return this.B.getText();//.getName(); }
Après tu as encore une erreur :
java.lang.ArrayIndexOutOfBoundsException: 4 at g.drawString(tab[i][debut].getA(),x,y);
Là le problème c'est ta boucle while, car tu fais un test <=nb alors que ce devrait être <nb.
Remarque : ici une boucle for serait bien plus jolie.
for ( ; debut<nb; debut++, x+=pasX, y+=pasY) { g.drawString(tab[i][debut].getA(),x,y); g.drawString(tab[i][debut].getB(),x,y+10); }
À partir de là ça fonctionne, mais je ne suis pas sûr que le texte soit au bon endroit, tu régleras x et y si nécessaire selon ce que tu veux...
Pour les diagonales, c'est assez simple, il suffit de tracer deux lignes droites qui se croisent.
private void drawLines(Graphics g) { int rayon = taille/2; int coord = (int) (rayon*Math.sqrt(2)/2); g.setColor(Color.BLACK); g.drawLine(rayon-coord,rayon-coord,rayon+coord,rayon+coord); g.drawLine(rayon+coord,rayon-coord,rayon-coord,rayon+coord); } @Override public void paint(Graphics g) { super.paint(g); drawOvals(g); drawLines(g); drawStrings(g); }
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Étienne9
Messages postés
1022
Date d'inscription
mardi 1 mars 2011
Statut
Membre
Dernière intervention
10 mai 2015
49
19 juin 2013 à 18:26
19 juin 2013 à 18:26
Bonjour,
J'ai réussi à avancer mais j'ai des problèmes avec les set (pour modifier les valeurs de mon affichage et pour les JTextField qui se placent au bon endroit mais ils sont en double et les doublons sont mal placés, ils se mettent tous en haut !
Je ne vois pas où est le problème... Quelqu'un peut m'aider s'il vous plaît ?
J'ai réussi à avancer mais j'ai des problèmes avec les set (pour modifier les valeurs de mon affichage et pour les JTextField qui se placent au bon endroit mais ils sont en double et les doublons sont mal placés, ils se mettent tous en haut !
import java.awt.Color; import java.awt.Graphics; import java.lang.Math.*; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import java.lang.String; public class Round extends JPanel { private int nb; private int taille; private int marge=20; private int ecartCouleur=20; private Couple tab[][]; public void refresh() { repaint(); } public void initAB(Couple tab[][]) { for (int i=0;i<tab.length;i++) { for (int j=0;j<tab[i].length;j++) { tab[i][j] = new Couple("A" + i + j,"B" + i + j); } } } public void setA(int a, int b, String s) { tab[a][b].setA(s); } public void setB(int a, int b, String s) { tab[a][b].setB(s); } public Couple[][] getTab() { return tab; } public int getTaille() { return taille; } public Round(int taille,int nbCercles) { super(true); setSize(taille,taille); this.taille = taille; this.nb = nbCercles; tab = new Couple[4][nbCercles]; } public Round(int taille,int nbCercles,Couple tab[][]) { super(true); setSize(taille,taille); this.taille = taille; this.nb = nbCercles; this.tab = tab; } public void paint(Graphics g) { super.paint(g); int rayonGrandCercle; int ecartEntreDeuxCercles; int CentreCercle; int gris=200; // couleur gris le plus loin du centre qui diminuera int hautgauche=marge; setBackground(new Color(225,225,225)); initAB(tab); CentreCercle = (int)(taille/2); rayonGrandCercle = (int) ((taille-2*marge)/2); if (nb >= 1) { ecartEntreDeuxCercles = (int)(((taille-2*marge)/nb)/2); int nbEc=2; for (int i=nb;i>=1;i--) { g.setColor(new Color(gris,gris,gris)); g.fillOval(hautgauche,hautgauche,taille-2*marge-((nbEc-2)*ecartEntreDeuxCercles),taille-2*marge-((nbEc-2)*ecartEntreDeuxCercles)); nbEc=nbEc+2; hautgauche = hautgauche+ecartEntreDeuxCercles; gris = gris - ecartCouleur; } g.setColor(new Color(255,255,255)); int x; int y; int pasX; int pasY; int debut; for (int i=0;i<4;i++) { x=CentreCercle-5; y=CentreCercle+5; pasX=0; pasY=0; debut=1; if (i == 0) { debut=0; pasY=(int) -ecartEntreDeuxCercles-(99/100)*ecartEntreDeuxCercles; y=y-16; } else { if (i == 1) { pasX=(int) ecartEntreDeuxCercles +(99/100)*ecartEntreDeuxCercles+1; x = x+pasX+16; } else { if (i == 2) { pasY=(int) ecartEntreDeuxCercles+(99/100)*ecartEntreDeuxCercles+1; y=y+pasY+16; } else { pasX=(int)-ecartEntreDeuxCercles-(99/100)*ecartEntreDeuxCercles+1; x=x+pasX-30; } } } for (int j=debut;j<tab[i].length;j++) { g.drawString(tab[i][j].getA(),x,y); tab[i][j].getB().setBounds(x-13,y-35,30,23); this.add(tab[i][j].getB()); x = x+pasX; y = y+pasY; } } } } }
Je ne vois pas où est le problème... Quelqu'un peut m'aider s'il vous plaît ?
KX
Messages postés
16733
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
31 janvier 2024
3 014
19 juin 2013 à 19:03
19 juin 2013 à 19:03
Pour le problème de doublons, c'est parce que ton initAB(tab); ne devrait être fait qu'une seule fois, or tu l'appelles dans paint, donc à chaque fois que paint est appelé tu recréés des Couple et donc des JTextField qui sont ajoutés à la fenêtre, alors les premiers seront bien placés, mais faute de place, les seconds seront mis les uns à la suite des autres dans la grille.
Tu peux "t'amuser" à redimensionner la taille de la fenêtre pour provoquer des paint supplémentaires, tu verras les nouveaux JTextField se rajouter bien gentiment alignés sur la grille.
Ce qu'il faut faire ici c'est déplacer l'appel de initAB afin qu'il ne soit fait qu'une seule fois.
Tu peux "t'amuser" à redimensionner la taille de la fenêtre pour provoquer des paint supplémentaires, tu verras les nouveaux JTextField se rajouter bien gentiment alignés sur la grille.
Ce qu'il faut faire ici c'est déplacer l'appel de initAB afin qu'il ne soit fait qu'une seule fois.
Étienne9
Messages postés
1022
Date d'inscription
mardi 1 mars 2011
Statut
Membre
Dernière intervention
10 mai 2015
49
19 juin 2013 à 20:51
19 juin 2013 à 20:51
Bonsoir KX,
Merci beaucoup.
Par contre j'ai trois problèmes qui persistent. Peux-tu m'aider s'il te plaît ?
Le premier problème c'est que je ne vois uniquement que 2 morceaux de JTextField et les autres sont invisibles, par contre si je redimensionne la taille de ma fenêtre, ils apparaissent tous tout à coup correctement. Je ne sais pas à quoi c'est dû.
Le deuxième problème c'est que je ne peux pas modifier ce qui est écrit dans l'Affichage car ça crash...
Le troisième problème c'est que j'ai une diagonale qui n'est pas bien placé ou alors c'est mon cercle le problème....
Je te parlais tout à l'heure de deux morceaux de JTextField, voilà ce que ça donne en vrai.
Capture écran ici : http://hpics.li/353c123
Finalement les drawlines j'ai mis à la suite, pour 4 lignes je ne me suis pas amusé à faire une fonction.
Voilà les codes actuels :
Merci beaucoup encore KX :)
Bonne soirée ;)
Merci beaucoup.
Par contre j'ai trois problèmes qui persistent. Peux-tu m'aider s'il te plaît ?
Le premier problème c'est que je ne vois uniquement que 2 morceaux de JTextField et les autres sont invisibles, par contre si je redimensionne la taille de ma fenêtre, ils apparaissent tous tout à coup correctement. Je ne sais pas à quoi c'est dû.
Le deuxième problème c'est que je ne peux pas modifier ce qui est écrit dans l'Affichage car ça crash...
Le troisième problème c'est que j'ai une diagonale qui n'est pas bien placé ou alors c'est mon cercle le problème....
Je te parlais tout à l'heure de deux morceaux de JTextField, voilà ce que ça donne en vrai.
Capture écran ici : http://hpics.li/353c123
Finalement les drawlines j'ai mis à la suite, pour 4 lignes je ne me suis pas amusé à faire une fonction.
Voilà les codes actuels :
import javax.swing.JTextField; import java.lang.String; public class Couple { private String A; private JTextField B; public Couple(String a, String b) { this.A = a; this.B = new JTextField(b); this.B.setText(b); } public void setA(String a) { this.A = a; } public void setB(String b) { this.B.setName(b); this.B.setText(b); } public String getA() { return A; } public JTextField getB() { return B; } }
import java.awt.Color; import java.awt.Graphics; import java.lang.Math.*; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import java.lang.String; import java.lang.Math; public class Round extends JPanel { private boolean dejaInitialise; private int nb; private int taille; private int marge=20; private int ecartCouleur=20; private Color fond = new Color(225,225,225); private Couple tab[][]; public void refresh() { repaint(); } public void initAB(Couple tab[][]) { for (int i=0;i<tab.length;i++) { for (int j=0;j<tab[i].length;j++) { tab[i][j] = new Couple("A" + i + j,"B" + i + j); } } } public void setA(int a, int b, String s) { tab[a][b].setA(s); } public void setB(int a, int b, String s) { tab[a][b].setB(s); } public Couple[][] getTab() { return tab; } public int getTaille() { return taille; } public Round(int taille,int nbCercles) { super(true); setSize(taille,taille); this.taille = taille; this.nb = nbCercles; tab = new Couple[4][nbCercles]; this.dejaInitialise = false; } public Round(int taille,int nbCercles,Couple tab[][]) { super(true); setSize(taille,taille); this.taille = taille; this.nb = nbCercles; this.tab = tab; this.dejaInitialise = false; } public void paint(Graphics g) { super.paint(g); if (!dejaInitialise) { initAB(tab); this.dejaInitialise = true; } int rayonGrandCercle; int ecartEntreDeuxCercles; int centreCercle; int gris=200; // couleur gris le plus loin du centre qui diminuera int hautgauche=marge; setBackground(fond); centreCercle = (int)(taille/2); rayonGrandCercle = (int) ((taille-2*marge)/2); if (nb >= 1) { // on dessine les cercles les uns dans les autres ecartEntreDeuxCercles = (int)(((taille-2*marge)/nb)/2); int nbEc=2; for (int i=nb;i>=1;i--) { g.setColor(new Color(gris,gris,gris)); g.fillOval(hautgauche,hautgauche,taille-2*marge-((nbEc-2)*ecartEntreDeuxCercles),taille-2*marge-((nbEc-2)*ecartEntreDeuxCercles)); nbEc=nbEc+2; hautgauche = hautgauche+ecartEntreDeuxCercles; gris = gris - ecartCouleur; } g.setColor(new Color(255,255,255)); // on écrit les données int x; int y; int pasX; int pasY; int debut; for (int i=0;i<4;i++) { x=centreCercle-5; y=centreCercle+5; pasX=0; pasY=0; debut=1; if (i == 0) { debut=0; pasY=(int) -ecartEntreDeuxCercles-(99/100)*ecartEntreDeuxCercles; y=y-16; } else { if (i == 1) { pasX=(int) ecartEntreDeuxCercles +(99/100)*ecartEntreDeuxCercles+1; x = x+pasX+16; } else { if (i == 2) { pasY=(int) ecartEntreDeuxCercles+(99/100)*ecartEntreDeuxCercles+1; y=y+pasY+16; } else { pasX=(int)-ecartEntreDeuxCercles-(99/100)*ecartEntreDeuxCercles+1; x=x+pasX-30; } } } for (int j=debut;j<tab[i].length;j++) { g.drawString(tab[i][j].getA(),x,y); tab[i][j].getB().setBounds(x-13,y-35,30,23); this.add(tab[i][j].getB()); x = x+pasX; y = y+pasY; } } // on dessine les diagonales int coord = (int) (rayonGrandCercle*Math.sqrt(2)/2); g.setColor(Color.BLACK); g.drawLine(rayonGrandCercle-coord,rayonGrandCercle-coord,rayonGrandCercle+coord,rayonGrandCercle+coord); g.drawLine(rayonGrandCercle+coord,rayonGrandCercle-coord,rayonGrandCercle-coord,rayonGrandCercle+coord); } } }
Merci beaucoup encore KX :)
Bonne soirée ;)
KX
Messages postés
16733
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
31 janvier 2024
3 014
19 juin 2013 à 21:47
19 juin 2013 à 21:47
"Finalement les drawlines j'ai mis à la suite, pour 4 lignes je ne me suis pas amusé à faire une fonction."
Mais tu aurais pu le faire pour les 2 autres (drawOvals et drawStrings) qui ont bien plus de lignes !
Pour ton histoire de initAB, pourquoi ne pas avoir directement rempli ton tableau lors de sa création, par exemple au lieu de faire this.dejaInitialise = false; dans Round() tu pourrais directement appeler initAB, et ainsi ne pas avoir à l'utiliser dans paint.
Il faut toujours limiter au maximum les opérations dans paint, par exemple tous tes calculs centreCercle, rayonGrandCercle, etc. pourraient être fais à la construction, ce sont des valeurs qui ne changeront jamais de toute façon... de même que des propriétés comme setBackground qui ne sont à faire qu'une seule fois, pas à chaque paint !
Au niveau de ton problème d'affichage moi je ne l'ai pas chez moi, ça s'affiche correctement, mais est-ce que tu as modifié ton code de test ? En particulier est-ce que la méthode setVisible est bien déclaré APRES la méthode add(affichage) ? Cela peut aussi venir de l'ordre dans lequel les éléments sont affichés dans paint, je commencerais déjà par simplifier au maximum ton paint, et ne garder que ce qui est strictement nécessaire (les méthodes g.xxx et les boucles) mais la vitesse d'exécution de paint est primordial pour éviter les bugs d'affichage.
Pour tes diagonales, elles sont décalées à cause de ta marge (avec marge=0 c'est bon), il faut donc recalculer la position des deux droites en prenant en compte tes marges. En fait tu as déjà essayé de le faire, mais il faut le faire bien...
Mais tu aurais pu le faire pour les 2 autres (drawOvals et drawStrings) qui ont bien plus de lignes !
Pour ton histoire de initAB, pourquoi ne pas avoir directement rempli ton tableau lors de sa création, par exemple au lieu de faire this.dejaInitialise = false; dans Round() tu pourrais directement appeler initAB, et ainsi ne pas avoir à l'utiliser dans paint.
Il faut toujours limiter au maximum les opérations dans paint, par exemple tous tes calculs centreCercle, rayonGrandCercle, etc. pourraient être fais à la construction, ce sont des valeurs qui ne changeront jamais de toute façon... de même que des propriétés comme setBackground qui ne sont à faire qu'une seule fois, pas à chaque paint !
Au niveau de ton problème d'affichage moi je ne l'ai pas chez moi, ça s'affiche correctement, mais est-ce que tu as modifié ton code de test ? En particulier est-ce que la méthode setVisible est bien déclaré APRES la méthode add(affichage) ? Cela peut aussi venir de l'ordre dans lequel les éléments sont affichés dans paint, je commencerais déjà par simplifier au maximum ton paint, et ne garder que ce qui est strictement nécessaire (les méthodes g.xxx et les boucles) mais la vitesse d'exécution de paint est primordial pour éviter les bugs d'affichage.
Pour tes diagonales, elles sont décalées à cause de ta marge (avec marge=0 c'est bon), il faut donc recalculer la position des deux droites en prenant en compte tes marges. En fait tu as déjà essayé de le faire, mais il faut le faire bien...
rayonGrandCercle = taille/2; coord = (int) ((rayonGrandCercle-marge)*Math.sqrt(2)/2);
Étienne9
Messages postés
1022
Date d'inscription
mardi 1 mars 2011
Statut
Membre
Dernière intervention
10 mai 2015
49
20 juin 2013 à 09:18
20 juin 2013 à 09:18
Salut KX,
J'ai fais les modifications mais les soucis ne sont pas réglés.
- Les JTextField sont visibles directement mais maintenant ils sont tout en haut et au bon endroit (en double...)
- Les diagonales sont toujours un léger problème.
- J'ai encore des erreurs partout.
J'ai bien fait comme tu as dis, j'ai créé plusieurs fonctions.
Voilà les codes Java :
https://pjjoint.malekal.com/files.php?read=20130620_l7u11m14k13x10
Je pense que ça sera plus facile comme ça :)
J'ai fais les modifications mais les soucis ne sont pas réglés.
- Les JTextField sont visibles directement mais maintenant ils sont tout en haut et au bon endroit (en double...)
- Les diagonales sont toujours un léger problème.
- J'ai encore des erreurs partout.
J'ai bien fait comme tu as dis, j'ai créé plusieurs fonctions.
Voilà les codes Java :
https://pjjoint.malekal.com/files.php?read=20130620_l7u11m14k13x10
Je pense que ça sera plus facile comme ça :)
KX
Messages postés
16733
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
31 janvier 2024
3 014
20 juin 2013 à 19:16
20 juin 2013 à 19:16
"J'ai encore des erreurs partout."
Comme je le disais hier, les traces sont longues avec Swing, mais au final il n'y a qu'une erreur.
La variable gris doit être entre 0 et 255, or au moment de l'exception elle a pour valeur -20 !!
C'est parce que tu ne réinitialises pas la variable gris à 200 entre deux paint. Donc au premier paint gris va de 200 à 140, au deuxième paint de 120 à 60, et au troisième il plante à -20...
Il faut donc que tu réinitialises la variable gris au départ de chaque drawOvals.
Pour t'aider à clarifier un peu ton code voici ce que je propose : tout ce qui est constant, est déclaré private final dans la classe Round, et tout ce qui évolue est déclaré à l'intérieur de la méthode. Cela évite ce genre de conflits
Remarque : un attribut final peut être initialisé soit à sa déclaration (dans ce cas il est généralement static), soit dans le constructeur (dans ce cas il dépend des paramètres du constructeur et donc de l'objet). S'il n'est pas initialisé il y aura une erreur à la compilation.
Remarque : cela peut se généraliser à tout programme Java...
"Les JTextField sont visibles directement mais maintenant ils sont tout en haut et au bon endroit (en double...) "
Non, ils sont bien présents qu'une seule fois, par contre c'est vrai qu'ils se déplacent tout seuls au moment du paint, mais c'est parce que tu fais des add() dans le paint alors que les JTextFields n'ont pas à être gérés dans le paint, ils doivent être ajoutés une seule fois à la fenêtre, par exemple dans le initAB, en revanche tu peux les déplacer si nécessaires en fonction de la taille de la fenêtre même si tu ne gères pas ce cas dans ton code.
Remarque : ta méthode de positionnement est très alambiquée ! Tout ton code en général est très compliqué pour quelque chose de normalement assez simple... J'essayerais de te proposer quelque chose de plus simple un peu plus tard dans la soirée, ou demain, tout en gardant la structure de base que tu as utilisée jusqu'à présent. Le problème de diagonale devrait se régler tout seul.
Comme je le disais hier, les traces sont longues avec Swing, mais au final il n'y a qu'une erreur.
java.lang.IllegalArgumentException: Color parameter outside of expected range: Red Green Blue at g.setColor(new Color(gris,gris,gris));
La variable gris doit être entre 0 et 255, or au moment de l'exception elle a pour valeur -20 !!
C'est parce que tu ne réinitialises pas la variable gris à 200 entre deux paint. Donc au premier paint gris va de 200 à 140, au deuxième paint de 120 à 60, et au troisième il plante à -20...
Il faut donc que tu réinitialises la variable gris au départ de chaque drawOvals.
Pour t'aider à clarifier un peu ton code voici ce que je propose : tout ce qui est constant, est déclaré private final dans la classe Round, et tout ce qui évolue est déclaré à l'intérieur de la méthode. Cela évite ce genre de conflits
Remarque : un attribut final peut être initialisé soit à sa déclaration (dans ce cas il est généralement static), soit dans le constructeur (dans ce cas il dépend des paramètres du constructeur et donc de l'objet). S'il n'est pas initialisé il y aura une erreur à la compilation.
Remarque : cela peut se généraliser à tout programme Java...
/** Couleur gris le plus loin du centre qui diminuera, plus entier est petit, plus le gris sera foncé*/ private final static int GRIS=200; public void drawOvals(Graphics g) { int gris = GRIS; ... }
"Les JTextField sont visibles directement mais maintenant ils sont tout en haut et au bon endroit (en double...) "
Non, ils sont bien présents qu'une seule fois, par contre c'est vrai qu'ils se déplacent tout seuls au moment du paint, mais c'est parce que tu fais des add() dans le paint alors que les JTextFields n'ont pas à être gérés dans le paint, ils doivent être ajoutés une seule fois à la fenêtre, par exemple dans le initAB, en revanche tu peux les déplacer si nécessaires en fonction de la taille de la fenêtre même si tu ne gères pas ce cas dans ton code.
Remarque : ta méthode de positionnement est très alambiquée ! Tout ton code en général est très compliqué pour quelque chose de normalement assez simple... J'essayerais de te proposer quelque chose de plus simple un peu plus tard dans la soirée, ou demain, tout en gardant la structure de base que tu as utilisée jusqu'à présent. Le problème de diagonale devrait se régler tout seul.
KX
Messages postés
16733
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
31 janvier 2024
3 014
20 juin 2013 à 22:52
20 juin 2013 à 22:52
Voici de quoi continuer ton code sur des bases saines, je ne dis pas qu'il faut tout garder tel quel, mais tu verras notamment que le code dans le paint est considérablement réduit, en contre-partie le constructeur est un peu plus compliqué, mais il n'est exécuté qu'une fois...
package kx.ccm.etienne9; import javax.swing.JFrame; public class Test { public static void main(String args[]) { int taille = 600; int nb = 4; final JFrame jframe= new JFrame("Round"); jframe.setSize(taille+17,taille+39); jframe.setResizable(false); jframe.add(new Round(taille,nb)); jframe.setLocationRelativeTo(null); jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jframe.setVisible(true); } }
package kx.ccm.etienne9; import javax.swing.JTextField; public class Couple { private final int x; private final int y; private final String a; private final JTextField b; public Couple(int x, int y) { a = String.format("A(%d,%d)",x,y); b = new JTextField(String.format("B(%d,%d)",x,y)); this.x=x; this.y=y; } public String getA() { return a; } public JTextField getB() { return b; } public int getX() { return x; } public int getY() { return y; } public int getDX(int base) { if (x==0) return x*base; else if (x>0) return x*base+base/2; else return x*base-base/2; } public int getDY(int base) { if (y==0) return y*base; else if (y>0) return y*base+base/2; else return y*base-base/2; } }
package kx.ccm.etienne9; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import javax.swing.JPanel; import javax.swing.JTextField; public class Round extends JPanel { private static final long serialVersionUID = 1; private final static int MARGE = 20; private final static Dimension DIM_FIELD = new Dimension(45,25); private final static Color FOND = Color.BLUE;//new Color(225,225,225); private final static Color COULEUR_CENTRE = Color.RED;//new Color(140,140,140); private final static Color COULEUR_BORD = Color.GREEN;//new Color(200,200,200); private final static Color CONTOUR = Color.BLACK; private final int nb; private final Couple[] tab; private final int ecartEntreDeuxCercles; private final int rayonGrandCercle; private final int centreCercle; private final int coord; private final Color[] degrades; public Round(int taille,int nbCercles) { setSize(taille,taille); setLayout(null); setBackground(FOND); this.nb = nbCercles; this.tab = new Couple[4*nb+1]; ecartEntreDeuxCercles = (taille/2-MARGE)/(nb+1); rayonGrandCercle = (nb+1)*ecartEntreDeuxCercles; centreCercle = rayonGrandCercle+MARGE; coord = (int) (rayonGrandCercle*Math.sqrt(2)/2); initAB(); degrades = new Color[nb+1]; initCouleurs(); } private void initAB() { tab[0] = new Couple(0,0); for (int i=1, j=1; i<=nb; i++) { tab[j++] = new Couple(0,+i); tab[j++] = new Couple(0,-i); tab[j++] = new Couple(+i,0); tab[j++] = new Couple(-i,0); } for (Couple c : tab) { JTextField field = c.getB(); field.setBounds(centreCercle+c.getDX(ecartEntreDeuxCercles)-DIM_FIELD.width/2,centreCercle+c.getDY(ecartEntreDeuxCercles)-DIM_FIELD.height/2,DIM_FIELD.width, DIM_FIELD.height); add(field); } tab[0].getB().setLocation(centreCercle-DIM_FIELD.width/2,centreCercle-DIM_FIELD.height/2); } private static float[] getHSV(Color clr) { return Color.RGBtoHSB(clr.getRed(), clr.getGreen(), clr.getBlue(), null); } private void initCouleurs() { float[] centre = getHSV(COULEUR_CENTRE); float[] bord = getHSV(COULEUR_BORD); for (int i=0; i<=nb; i++) degrades[i] = Color.getHSBColor((bord[0]*i+centre[0]*(nb-i))/nb, (bord[1]*i+centre[1]*(nb-i))/nb, (bord[2]*i+centre[2]*(nb-i))/nb); } @Override public void paint(Graphics g) { super.paint(g); drawOvals(g); drawLines(g); drawStrings(g); super.paintComponents(g); } private void drawOvals(Graphics g) { for (int i=nb; i>=0; i--) { int sz = (i+1)*ecartEntreDeuxCercles*2; int mg = centreCercle-sz/2; g.setColor(degrades[i]); g.fillOval(mg, mg, sz, sz); } } private void drawStrings(Graphics g) { g.setColor(CONTOUR); for (Couple c : tab) { JTextField field = c.getB(); g.drawString(c.getA(),field.getX(),field.getY()); } } private void drawLines(Graphics g) { g.setColor(CONTOUR); g.drawLine(centreCercle-coord,centreCercle-coord,centreCercle+coord,centreCercle+coord); g.drawLine(centreCercle+coord,centreCercle-coord,centreCercle-coord,centreCercle+coord); } }
Étienne9
Messages postés
1022
Date d'inscription
mardi 1 mars 2011
Statut
Membre
Dernière intervention
10 mai 2015
49
21 juin 2013 à 11:40
21 juin 2013 à 11:40
Salut KX,
Impeccable, je ne sais pas comment te remercier :)
Par contre, c'est quoi getdx et getdy s'il te plaît ?
Cordialement et merci beaucoup d'avance.
Impeccable, je ne sais pas comment te remercier :)
Par contre, c'est quoi getdx et getdy s'il te plaît ?
Cordialement et merci beaucoup d'avance.
KX
Messages postés
16733
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
31 janvier 2024
3 014
21 juin 2013 à 15:35
21 juin 2013 à 15:35
getDX et getDY je m'en sers dans initAB pour positionner correctement les JTextField au centre de chaque disque, le paramètre "base" correspond à la distance entre deux cercles.