2

我正在开发我的第一个 Java Swing 项目(实际上是我的第一个 GUI 项目,除非你算上客户端 Web 编程),但我遇到了审美问题。我正在 JPanel 中制作数独板。该面板采用 3x3 GridLayout 布局,其中包含 JPanel 的九个单元中的每一个都填充了另一个 3x3 GridLayout。外部网格具有较宽的边框来指示数独板的“框”,而内部网格具有较细的边框来显示“单元格”(如果您需要可视化的帮助,这里是一个屏幕截图)。

问题是我在内部和外部网格的边界之间获得了额外的空间,这看起来很糟糕。我尝试将插图显式设置为零,但没有做任何事情。我认为解决它的唯一方法是完全消除 GridLayout 嵌套,而是使用一个 9x9 网格,在适当的情况下将单个单元格边框设置为在顶部/底部/左侧/右侧更厚;但是,每个单元格的边框在获得焦点时都会改变颜色和粗细,我想不出一种优雅的方式来实施该策略。我也一直在研究其他布局,但 GridLayout 似乎非常适合这个目的(每个单元格应该是相同的大小)。

这是 BoardPanel 的构造函数(扩展 JPanel),我试图省略任何无关的代码:

BoardPanel(Board newBoardData)
{
    /**
     * Instance variable initializations, call to super(), etc. omitted.
     */     

    // Outer grid initialization
    // In pictures, .getBoxWidth() and .getBoxHeight both return (int)3
    setLayout(new GridLayout(boardData.getBoxWidth(), boardData.getBoxHeight(), 0, 0));
    setBorder(new LineBorder(colorGridBorders, 2));

    // Inner grid array; .getBoardSize() returns (int)9
    JPanel innerBoxGridPanels[] = new JPanel[boardData.getBoardSize()];
    GridLayout innerBoxGridLayout = new GridLayout(boardData.getBoxHeight(), boardData.getBoxWidth(), 0, 0);
    LineBorder innerBoxLineBorder = new LineBorder(colorGridBorders, 1);

    for (int columnIndex = 0; columnIndex < boardData.getBoardSize(); ++columnIndex)
    {
        for (int rowIndex = 0; rowIndex < boardData.getBoardSize(); ++rowIndex)
        {
            // CellPanel derives from JPanel; has a call to setBorder() to create inner grid lines
            cellPanes[columnIndex][rowIndex] = new CellPanel(columnIndex, rowIndex, boardData.getCell(columnIndex, rowIndex));
        }
    }

    for (int box = 0; box < boardData.getBoardSize(); ++box)
    {
        // Inner grid initialization
        innerBoxGridPanels[box] = new JPanel(innerBoxGridLayout);
        innerBoxGridPanels[box].setBorder(innerBoxLineBorder);

        // Adding cells to inner grid
        for (int cell = 0; cell < boardData.getBoardSize(); ++cell)
        {

            innerBoxGridPanels[box].add(cellPanes
                                [( cell % boardData.getBoxWidth() )
                                  + ( ( box % boardData.getBoxHeight() ) * boardData.getBoxWidth() )]
                                [( cell / boardData.getBoxWidth() )
                                  + ( (box / boardData.getBoxHeight() ) * boardData.getBoxHeight() ) ]);
        }

        // Adding inner grids to outer grid
        add(innerBoxGridPanels[box]);
    }
}

这是各种尺寸的渲染板的屏幕截图。在右上角的图像中,您可以看到,如果您将窗口大小调整得恰到好处,则可以消除大部分额外空间(尽管边缘仍有一些)。

有没有人在嵌套 GridLayouts 之前遇到过这种问题并找到了解决方案?任何帮助将不胜感激,我已经为此烦恼了一天多。

4

1 回答 1

3

似乎是窗口大小的问题。假设在外面板内水平有 2 个面板。外面板的边框大小为 2,内面板的边框大小为 1。

例如,如果窗口的大小为 18,我们有

  • 2px 外边框
  • 1px 内边框
  • 5px 用于面板内容
  • 1px 内边框
  • 1px 内边框
  • 5px 用于面板内容
  • 1px 内边框
  • 2px 外边框

所以没有空间,两个内板的尺寸相同

如果出于某种原因将窗口大小更改为 19,则需要在面板之间创建一个间隙以保持它们的大小相同。

如果大小为 20,则两个面板的大小都会 +1,并且不需要间隙。

要解决这个问题,您可以使用固定大小的窗口(您知道窗口没有间隙),或者在调整窗口大小时向外部面板添加填充,以便填充使框架的其余部分具有不产生差距。(在你的情况下,如果我的数学很好,应该是 20 + x/3)

如果要放弃使用嵌套面板并在获得焦点时更改单元格边框,则需要为每个单元格创建一个 LineBorder 实例。在您的代码中,所有单元格都使用相同的 LineBorder 实例。

于 2013-05-22T17:03:38.067 回答