package org.Views; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.util.Observable; import java.util.Observer; import javax.swing.BorderFactory; import javax.swing.JPanel; import org.Models.Grille; import org.Models.Jeu; import org.Models.Ordonnanceur; import org.Models.PieceCourante; /** * Vue graphique de la grille de jeu Tetris. * Affiche l'état de la grille, la pièce courante et gère la mise à jour de l'affichage. */ @SuppressWarnings("deprecation") public class VueGrille extends JPanel implements Observer, Runnable { private JPanel grillePanel; private Grille grille; private Jeu jeu; private Ordonnanceur ordonnanceur; private boolean afficherFenetreFinPartie = false; private int nbLignes; private int nbColonnes; private JPanel[][] casesGrille; /** * Construit la vue de la grille à partir du modèle de grille et du jeu. * * @param grille le modèle de la grille * @param jeu le modèle du jeu */ public VueGrille(Grille grille, Jeu jeu) { this.grille = grille; this.jeu = jeu; this.nbLignes = grille.getNbLignes(); this.nbColonnes = grille.getNbColonnes(); this.nbLignes = grille.getNbLignes(); this.nbColonnes = grille.getNbColonnes(); setLayout(new BorderLayout()); initialiserVueGrille(); grille.addObserver(this); jeu.addObserver(this); this.ordonnanceur = new Ordonnanceur(this, 1000); ordonnanceur.start(); } /** * Redimensionne les cases de la grille pour qu'elles restent carrées * lors du redimensionnement du panneau. */ public void resizeCases() { int largeurPanel = grillePanel.getWidth(); int hauteurPanel = grillePanel.getHeight(); if (largeurPanel == 0 || hauteurPanel == 0) { return; } int taille = Math.min(largeurPanel, hauteurPanel); grillePanel.setPreferredSize(new Dimension(taille, taille)); grillePanel.setMaximumSize(new Dimension(taille, taille)); grillePanel.setMinimumSize(new Dimension(taille, taille)); grillePanel.setSize(new Dimension(taille, taille)); int tailleCaseX = largeurPanel / nbColonnes; int tailleCaseY = hauteurPanel / nbLignes; int tailleCase = Math.min(tailleCaseX, tailleCaseY); Dimension taillePreferee = new Dimension(tailleCase, tailleCase); for (int i = 0; i < nbLignes; i++) { for (int j = 0; j < nbColonnes; j++) { casesGrille[i][j].setPreferredSize(taillePreferee); } } grillePanel.revalidate(); grillePanel.repaint(); } /** * Initialise l'affichage de la grille et crée les cases graphiques. */ private void initialiserVueGrille() { grillePanel = new JPanel(new GridLayoutCarre(nbLignes, nbColonnes)); // pour que les cases soient carrés add(grillePanel, BorderLayout.CENTER); casesGrille = new JPanel[nbLignes][nbColonnes]; for (int i = 0; i < nbLignes; i++) { for (int j = 0; j < nbColonnes; j++) { JPanel caseG = new JPanel() { @Override public Dimension getPreferredSize() { return super.getPreferredSize(); } }; caseG.setBackground(Color.WHITE); caseG.setBorder(BorderFactory.createLineBorder(Color.GRAY)); casesGrille[i][j] = caseG; grillePanel.add(caseG); } } } /** * Met à jour l'affichage de la grille et de la pièce courante. */ public synchronized void updateGrille() { for (int i = 0; i < nbLignes; i++) { for (int j = 0; j < nbColonnes; j++) { JPanel caseG = casesGrille[i][j]; if (grille.getGrille()[i][j]) { caseG.setBackground(Color.BLUE); } else { caseG.setBackground(Color.WHITE); } } } // dessiner la pièce courante if (jeu != null) { PieceCourante piece = grille.getPieceCourante(); int posX = grille.getPieceCouranteX(); int posY = grille.getPieceCouranteY(); boolean[][] motif = piece.getMotif(); for (int i = 0; i < motif.length; i++) { for (int j = 0; j < motif[i].length; j++) { if (motif[i][j]) { int grilleX = posX + j; int grilleY = posY + i; if (grilleY >= 0 && grilleY < nbLignes && grilleX >= 0 && grilleX < nbColonnes) { JPanel caseG = casesGrille[grilleY][grilleX]; caseG.setBackground(Color.RED); } } } } } repaint(); } /** * * Met à jour la vue de la grille lorsque l'état de la grille change. */ @Override public void update(Observable o, Object arg) { if (o instanceof Grille) { updateGrille(); } if (o instanceof Jeu) { Jeu jeu = (Jeu) o; if (!jeu.jeuEnCours && !afficherFenetreFinPartie) { afficherFenetreFinPartie = true; new VueGameOver( jeu.getGrille().getScore(), e -> System.exit(0), () -> jeu.reinitialiserPartie() ); } } } /** * * Met à jour la vue de la grille périodiquement selon l'ordonnaceur. */ @Override public void run() { updateGrille(); } }