1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
| public class Plateau extends JPanel {
// pour les cases ovales
public static final float DEBUT_OVAL_X = 0.2f; // il s'agit de l'offset - on travaille tout en relatif (pourcentage), pour pouvoir s'adapter à une taille de plateau qui change (ici 20%)
public static final float DEBUT_OVAL_Y = 0.2f; // il s'agit de l'offset
public static final float ESPACE_OVAL_X = 0.05f; // on va utiliser ça pour définir un espacement entre chaque case
public static final float ESPACE_OVAL_Y = 0.05f; // on va utiliser ça pour définir un espacement entre chaque case
// pour les cases carrées
public static final float DEBUT_CARRE_X = 0.1f; // il s'agit de l'offset
public static final float DEBUT_CARRE_Y = 0.1f; // il s'agit de l'offset
public static final float ESPACE_CARRE_X = 0.1f; // on va utiliser ça pour définir un espacement entre chaque case
public static final float ESPACE_CARRE_Y = 0.1f; // on va utiliser ça pour définir un espacement entre chaque case
// pour le rectangle rouge, la base est les carrés
public static final float DEBUT_RECTANGLE_X = DEBUT_CARRE_X;
public static final float DEBUT_RECTANGLE_Y = DEBUT_CARRE_Y;
private Case[][] tabCaseOval = new Case[4][8];
private Case[][] tabCaseCarre = new Case[4][32];
public Plateau() {
setBackground(Color.CYAN);
// rempli les tableaux :
remplirTableau(tabCaseOval); // j'utilise une méthode parce que j'ai 2 tableaux mais aussi parce que ça évite d'avoir trop de chose dans la même méthode ou constructeur
remplirTableau(tabCaseCarre);
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
// Cet événement réagit au changement de taille du Plateau
calculerFormes(tabCaseOval, DEBUT_OVAL_X, DEBUT_OVAL_Y, ESPACE_OVAL_X, ESPACE_OVAL_Y); // je calcule les positions des rectangles correspondant (j'utilise des constantes comme ça je peux modifier ces valeurs à un seul endroit sans revenir dans le code)
calculerFormes(tabCaseCarre, DEBUT_CARRE_X, DEBUT_CARRE_Y, ESPACE_CARRE_X, ESPACE_CARRE_Y);
repaint(); // on a changer la taille des rectangles, il faut redessiner
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
clicCase(e.getX(), e.getY()); // on cherche la case cliquée
}
});
}
private void remplirTableau(Case[][] tabCase) {
for(int i=0; i<tabCase.length; i++) {
for(int j=0; j<tabCase[i].length; j++) {
tabCase[i][j]=new Case();
}
}
}
private void calculerFormes(Case[][] tabCase, float debutx,
float debuty, float espacex, float espacey) {
// quelle est la taille du plateau
double width = getWidth();
double height = getHeight();
// on calcul les pourcentages pour les offset
double offsetx = width * debutx;
double offsety = height * debuty;
// quelle est la taille du plateau dans lequel on va dessiner : les offset debutx et debuty servent de marges
width = width - offsetx - offsetx;
height = height - offsety - offsety;
// combien de cases en hauteur
int nbHeight = tabCase.length;
// combien de cases en largeur
int nbWidth = tabCase[0].length;
// la largeur width est égale au nombre de case en largeur x la largeur d'une case + le nombre d'espaces entre chaque case * l'espacement entre case
// le nombre d'espaces entre chaque case et le nombre de case moins un
// width = nbWidth * caseWidth + (nbWidth-1) * espaceWidth
// on définit l'espace ici comme un % de la largeur de case :
// width = nbWidth * caseWidth + (nbWidth-1) * caseWidth * espaceX
// autrement écrit : width = caseWidth * ( nbWidth + ( nbWidth - 1 ) * espacex ))
// donc caseWidth = width / ( nbWidth + ( nbWidth - 1 ) * espacex ))
double caseWidth = width / ( nbWidth + (nbWidth-1) * espacex);
// pareil pour la hauteur
double caseHeight = height/ ( nbHeight + (nbHeight -1) * espacey);
// maintenant on peut calculer les rectangles correspondant au case :
double y = offsety;
for(int i=0; i<tabCase.length; i++) {
double x = offsetx;
for(int j=0; j<tabCase[i].length; j++) {
Shape shape; // on détermine la forme
if ( tabCase == tabCaseOval ) { // table d'ovales...
shape = new Ellipse2D.Double(x, y, caseWidth, caseHeight); // la forme est un ovale
}
else { // sinon
shape = new Rectangle((int)x, (int)y, (int)caseWidth, (int)caseHeight); // c'est un rectangle
}
tabCase[i][j].setShape(shape);
x += caseWidth; // on avance d'une largeur de case
x += caseWidth * espacex; // on avance de l'espace entre case
}
y += caseHeight; // on avance d'une hauteur de case
y += caseHeight * espacey; // on avance de l'esapce entre case
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// quelle est la taille du plateau
double width = getWidth();
double height = getHeight();
// on calcul les pourcentages pour les offset
double offsetx = width * DEBUT_RECTANGLE_X;
double offsety = height * DEBUT_RECTANGLE_Y;
// on dessine le fond qu'on a envie
g.setColor(Color.RED);
g.fillRect((int)offsetx, (int)offsety, (int)(getWidth() - offsetx*2), (int)(getHeight() - offsety*2));
// puisqu'on a calculer les rectangles dans calculerRectangles, il nous suffit de les utiliser pour dessiner au bon endroit
g.setColor(Color.MAGENTA);
dessineTableau(g, tabCaseCarre);
g.setColor(Color.WHITE);
dessineTableau(g, tabCaseOval);
}
private void dessineTableau(Graphics g, Case[][] tabCase) {
for(int i=0; i<tabCase.length; i++) {
for(int j=0; j<tabCase[i].length; j++) {
((Graphics2D)g).fill(tabCase[i][j].getShape());
}
}
}
private void clicCase(int mouseX, int mouseY) {
if ( !clicCase(mouseX, mouseY, tabCaseOval) ) { // un clic sur un oval est prioritaire
if( !clicCase(mouseX, mouseY, tabCaseCarre) ) {
clicHorsCase(mouseX, mouseY);
}
}
}
private void clicHorsCase(int x, int y) {
// on passe ici si on a cliqué sur aucune case
System.out.println("Cliquer en dehors des cases");
// ici on même déterminer encore si on est dans le rectangle rouge ou pas
// quelle est la taille du plateau
double width = getWidth();
double height = getHeight();
// on calcul les pourcentages pour les offset
double offsetx = width * DEBUT_RECTANGLE_X;
double offsety = height * DEBUT_RECTANGLE_Y;
if ( new Rectangle2D.Double(offsetx, offsety, width-offsetx-offsetx, height-offsety-offsety).contains(x, y ) ) {
System.out.println("Clic dans le rectangle rouge");
}
else {
System.out.println("Clic en dehors du rectangle rouge");
}
}
private boolean clicCase(int x, int y, Case[][] tabCase) {
for(int i=0; i<tabCase.length; i++) {
for(int j=0; j<tabCase[i].length; j++) {
if ( tabCase[i][j].getShape().contains(x, y) ) {
// si le point de la souris est dans le rectangle
if ( tabCase == tabCaseOval ) {
clicCaseOval(i, j, tabCase[i][j]);
}
else {
clicCaseCarre(i, j, tabCase[i][j]);
}
return true; // on a trouvé une case qui correspond
}
}
}
return false; // on a trouvé aucune case
}
private void clicCaseOval(int i, int j, Case caseOval) {
// on passe par ici si on a cliqué sur case ovale
System.out.println("Clic sur la case ovale (" + i + ", " + j + ")");
}
private void clicCaseCarre(int i, int j, Case caseCarre) {
// on passe par ici si on a cliqué sur case carrée
System.out.println("Clic sur la case carrée (" + i + ", " + j + ")");
}
} |
Partager