在 GridLayout 中交换组件时出现 IndexOutOfBoundException 和 NullPointerException?
IndexOutOfBoundException and NullPointerException when swapping components in a GridLayout?
我在创建 15 人益智游戏时 运行 遇到了一些问题。 (你只能将相邻数字交换到 "EMPTY" 按钮)它主要是做我想做的,但在点击几次按钮后它给了我一个错误。
问题:
- 当向下或返回到之前的位置时,我得到
指向
panel.remove(buttonTemp0);
的 NullPointerException
- 当将空白按钮交换到网格边缘时,我得到一个指向
isSwappable
方法的 ArrayIndexOutOfBoundException。
我很确定我的逻辑不对...
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++;
}
}
}
}
}
}
}
}
现已解决!
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();
}
}
}
}
我在创建 15 人益智游戏时 运行 遇到了一些问题。 (你只能将相邻数字交换到 "EMPTY" 按钮)它主要是做我想做的,但在点击几次按钮后它给了我一个错误。
问题:
- 当向下或返回到之前的位置时,我得到
指向
panel.remove(buttonTemp0);
的 NullPointerException
- 当将空白按钮交换到网格边缘时,我得到一个指向
isSwappable
方法的 ArrayIndexOutOfBoundException。
我很确定我的逻辑不对...
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++;
}
}
}
}
}
}
}
}
现已解决!
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();
}
}
}
}