IndexOutOfBoundException и NullPointerException при обмене компонентами в GridLayout? - PullRequest
0 голосов
/ 26 октября 2019

Я столкнулся с некоторыми проблемами при создании игры-головоломки. (Вы можете поменять местами только номера приставок к кнопке «ПУСТО»). Она в основном делает то, что я хочу, но после нескольких нажатий кнопок выдает ошибку.

Проблема:

  1. При обменевниз или назад к предыдущему положению я получаю исключение NullPointerException, которое указывает на panel.remove(buttonTemp0);
  2. . При переключении пустой кнопки на край сетки я получаю исключение ArrayIndexOutOfBoundException, которое указывает на метод isSwappable.

Я почти уверен, что моя логика отключена ...

How the program looks

class GameTest extends JFrame implements ActionListener{

JPanel panel = new JPanel();
JButton[][] buttons = new JButton[4][4];
JButton button0 = new JButton("EMPTY");

public GameTest() {
    add(panel);
    setBackground(Color.RED);
    panel.setLayout(new GridLayout(4,4));
    int i = 1;
    for (int row = 0; row < buttons.length; row++) {
        for (int col = 0; col < buttons.length; col++ ) {
            if (row == 3 && col == 3) {
                buttons[row][col] = button0;
                panel.add(buttons[row][col]);
                buttons[row][col].setBackground(Color.WHITE);
                buttons[row][col].setName("button0");
            }
            else{
                buttons[row][col] = new JButton(i + "");
                panel.add(buttons[row][col]);
                buttons[row][col].addActionListener(this);
                buttons[row][col].setBackground(Color.RED);
                buttons[row][col].setName("button" + i);
                buttons[row][col].setFont(new Font("Arial", Font.PLAIN, 30));
                i++;
            }
        }
    }
    setCursor(new Cursor(Cursor.HAND_CURSOR));
    setResizable(false);
    setLocation(500,200);
    setSize(400,400);
    setVisible(true);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
}

public boolean isSwappable(JButton button) {

    int sourceRow = 0;
    int sourceCol = 0;
    int blankRow = 0;
    int blankCol = 0;

    // to find position of empty and clicked button
    for (int row = 0; row < buttons.length; row++) {
        for (int col = 0; col < buttons.length; col++ ) {
            if (buttons[row][col] == button) {
                sourceRow = row;
                sourceCol = col;
            }
            else if (buttons[row][col] == button0) {
                blankRow = row;
                blankCol = col;
            }
        }
    }
     //if it is to the right
    if ( sourceRow == blankRow && buttons[sourceRow][sourceCol + 1] == button0) {
        return true;
    }
    // if it is to the left
    else if (sourceRow == blankRow && buttons[blankRow][sourceCol - 1] == button0) {
        return true;
    }
    //if below
    else if (sourceCol == blankCol && buttons[sourceRow - 1][sourceCol] == button0) {
        return true;
    }
    //if above
    else if ( sourceCol == blankCol && buttons[sourceRow + 1][sourceCol] == button0) {
        return true;
    }

    return false;
}

@Override
public void actionPerformed(ActionEvent e) {
    JButton source = (JButton)e.getSource();
    if (isSwappable(source)) {
        int x = 0;
        int y = 0;
        JButton buttonTemp = null;
        JButton buttonTemp0 = null;
        for (int row = 0; row < buttons.length; row++) {
            for (int col = 0; col < buttons.length; col++) {
                if (buttons[row][col] == source) {
                    buttonTemp = source;
                    buttonTemp0 = button0;
                    x = row;
                    y = col;
                }
                if (buttons[row][col] == button0) {
                    buttons[row][col] = buttonTemp;
                    buttons[x][y] = buttonTemp0;
                    int index0 = (x * 4) + y;
                    int index =(row * 4) + col;
                    panel.remove(source);
                    panel.remove(buttonTemp0);
                    panel.add(button0,index0);
                    panel.add(source,index);
                    revalidate();
                    repaint();

                    int som = 0;
                    for (int i = 0; i < buttons.length; i++) {
                        for (int j = 0; j < buttons.length; j++) {
                            System.out.println(som + ": " + buttons[i][j].getName());
                            som++;
                        }
                    }
                }
            }
        }
    }
  }
}

1 Ответ

0 голосов
/ 26 октября 2019

Теперь решено!

class GameTest extends JFrame implements ActionListener{

JPanel panel = new JPanel();
JButton[][] buttons = new JButton[4][4];
JButton button0 = new JButton("EMPTY");
int emptyIndex;
int sourceIndex;
int sourceRow;
int sourceCol;
int blankRow;
int blankCol;

public GameTest() {
    add(panel);
    setBackground(Color.RED);
    panel.setLayout(new GridLayout(4,4));
    int i = 1;
    for (int row = 0; row < buttons.length; row++) {
        for (int col = 0; col < buttons.length; col++ ) {
            if (row == 3 && col == 3) {
                buttons[row][col] = button0;
                panel.add(buttons[row][col]);
                buttons[row][col].setBackground(Color.WHITE);
                buttons[row][col].setName("button0");
            }
            else{
                buttons[row][col] = new JButton(i + "");
                panel.add(buttons[row][col]);
                buttons[row][col].addActionListener(this);
                buttons[row][col].setBackground(Color.RED);
                buttons[row][col].setName("button" + i);
                buttons[row][col].setFont(new Font("Arial", Font.PLAIN, 30));
                i++;
            }
        }
    }
    setCursor(new Cursor(Cursor.HAND_CURSOR));
    setResizable(false);
    setLocation(500,200);
    setSize(400,400);
    setVisible(true);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
}

public boolean isSwappable(JButton button) {



    // för att hitta platsen på knappen man trycker och även den blanka platsen
    for (int row = 0; row < buttons.length; row++) {
        for (int col = 0; col < buttons.length; col++ ) {
            if (buttons[row][col] == button) {
                sourceRow = row;
                sourceCol = col;
            }
            else if (buttons[row][col] == button0) {
                blankRow = row;
                blankCol = col;
            }
        }
    }
    sourceIndex = (sourceRow * 4) + sourceCol;
    emptyIndex = (blankRow * 4) + blankCol;
    // om den är till höger
    if ( sourceCol != 3 && sourceRow == blankRow && buttons[sourceRow][sourceCol + 1] == button0) {
        return true;
    }
    // om den är till vänster
    else if (sourceCol != 0 && sourceRow == blankRow && buttons[blankRow][sourceCol - 1] == button0) {
        return true;
    }
    //om den är nedanför
    else if (sourceRow != 0 && sourceCol == blankCol && buttons[sourceRow - 1][sourceCol] == button0) {
        return true;
    }
    //om den är ovanför
    else if (sourceRow != 3 && sourceCol == blankCol && buttons[sourceRow + 1][sourceCol] == button0) {
        return true;
    }




    return false;
}

@Override
public void actionPerformed(ActionEvent e) {
    JButton source = (JButton)e.getSource();
    System.out.println(isSwappable(source));
    if (isSwappable(source)) {



        JButton tempButton = buttons[sourceRow][sourceCol];
        buttons[sourceRow][sourceCol] = buttons[blankRow][blankCol];
        buttons[blankRow][blankCol] = tempButton;

        if (emptyIndex < sourceIndex){
            panel.remove(button0);
            panel.remove(source);
            panel.add(source, emptyIndex);
            panel.add(button0, sourceIndex);
            revalidate();
            repaint();
        }
        else if (emptyIndex > sourceIndex){
            panel.remove(button0);
            panel.remove(source);
            panel.add(button0, sourceIndex);
            panel.add(source, emptyIndex);
            revalidate();
            repaint();
        }

    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...