Перерисовка доски в Java Swing - PullRequest
0 голосов
/ 19 марта 2020

Я пытаюсь реализовать игру. Это происходит на доске 9 на 9 и содержит стены и один блок пешек и пустых. Оба они являются подклассом GameObject. GameObject расширяет JLabel. Я сохраняю местоположение в массиве:

    GameObject[][] board = {
        {null,null,null,null,null,null,null,null,null},
        {null,null,null,null,null,null,null,null,null},
        {null,null,null,null,null,null,null,null,null},
        {null,null,null,null,null,null,null,null,null},
        {null,null,null,null,null,null,null,null,null},
        {null,null,null,null,null,null,null,null,null},
        {null,null,null,null,null,null,null,null,null},
        {null,null,null,null,null,null,null,null,null},
        {null,null,null,null,null,null,null,null,null},
};

Для каждого места в массиве я проверяю, какой GameObject должен быть помещен туда из строки, и помещаю его туда. Так что это означает, что там ничего не будет (Пусто), Стена или Пешка. Чтобы добавить GameObject (расширение JLabel) в мою JPanel, я использую следующий код:

for(int i = 0; i < 9; i++)
        {
            JPanel row = new JPanel(new GridLayout(1,9));
            for(int j = 0; j < 9; j++)
            {
                GameObject col = board[i][j];
                col.setHorizontalAlignment(JTextField.CENTER);
                col.setFont(new Font("SansSerif",Font.BOLD,20));
                col.setOpaque(true);
                col.setBackground(board[i][j].getColor());

                col.setBorder(BorderFactory.createLineBorder(Color.BLACK));
                row.add(col);
                int finalI = i;
                int finalJ = j;
            }
            row.setBorder(BorderFactory.createLineBorder(Color.BLACK));
            panel.add(row);
        }

Как только пользователь запросит ход, пешка будет размещена в другом месте на доске. Таким образом, текущее место в массиве установлено как пустое, а новое место - как пешка. Затем два квадрата должны быть перерисованы. Нужно нарисовать пустой JLabel и нарисовать новую позицию для Пешки. Это делается следующим образом:

board[pawn.getRow()][pawn.getCol()] = new Empty(board); //Old place is now empty
board[pawn.getRow()][pawn.getCol()].setBackground(Color.WHITE); //Set the old place color to white
pawn.movePawn(rowMove, colMove); //Move the pawn internally
board[pawn.getRow()][pawn.getCol()] = pawn; //Move the pawn on the board
board[pawn.getRow()][pawn.getCol()].setBackground(Color.BLUE); //Set the color to blue

К сожалению, ничего не происходит, когда я вызываю последний бит кода. Массив меняется, меняются внутренние координаты Пешки. Но в JPanel ничего не происходит. Как мне убедиться, что каждый раз, когда я вызываю функцию перемещения, мой JPanel обновляется, чтобы отразить это изменение?

1 Ответ

2 голосов
/ 19 марта 2020

Я сделаю ваш пример немного проще.

JLabel[][] labels = new JLabel[2][2];

Теперь есть 2D-массив с пространством для JLabels.

JPanel panel = new JPanel(new GridLayout(2, 2));
for(int i = 0; i<labels.length; i++){
    for(int j = 0; j<labels[i].length; j++){
        labels[i][j] = new JLabel(i + ", " + j);
        panel.add(labels[i][j]);
    }
}

Теперь я заполнил массив JLabels и добавили те же самые JLabels на панель.

labels[0][0].setText("XXX");

Это изменяет JLabel в моем массиве, чтобы иметь текст XXX, это также JLabel, который я добавил в свою JPanel, поэтому изменения будут отражены на экране.

labels[0][1] = new JLabel("XXX");

Изменения массива , указывающие на новую JLabel, не влияют на JLabel в JPanel. На экране вы не увидите никаких изменений.

Итак, что вы сделали:

board[pawn.getRow()][pawn.getCol()] = new Empty(board);
board[pawn.getRow()][pawn.getCol()].setBackground(Color.WHITE);

В массиве есть новый Empty, объект на панели вообще не был изменен. Затем вы устанавливаете цвет фона нового Пустого, но он нигде не отображается.

...