【问题标题】:Need help moving the buttons using JPanel GridLayout in Java? [duplicate]需要帮助在 Java 中使用 JPanel GridLayout 移动按钮? [复制]
【发布时间】:2021-01-04 13:22:18
【问题描述】:

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

我目前遇到的问题。

我希望它看起来像什么。

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);
}

【问题讨论】:

  • @Abre 对您的previous question 的回答有什么问题?
  • @GilbertLeBlanc 我需要它与我的 PanelCell 类一起工作,因为它有一个 KeyListener 允许您输入 1 到 5 之间的数字。实例变量 cells 也用于我的clear 方法开始一个新的游戏。所以我不想删除我已经为游戏创建的功能。
  • 我需要它与我的 PanelCell 类一起使用 - 然后修改方法以使用您的 PanelCell 类。我们不知道 PanelCell 类是什么,那么您希望我们如何告诉您如何使用它?我们所能做的就是提供根据您的图片布置组件的方法,这已在您的上一个问题中完成。

标签: java swing jpanel


【解决方案1】:

我猜你的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));
        }      
    }
}

现在您有一个 PanelCells 数组,可以包含 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 实例。

【讨论】:

  • 它显示得很好,我只是在努力让 PanelCell 类工作,因为我收到一个错误Index 6 out of bounds for length 5。对于上一个示例的第一个 if 语句,我添加了 cells[row][col] = new PanelCell(this,row,col); grid.add(cells[row][col]); 但似乎没有将数字分配到单元格 @GameDroids
  • 您现在正在循环 9 行 (0-8) 和每行 9 列(也是 0-8),因此当它想在第 6 行添加一个新单元格时它会失败,因为数组初始化只有 5 行。现在取决于什么最适合您:要么将网格中的所有单元格存储在网格数组中(很好但不必要),要么确保您的 cell 数组填充了正确的索引:cells[row/2][col/2]= new PanelCell(...) 它会“映射" 你的 grid 索引到你的每个 PanelCell 的 cell 索引
  • 好的,谢谢我也为我的清晰方法添加了这个。当我可以为所有数字单元格分配一个数字时,我遇到了另一个问题,因为我收到错误`线程“AWT-EventQueue-0”中的异常FutoshikiException:无效行(0)`,但我认为这需要是一个新的问题@GameDroids
猜你喜欢
  • 2020-03-11
  • 2015-06-11
  • 2021-11-24
  • 2019-08-08
  • 2019-01-25
  • 2014-08-11
  • 1970-01-01
  • 2020-11-12
  • 1970-01-01
相关资源
最近更新 更多