Graphics JPanel plusieurs cercles

Étienne9 Messages postés 1022 Date d'inscription   Statut Membre Dernière intervention   -  
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour à tous,

Mon but est de faire une interface graphique pour ceci :
http://www.hostingpics.net/viewer.php?id=177416interface.jpg

Sachant qu'il y a toujours 4 quartiers de cercle mais le nombre de cercles peut changer.
En gros, l'interface peut devenir ceci :
http://hpics.li/6e6b53d

Pour ce qui est de la couleur, gris clair au fond et pour les cercles faire tout gris mais plus on est au centre plus c'est foncé...

J'ai commencé si vous voulez mais j'ai un peu de mal. J'ai déjà tout dans mon cerveau mais le problème c'est qu'à mon avis je dois faire des erreurs de calculs.

J'ai créé une classe Couple.java car il y a une chaîne de caractère et un JTextField :
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);
 }
 public void setA(String a) {
  this.A = a;
 }
 public void setB(String b) {
  this.B.setName(b);
 }
 public String getA() {
  return A;
 }
 public String getB() {
  return this.B.getName();
 }
}


Et j'ai créé une classe Round.java qui me permet de faire l'affichage sachant que le tableau à double dimension permet de stocker les JTextField et les chaînes. Le premier indice correspond au numéro du quartier (le quartier en haut c'est 0, le quartier à droite c'est 1, le quartier en bas c'est 2 et le quartier à gauche c'est 3)
Une fois qu'on a donné le numéro du quartier on doit donner le numéro du cercle, le plus petit cercle c'est 0, celui un peu plus grand c'est 1 etc.... Et le plus grand cercle c'est nb-1 (il y a donc nb cercles)

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=50; // entre deux couleurs
  int marge=50; // 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));
   for (int i=nb;i>=1;i--) {
    g.setColor(new Color(gris,gris,gris));
    g.drawOval(hautgauche,hautgauche,ecartEntreDeuxCercles*i,ecartEntreDeuxCercles*i);
    hautgauche = hautgauche+ecartEntreDeuxCercles;
    gris = gris - ecartCouleur;
   }
  }
 }
}


Bien sûr j'ai dû faire un code pour lancer mais je m'en fous un peu c'est juste pour tester :

import java.awt.Color;
import java.awt.Graphics;
import java.lang.Math.*;
import javax.swing.JFrame;

public class Test {
 public static void main(String args[]) {
  Round affichage = new Round(500,4);
  JFrame jframe= new JFrame();
  jframe.setSize(affichage.getTaille(),affichage.getTaille());
  jframe.add(affichage);
  jframe.setTitle("Round 7");
  jframe.setLocationRelativeTo(null);
  jframe.setVisible(true);
 }
}


Quelqu'un peut m'aider s'il vous plaît ? Les cercles ne sont en fait pas les uns dans les autres et j'ai du mal.

Cordialement.

9 réponses

Étienne9 Messages postés 1022 Date d'inscription   Statut Membre Dernière intervention   49
 
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...
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 ?
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
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...

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);
0
Étienne9 Messages postés 1022 Date d'inscription   Statut Membre Dernière intervention   49
 
Bonsoir,

Merci beaucoup KX.
Par contre, comment faire de façon simple, des diagonales mais uniquement dans mes cercles ?
0
Étienne9 Messages postés 1022 Date d'inscription   Statut Membre Dernière intervention   49
 
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 :

  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 :)
0
Étienne9 Messages postés 1022 Date d'inscription   Statut Membre Dernière intervention   49
 
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 ?
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
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 :

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);
}
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Étienne9 Messages postés 1022 Date d'inscription   Statut Membre Dernière intervention   49
 
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 !

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 ?
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
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.
0
Étienne9 Messages postés 1022 Date d'inscription   Statut Membre Dernière intervention   49
 
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 :

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 ;)
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
"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...

rayonGrandCercle = taille/2;
coord = (int) ((rayonGrandCercle-marge)*Math.sqrt(2)/2);
0
Étienne9 Messages postés 1022 Date d'inscription   Statut Membre Dernière intervention   49
 
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 :)
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
"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.

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.
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
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);
    }
}
0
Étienne9 Messages postés 1022 Date d'inscription   Statut Membre Dernière intervention   49
 
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.
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 
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.
0