需要帮助在 Java 中使用 JPanel GridLayout 移动按钮吗?

问题描述

我想移动我的 GUI 游戏的按钮,它是一个 9x9 网格,因此按钮如下图所示。我已经很努力了,但还是想不通。

我目前遇到的问题。

enter image description here

我想要的样子。

enter image description here

public FutoshikiGUI()
{        
    grid  = new JPanel(new GridLayout(0,9));
    cells = new PanelCell[5+1][5+1];     
    
    for (int row=1; row<=5; row++) 
    {
        for (int col=1; col<=5; coL++)
        {
            // number input
            cells[row][col] = new PanelCell(this,row,col);
            grid.add(cells[row][col]); 
            if(col < 5)
            {
               // relation input 
              JButton button = new JButton("");
              button.setBackground(Color.white);
              button.setopaque(true);
              button.setBorder(new LineBorder(Color.BLACK));
              grid.add(button);
            }      
        }
    }
   
    for (int row=1; row<=4; row++) 
    {
        for (int col=1; col<=5; coL++)
        {
            // relation input
            JButton btn = new JButton("");
            btn.setBackground(Color.white);
            btn.setopaque(true);
            btn.setBorder(new LineBorder(Color.BLACK));
            grid.add(btn);
            if(col < 5)
            { 
              // blank input 
              JButton button = new JButton("");
              button.setBackground(Color.darkGray);
              button.setopaque(true);
              button.setBorder(new LineBorder(Color.BLACK));
              grid.add(button);
            }      
        }
    }
    setLayout(new BorderLayout());
    add(grid,BorderLayout.norTH);
}

解决方法

我猜您的 PanelCell 对象是“蓝色”单元格,而“白色”单元格是具有 white 背景的按钮,灰色单元格是具有 darkGray 背景颜色的按钮.

首先(为了让你的代码更容易维护)我建议你创建一个简单的“工厂方法”来创建你的按钮:

public static JButton createButton(Color background) {
    JButton button = new JButton("");
    button.setBackground(background);
    button.setOpaque(true);
    button.setBorder(new LineBorder(Color.BLACK));
    return button;
}

此方法包含重复三遍的冗余代码(但您只更改背景颜色)。所以把它放在一个方法里,把背景颜色作为参数传递会更容易。

现在你的代码看起来像这样(我缩短了格式):

for (int row=1; row<=5; row++){
    for (int col=1; col<=5; col++){
        cells[row][col] = new PanelCell(this,row,col);
        grid.add(cells[row][col]); 
        if(col < 5){
          grid.add(createButton(Color.white));  // I just replaced your code with the method call to create the button instance
        }      
    }
}

for (int row=1; row<=4; row++) {
    for (int col=1; col<=5; col++){
        grid.add(createButton(Color.white));
        if(col < 5){ 
          grid.add(createButton(Color.darkGray));
        }      
    }
}

现在您有一个 PanelCell 数组,可以包含 6 行和 6 列。然而,您的 for 循环从索引 1 开始,这意味着实际上您的数组在第一行中将没有单元格。
始终以索引 0 开始 for 循环,并让它们在数组的“长度”处结束 - 这样就不会再发生这些错误。

cells = new PanelCell[5][5];  // in your image I only see 5 "blue" cells in a row and 5 columns in each row

for(int row=0; row<cells.length; row++){   // you already initialised the array to have 5 rows
   for(int col=0; col<cells[row].length; col++){  // now you can be sure that all cells are iterated over once (each row and each column)
     // ...
   }
 }

所以你每次迭代超过 5 行和 5 列。您将新的 PanelCell 添加到您的网格中,并且(对于前 4 列)您添加了一个白色按钮。
问题来了
创建前 25 个单元格后,您再次迭代 4 行 5 列并添加白色和灰色按钮。所以最后你的网格包含 5 行带有蓝色和白色按钮的行和 4 行带有灰色和白色按钮的行。

所以你必须想办法以正确的顺序填充你的网格。这是一个示例,说明如何在不维护元胞数组的情况下执行此操作:

for(row=0; row<9; row++){     // your grid should contain 9 rows 
   for(col=0; col<9; col++){  // and 9 columns in each row
      if(row%2==0){           // your blue buttons are only in "even" rows (0,2,4,6,8)
         if(col%2==0){        // in even rows your blue buttons are only in even columns
            grid.add(new PanelCell(...));  // create your PanelCell
         }else{
            grid.add(createButton(Color.white)); // in "uneven" columns you add a white button)
         }
      }else{                  // in uneven rows you have white buttons in even columns and gray buttons in uneven columns
          if(col%2==0){        
            grid.add(createButton(Color.white));  // create a white button
         }else{
            grid.add(createButton(Color.darkGray)); // create a gray button
         }
      }
    }
 }

现在这应该可以工作了。上面的代码只是一个例子,应该正确填充你的“网格”,但是它没有考虑如何处理你的“单元格”数组或创建 PanelCell 实例。