【问题标题】:JComponents getting smaller in GridLayoutGridLayout 中的 JComponents 越来越小
【发布时间】:2022-01-05 01:25:00
【问题描述】:

我正在尝试创建 Game of Life 类型的应用程序,但在绘制单元格时遇到了一些问题。我有一个大的JPanel (RectGridPanel) 作为模拟的基础,在那个面板上我通过在GridLayout 中添加更小的面板(GridElement) 来绘制一个网格。然后我尝试将我的单元格添加到这些较小的面板中。

import java.awt.Dimension;
import java.awt.Color;
import java.awt.event.*;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import javax.swing.BorderFactory;
import javax.swing.JPanel;

public class GridElement extends JPanel
{
    
    public GridElement()
    {
        this.setLayout(new BorderLayout());
        
        this.setMinimumSize(new Dimension(40, 40));
        
        this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
    }
    
    public void createCell()
    {
        Cell newCell = new RectCell();
        this.add(newCell, BorderLayout.CENTER);
    }
}
import java.awt.*;

public class RectCell extends JPanel
{
    
    public RectCell()
    {
        
        this.setPreferredSize(new Dimension(40, 40));
        
        this.setBackground(Color.BLUE);
    }
}
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.awt.Graphics;

public class RectGridPanel extends JPanel
{   
    public RectGridPanel()
    {
        this.setPreferredSize(new Dimension(840, 800));
        
        this.setLayout(new GridLayout(20,21));
        
        for(int x = 0; x < 21; x++)
        {
            for(int y = 0; y < 20; y++)
            {
                GridElement element = new GridElement();
                element.createCell();
                this.add(element);
            }
        }
    }   
}

我想要实现的是我的单元格(蓝色)填充了我创建的所有 GridElement 组件,但实际上,单元格的颜色越远离左上角,其尺寸就越小:

【问题讨论】:

  • 一般情况下,您创建一个绘图JPanel 并绘制您的单元格。 Oracle 教程Performing Custom Painting 将向您展示如何操作。你可以看看这个版本的Conway's Game of Life
  • 如需更好的帮助,请edit添加minimal reproducible example
  • 顺便说一句:我有一些空闲时间,所以在这里把它变成了可运行的代码(一个 MRE)。在编译之前需要修复一个编译错误(Cell newCell = new RectCell(); -> RectCell newCell = new RectCell();),然后..对我来说似乎很好。这是how it appears shrunken down注意: 为避免浪费您的时间,更重要的是浪费他人免费帮助的时间,请务必检查您的 MRE 代码是否真正显示错误。
  • 是的,没有注意到,但这只是我在减少代码方面的错误(RectCell 扩展了单元格)。这也正是我正在寻找的行为,但我的看起来仍然受到干扰。
  • 1) 你有太多级别的组件。您只需要一个“GridCell”来表示每个组件和一个“GridPanel”来保存网格布局中的所有 GridCell。我猜是因为您有一个包含一个面板的面板,该面板包含一个您有布局问题的面板。 2) 不要在“GridPanel”上使用setPreferredSize()。布局管理器将根据添加到面板的组件确定大小。

标签: java swing awt


【解决方案1】:

如前所述,在使用 GridLayout 时嵌套具有这么多级别的组件并定义大小是没有意义的。 蓝色矩形的移动是由您未发布的代码引起的。似乎变量 x 和 y 对没有意义的位置有影响。 这是一个几乎 MRB,您的第一个目标是多么容易实现:

    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    JPanel basePanel = new JPanel(new GridLayout(20,21));
    int cols = 21, rows = 20;
    Dimension dimension = new Dimension(30, 30);

    for (int i=0; i<rows*cols; i++) {
        final int number = i;
        JPanel square = new JPanel(new BorderLayout()) {
            {
                this.setBackground(Color.BLUE);
                this.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
                this.add(new JLabel(String.valueOf(number), SwingConstants.CENTER));
                this.setPreferredSize(dimension);
            }
        };
        basePanel.add(square);
    }

    frame.add(basePanel, BorderLayout.CENTER);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}

代替用于定义图块的匿名内部类,您可以将其提取到自己的扩展 JPanel 的类中。

【讨论】:

  • 如前所述,在使用 GridLayout 时定义尺寸是没有意义的。它与 GridLayout 无关。它适用于所有布局管理器。不要使用 setBounds()。您不知道框架的大小应该是多少,因为您不知道 LAF 的装饰(边框、标题栏)的大小。您刚刚破坏了使用布局管理器的目的。相反,您应该在使其可见之前pack() 框架(并且在所有组件都已添加到框架之后。
  • 是的,正确的。旧习惯,因为我只使用未装饰的框架。更改了代码,以便“空”方块(删除用于演示的标签时)和框架获得首选大小并在运行时显示。
  • 即使您使用未装饰的框架,您也不应该设置大小/边界。 pack() 方法将为您完成工作。
猜你喜欢
  • 1970-01-01
  • 2018-01-28
  • 2020-06-06
  • 1970-01-01
  • 2016-01-16
  • 1970-01-01
  • 2016-03-05
  • 2014-05-02
  • 1970-01-01
相关资源
最近更新 更多