web-dev-qa-db-fra.com

Créer un échiquier avec JPanel

J'ai un simple échiquier dans un JPanel avec GridLayout(8,8) comme gestionnaire de disposition.

J'essaie d'ajouter des panneaux pour le nom de colonne et le numéro de ligne des champs.

En ce moment, j'ai créé un autre panneau avec BorderLayout comme gestionnaire de disposition, et dans ce panneau j'ajoute la carte dans BorderLayout.CENTER. À côté de la carte elle-même, j'ai ajouté un panneau avec GridLayout(0,8) dans BorderLayout.SOUTH Et un panneau avec GridLayout(8,0) dans BorderLayout.WEST. Le nombre de lignes est parfaitement placé à côté du tableau, car le nombre de lignes dans le JPanel gauche correspond au nombre de lignes dans le tableau, mais les noms des colonnes (A, B, C, D, E, F, G, H) dans le JPanel sous le plateau n'est pas placé correctement à cause du JPanel dans BorderLayout.WEST.

Que puis-je faire pour créer un échiquier approprié avec des panneaux latéraux pour afficher les numéros/noms de champ?

J'ai essayé de définir la disposition du panneau sud sur GridLayout(0,9) et d'avoir le premier champ vide, mais la largeur du panneau de gauche n'est pas égale à chaque champ du tableau, donc ce n'est pas une bonne solution.

12
Jamgreen

Remarque

L'interface graphique vue ici a été améliorée et déplacée vers Création d'une interface graphique d'échecs Swing robuste et redimensionnable .

Je vais laisser le GIF animé ici (parce que c'est mignon) et le code original, dépouillé (de seulement 125 lignes de code, le code final vu sur l'autre thread est 218 LOC).

Chess Game Layout

import Java.awt.*;
import Java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.*;

public class ChessBoardWithColumnsAndRows {

    private final JPanel gui = new JPanel(new BorderLayout(3, 3));
    private JButton[][] chessBoardSquares = new JButton[8][8];
    private JPanel chessBoard;
    private final JLabel message = new JLabel(
            "Chess Champ is ready to play!");
    private static final String COLS = "ABCDEFGH";

    ChessBoardWithColumnsAndRows() {
        initializeGui();
    }

    public final void initializeGui() {
        // set up the main GUI
        gui.setBorder(new EmptyBorder(5, 5, 5, 5));
        JToolBar tools = new JToolBar();
        tools.setFloatable(false);
        gui.add(tools, BorderLayout.PAGE_START);
        tools.add(new JButton("New")); // TODO - add functionality!
        tools.add(new JButton("Save")); // TODO - add functionality!
        tools.add(new JButton("Restore")); // TODO - add functionality!
        tools.addSeparator();
        tools.add(new JButton("Resign")); // TODO - add functionality!
        tools.addSeparator();
        tools.add(message);

        gui.add(new JLabel("?"), BorderLayout.LINE_START);

        chessBoard = new JPanel(new GridLayout(0, 9));
        chessBoard.setBorder(new LineBorder(Color.BLACK));
        gui.add(chessBoard);

        // create the chess board squares
        Insets buttonMargin = new Insets(0,0,0,0);
        for (int ii = 0; ii < chessBoardSquares.length; ii++) {
            for (int jj = 0; jj < chessBoardSquares[ii].length; jj++) {
                JButton b = new JButton();
                b.setMargin(buttonMargin);
                // our chess pieces are 64x64 px in size, so we'll
                // 'fill this in' using a transparent icon..
                ImageIcon icon = new ImageIcon(
                        new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB));
                b.setIcon(icon);
                if ((jj % 2 == 1 && ii % 2 == 1)
                        //) {
                        || (jj % 2 == 0 && ii % 2 == 0)) {
                    b.setBackground(Color.WHITE);
                } else {
                    b.setBackground(Color.BLACK);
                }
                chessBoardSquares[jj][ii] = b;
            }
        }

        //fill the chess board
        chessBoard.add(new JLabel(""));
        // fill the top row
        for (int ii = 0; ii < 8; ii++) {
            chessBoard.add(
                    new JLabel(COLS.substring(ii, ii + 1),
                    SwingConstants.CENTER));
        }
        // fill the black non-pawn piece row
        for (int ii = 0; ii < 8; ii++) {
            for (int jj = 0; jj < 8; jj++) {
                switch (jj) {
                    case 0:
                        chessBoard.add(new JLabel("" + (ii + 1),
                                SwingConstants.CENTER));
                    default:
                        chessBoard.add(chessBoardSquares[jj][ii]);
                }
            }
        }
    }

    public final JComponent getChessBoard() {
        return chessBoard;
    }

    public final JComponent getGui() {
        return gui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                ChessBoardWithColumnsAndRows cb =
                        new ChessBoardWithColumnsAndRows();

                JFrame f = new JFrame("ChessChamp");
                f.add(cb.getGui());
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.pack();
                // ensures the minimum size is enforced.
                f.setMinimumSize(f.getSize());
                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

Remarques

  • L'échiquier complet avec des colonnes à gauche et une rangée au-dessus est fourni par un 9x9 GridLayout. La première cellule de la disposition de la grille est une étiquette sans texte.
  • Cependant, pour simplifier la logique du jeu, nous maintenons un tableau de boutons 8x8 séparé.
  • Pour permettre la fonctionnalité du clavier, nous utilisons des boutons pour les emplacements de l'échiquier. Cela fournit également une indication de mise au point intégrée. Retirez la marge du bouton pour leur permettre de se réduire à la taille de l'icône. Ajoutez un ActionListener au bouton et il répondra aux événements du clavier et de la souris.
  • Le petit ? dans le côté gauche de l'interface graphique signifie que la zone est "réservée pour une utilisation future". Nous pourrions l'utiliser pour afficher des listes de pièces capturées, un sélecteur de choix de pièce lors de la promotion de pions, des statistiques de jeu, ...
  • Les images des pièces d'échecs ont été obtenues à partir de Exemples d'images pour le code et les questions et réponses sur le balisage , qui à son tour a été développé à partir de 'Remplir' les caractères Unicode dans les étiquettes .

    L'utilisation des images est plus simple, tandis que le remplissage des caractères Unicode est plus polyvalent et plus "léger". C'EST À DIRE. pour supporter 4 couleurs différentes dans 3 tailles distinctes de 3 styles de pièces d'échecs différents, il faudrait 36 ​​feuilles Sprite distinctes!
19
Andrew Thompson