Dans ce tutoriel, tu vas créer un jeu du Morpion en Java (Tic-Tac-Toe) avec Swing et NetBeans : un plateau 3×3 cliquable, la détection du gagnant ou de l’égalité et un bouton pour recommencer. Un projet idéal pour progresser en Java, découvrir Swing et apprendre à séparer la logique du jeu de l’interface.

Ce que tu vas construire : un jeu du Morpion en Java
Marre des « Hello World » ? Ce jeu du Morpion en Java est un vrai petit jeu qui fonctionne, avec une logique solide et une interface graphique. Tu y apprendras des compétences utiles, que tu sois étudiant, développeur en herbe ou simplement curieux.
Prérequis
- Un JDK installé (Java 8 ou plus récent)
- L’IDE Apache NetBeans (ou un autre IDE Java comme IntelliJ IDEA ou Eclipse)
- Les bases de Java : classes, méthodes, tableaux et conditions
Étape 1 : créer le projet dans NetBeans
- Ouvre NetBeans et crée un nouveau projet Java Application nommé
TicTacToe - Dans le dossier Source Packages, ajoute un nouveau package :
com.myapp.tictactoepackageTon jeu du Morpion en Java repose sur deux classes à créer dans ce package :
On sépare la logique (le modèle) de l’affichage (la vue). C’est une version simplifiée du modèle MVC : le code est plus clair, plus facile à tester et à faire évoluer.
Étape 2 : GameModel.java, le cerveau du jeu
Cette classe gère toute la logique de ton jeu du Morpion en Java : le plateau, le joueur actuel, la vérification du gagnant et les changements de tour.
package com.myapp.tictactoe;
public class GameModel {
public enum Player { X, O, NONE }
private Player[] board = new Player[9];
private Player currentPlayer = Player.X;
private boolean gameOver = false;
public GameModel() { reset(); }
public void reset() {
for (int i = 0; i < 9; i++) board[i] = Player.NONE;
currentPlayer = Player.X;
gameOver = false;
}
public Player getCurrentPlayer() { return currentPlayer; }
public Player getCell(int idx) { return board[idx]; }
public boolean isGameOver() { return gameOver; }
public Player playMove(int idx) {
if (gameOver || board[idx] != Player.NONE) return null;
board[idx] = currentPlayer;
Player winner = checkWinner();
if (winner != Player.NONE) {
gameOver = true;
return winner;
}
if (isBoardFull()) {
gameOver = true;
return Player.NONE; // match nul
}
currentPlayer = (currentPlayer == Player.X) ? Player.O : Player.X;
return null;
}
private boolean isBoardFull() {
for (Player p : board)
if (p == Player.NONE) return false;
return true;
}
private Player checkWinner() {
int[][] lines = {
{0,1,2},{3,4,5},{6,7,8},
{0,3,6},{1,4,7},{2,5,8},
{0,4,8},{2,4,6}
};
for (int[] line : lines) {
Player a = board[line[0]], b = board[line[1]], c = board[line[2]];
if (a != Player.NONE && a == b && b == c) return a;
}
return Player.NONE;
}
}GameModel.java- Le plateau est un tableau de 9 cases
- L’enum Player distingue clairement X, O et une case vide (NONE)
- La méthode
playMove()joue le rôle d’arbitre : elle accepte ou refuse le coup et indique s’il y a un gagnant ou une égalité - Impossible de tricher : une case déjà prise ne peut pas être rejouée
Étape 3 : GameView.java, l’interface graphique Swing
Maintenant que le cerveau du jeu du Morpion en Java est prêt, il faut le corps : l’interface que les joueurs utilisent pour poser leurs X et leurs O.
package com.myapp.tictactoe;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GameView extends JFrame {
private GameModel model = new GameModel();
private JButton[] cells = new JButton[9];
private JLabel statusLabel = new JLabel("Au tour de X");
private JButton resetBtn = new JButton("Recommencer");
public GameView() {
super("Morpion");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout(10,10));
JPanel grid = new JPanel(new GridLayout(3,3,5,5));
for (int i = 0; i < 9; i++) {
final int idx = i;
cells[i] = new JButton("");
cells[i].setFont(new Font(Font.SANS_SERIF, Font.BOLD, 48));
cells[i].addActionListener(e -> handleClick(idx));
grid.add(cells[i]);
}
JPanel bottom = new JPanel();
bottom.add(statusLabel);
bottom.add(resetBtn);
resetBtn.addActionListener(e -> initGame());
add(grid, BorderLayout.CENTER);
add(bottom, BorderLayout.SOUTH);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
private void initGame() {
model.reset();
statusLabel.setText("Au tour de X");
for (JButton b : cells) {
b.setText("");
b.setEnabled(true);
}
}
private void handleClick(int idx) {
GameModel.Player winner = model.playMove(idx);
GameModel.Player p = model.getCell(idx);
cells[idx].setText(p == GameModel.Player.X ? "X" : "O");
if (winner != null) {
if (winner == GameModel.Player.NONE) {
statusLabel.setText("Match nul.");
} else {
statusLabel.setText("Le joueur " + winner + " a gagné !");
}
disableAll();
} else {
statusLabel.setText("Au tour de " + model.getCurrentPlayer());
}
}
private void disableAll() {
for (JButton b : cells) b.setEnabled(false);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(GameView::new);
}
}GameView.javaJPanel en grille 3×3 accueille les neuf boutons.SwingUtilities.invokeLater() lance l’interface sur le bon thread, comme le recommande Swing.Étape 4 : lancer le jeu du Morpion en Java
- Clique sur Run Project (ou F6) dans NetBeans
- Une fenêtre s’ouvre avec le plateau 3×3
- Joue une partie : les X et les O s’affichent à chaque clic, puis un message annonce le vainqueur ou l’égalité
- Clique sur « Recommencer » pour rejouer
Aller plus loin
- Ajouter un tableau des scores qui compte les victoires de X et de O
- Créer un mode contre l’ordinateur, d’abord aléatoire, puis imbattable avec l’algorithme minimax
- Mettre en couleur la ligne gagnante
- Passer à un projet Java plus complet : le logiciel de gestion de restaurant avec JavaFX et SQLite
- Découvrir d’autres jeux de plateau : le jeu de dames en Python ou le jeu d’échecs en React et TypeScript
FAQ : questions fréquentes
Faut-il absolument utiliser NetBeans ?
Non. Le code fonctionne dans n’importe quel IDE Java (IntelliJ IDEA, Eclipse, VS Code avec l’extension Java). Il suffit de respecter le package com.myapp.tictactoe.
Pourquoi utiliser SwingUtilities.invokeLater() ?
Swing n’est pas thread-safe : toute modification de l’interface doit se faire sur le thread dédié à l’affichage. invokeLater() garantit que la fenêtre est créée au bon endroit.
Comment le jeu détecte-t-il une égalité ?
Quand toutes les cases sont remplies et qu’aucune ligne, colonne ou diagonale n’est complète, la partie est déclarée nulle.
Swing est-il encore utilisé ?
Swing reste très présent dans l’enseignement et dans de nombreuses applications existantes. Pour un projet moderne, JavaFX est une bonne alternative.
Bravo, ton jeu du Morpion en Java est terminé ! Tu as découvert Swing et appris à séparer la logique de l’interface. Partage ta version ou tes questions en commentaire !


L&m