Ciao, sto progettando la GUI per un gioco chiamato MyShelfie. Gioco da tavolo a turni, con una board (che è una matrice 10x10 contenente tessere oggetto, che sono una enum e che per quanto riguarda la GUI corrispondono a 6 immagini diverse). Ogni giocatore ha una bookshelf (matrice 6x5 di tessere oggetto) e deve riempirla per completare obiettivi e vincere la partita. Sto sviluppando la GUI con swing. In questo momento sto creando la GameScene, ovvero il JPanel in cui si svolgeranno i turni dei giocatori (che hanno già fatto login e tutto). Questa è la sua organizzazione: public class GameScene extends JPanel {
    private BoardPanel boardPanel;
    private BookshelfPanel playerBookshelfPanel;
    private OtherPlayerBookshelfPanel otherBookshelfPanel;
    private final CommonGoalPanel commonGoalPanel1;
    private final CommonGoalPanel commonGoalPanel2;
    private JButton confirmButton;

    private ChatPanel chatPanel;
    private List<String> tileTypes = null;


    private final PersonalGoalPanel personalGoalPanel;
    private final Image backgroundImage;
    private int numOfOtherPlayers = 1;


    public GameScene(SwingGUI swingGUI) {
        setLayout(null);

        // Crea l'istanza di BoardPanel
        boardPanel = new BoardPanel(tileTypes);
        boardPanel.setBounds(420, 75, 600, 600);
        add(boardPanel);

        otherBookshelfPanel = new OtherPlayerBookshelfPanel(numOfOtherPlayers);
        otherBookshelfPanel.setBounds(1150, 50, 175, 650);
        add(otherBookshelfPanel);

        playerBookshelfPanel = new BookshelfPanel(swingGUI);
        playerBookshelfPanel.setBounds(30, 75, 360, 360);
        add(playerBookshelfPanel);

        confirmButton = new JButton("Confirm");
        confirmButton.setBounds(1100, 700, 100, 40);
        confirmButton.addActionListener(e -> {
            // Invia la lista delle tessere selezionate al model
            List<Coordinate> selectedTileList = new ArrayList<>();
            for (Coordinate tilePosition : boardPanel.getSelectedTiles()) {

                selectedTileList.add(tilePosition);
            }
            swingGUI.getView().notifyObservers(new CoordinatesEvent(selectedTileList));
        });
        confirmButton.setEnabled(false); // Disabilita il ConfirmButton all'inizio
        add(confirmButton);





        commonGoalPanel1 = new CommonGoalPanel();
        commonGoalPanel1.setBounds(500, 700, 75, 75);
        add(commonGoalPanel1);

        commonGoalPanel2 = new CommonGoalPanel();
        commonGoalPanel2.setBounds(700,700,75,75);
        add(commonGoalPanel2);

        personalGoalPanel = new PersonalGoalPanel();
        personalGoalPanel.setBounds(900, 700, 75, 100);
        add(personalGoalPanel);

        chatPanel = new ChatPanel();
        chatPanel.setBounds(30,475,350,300);
        add(chatPanel);

        backgroundImage = new ImageIcon(Objects.requireNonNull(swingGUI.getClass().getResource("/PublisherMaterial/Display_1.jpg"))).getImage();

    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        // Draw background image
        g.drawImage(backgroundImage, 0, 0, getWidth(), getHeight(), this);

    }

    public void updateBoardPanel(List<String> tileTypes) {
        this.tileTypes = tileTypes;
        boardPanel.initializeGameMatrix(tileTypes);
        repaint(); // Aggiorna la visualizzazione della scena
    }
    public void setBoardPanel(BoardPanel boardPanel) {
        this.boardPanel = boardPanel;
    }

    public CommonGoalPanel getCommonGoalPanel1() {
        return commonGoalPanel1;
    }

    public CommonGoalPanel getCommonGoalPanel2() {
        return commonGoalPanel2;
    }

    public PersonalGoalPanel getPersonalGoalPanel() {
        return personalGoalPanel;
    }

    public BoardPanel getBoardPanel() {
        return boardPanel;
    }

    public void showConfirmButton(boolean b) {
        confirmButton.setVisible(b);
        confirmButton.setEnabled(b);
    }

    public BookshelfPanel getPlayerBookshelfPanel() {
        return playerBookshelfPanel;
    }
}
Sto avendo difficoltà nell'utilizzare il boardPanel. Il boardPanel è un JPanel che ha come sfondo un'immagine della board e su cui sopra inserirò una griglia per poterci mettere delle tessere oggetto. Ero riuscito a disegnarci sopra la board inizializzata, ma purtroppo poi non era più modificabile: public class BoardPanel extends JPanel {
     private Image backgroundImage;
     private String[][] gameMatrix;
     private List<String> tileTypes;
     private int tileSize = 58; // Dimensione della tessera
     int margin = 2;
 //TODO va resa cliccabile e va gestito l'update
     public BoardPanel(List<String> tileTypes) {
         setOpaque(false);
         initializeBackgroundImage();
         if (tileTypes != null) {
             this.tileTypes = tileTypes;
             initializeGameMatrix(tileTypes);
         } else {
             this.tileTypes = new ArrayList<>();
         }
     }

     private void initializeBackgroundImage() {
         backgroundImage = new ImageIcon(getClass().getResource("/Board/livingroom.png")).getImage();
     }

     private String getTileImageName(String tileType) {
         switch (tileType) {
             case "P":
                 return "Piante1.1.png";
             case "T":
                 return "Trofei1.1.png";
             case "G":
                 return "Giochi1.1.png";
             case "F":
                 return "Cornici1.1.png";
             case "C":
                 return "Gatti1.1.png";
             case "B":
                 return "Libri1.1.png";
             default:
                 return "Empty";
         }
     }
 //TODO Tessere vanno messe in maniera più precisa
     @Override
     protected void paintComponent(Graphics g) {
         super.paintComponent(g);
         g.drawImage(backgroundImage, 0, 0, getWidth(), getHeight(), this);

         if (gameMatrix != null) {
             int boardWidth = gameMatrix[0].length;
             int boardHeight = gameMatrix.length;

             int totalWidth = boardWidth * (tileSize + margin) - margin;
             int totalHeight = boardHeight * (tileSize + margin) - margin;

             int startX = (getWidth() - totalWidth) / 2;
             int startY = (getHeight() - totalHeight) / 2;

             for (int row = 0; row < boardHeight; row++) {
                 for (int col = 0; col < boardWidth; col++) {
                     String tileType = gameMatrix[row][col];
                     if (!tileType.equals("E")) {
                         String imagePath = "/ItemTile/" + getTileImageName(tileType);
                         try {
                             InputStream inputStream = getClass().getResourceAsStream(imagePath);
                             BufferedImage tileImage = ImageIO.read(inputStream);
                             Image scaledImage = tileImage.getScaledInstance(tileSize, tileSize, Image.SCALE_SMOOTH);

                             // Calcola le coordinate della casella nella matrice di gioco
                             int x = startX + col * (tileSize + margin);
                             int y = startY + row * (tileSize + margin);

                             // Disegna l'immagine della tessera nella casella corrispondente
                             g.drawImage(scaledImage, x, y, null);
                         } catch (IOException e) {
                             e.printStackTrace();
                         }
                     }
                 }
             }
         }
     }




     public void initializeGameMatrix(List<String> stringList) {
         int counter = 0;
         int boardSize = 9;
         gameMatrix = new String[boardSize][boardSize];

         for (int row = 0; row < gameMatrix.length; row++) {
             for (int col = 0; col < gameMatrix[row].length; col++) {
                 gameMatrix[row][col] = stringList.get(counter);
                 counter++;
             }
         }
     }
 } Soluzioni?