GridLayout 中的 JComponents 越来越小

Posted

技术标签:

【中文标题】GridLayout 中的 JComponents 越来越小【英文标题】:JComponents getting smaller in GridLayout 【发布时间】: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()。布局管理器将根据添加到面板的组件确定大小。 【参考方案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() 方法将为您完成工作。

以上是关于GridLayout 中的 JComponents 越来越小的主要内容,如果未能解决你的问题,请参考以下文章

Kivy:GridLayout 中的按钮有间隙

GridLayout中的Nativescript垂直对齐不起作用

如何更新或读取 TabView 中的 GridLayout 内的文本字段

如何使用 kv 文件刷新 Kivy 中的 GridLayout

NestedScrollView 中的 GridLayout ,为啥我的列会超出视图空间?

如何正确使用 QQuickItem::stackBefore() 重新排序 GridLayout 中的项目?