努力在 Swing 中创建不均匀的网格

问题描述 投票:0回答:1

我有一个工作应用程序,它使用

GridLayout
制作 2 x 2 网格,每个网格包含一个
JPanel

GridLayout
工作得很好,我只是做了
mainPanel.setLayout(new GridLayout(2, 2))
,一切都很顺利。

但是,我注意到我的两个组件在网格内部(水平方向)有点狭窄。我知道我可以将布局交换为使用

CardLayout
或其他东西,但我正在构建的应用程序更像是一个仪表板,因此,同时查看所有元素是相当重要的。水平空间的缺乏是为了最大化窗口,所以最大化不是一个选择。

好吧,事实证明,其他 2 个组件有多余的水平空间,所以我心想,“为什么我不将 2 个大组件移到同一列,将 2 个小组件移到另一列,然后调整列的大小,以便它们都有所需的足够空间?”

这是我的意思的简单视觉表示。

事实证明,

GridLayout
(可以理解)不提供此功能,因此我决定循环浏览本教程中列出的不同 Swing 布局。在所有布局中,GridBagLayout 似乎最适合我的需求。

所以,我看了一下GridBagLayout

教程。我的第一个目标是重新创建我已经拥有的 
GridLayout
,然后操纵该解决方案,直到它看起来像我需要的。

这是我的第一次天真的尝试。这是浏览完教程后的结果。

import java.awt.*;
import javax.swing.*;

public class GUI
{

    private final JFrame frame = new JFrame();

    public GUI()
    {

        this.frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.frame.setExtendedState(JFrame.MAXIMIZED_BOTH);

        this.frame.add(createPanel());

        this.frame.setVisible(true);

    }

    private static JPanel createPanel()
    {

        final JPanel grid = new JPanel();
        grid.setBorder(BorderFactory.createLineBorder(Color.MAGENTA));

        final java.util.function.Supplier<JPanel> createButtonGrid =
         () ->
         {

            final JPanel buttonGrid = new JPanel(new java.awt.GridLayout(4, 4));

            for (int i = 0; i < 16; i++)
            {

               buttonGrid
                  .add
                  (
                     new
                        JButton
                        (
                           """
                           <html>
                           THIS IS BUTTON TEXT<br>
                           THIS IS BUTTON TEXT<br>
                           THIS IS BUTTON TEXT<br>
                           THIS IS BUTTON TEXT
                           </html>
                           """
                        )
                  );

            }

            return buttonGrid;

         };

        TOP_LEFT:
        {

            final GridBagConstraints c = new GridBagConstraints();

            c.gridx = 0;
            c.gridy = 0;

            final JPanel tempPanel = createButtonGrid.get();
            tempPanel.setBorder(BorderFactory.createLineBorder(Color.RED));
            grid.add(tempPanel, c);

        }


        TOP_RIGHT:
        {

            final GridBagConstraints c = new GridBagConstraints();

            c.gridx = 1;
            c.gridy = 0;

            final JPanel tempPanel = createButtonGrid.get();
            tempPanel.setBorder(BorderFactory.createLineBorder(Color.ORANGE));
            grid.add(tempPanel, c);

        }

        BOTTOM_LEFT:
        {

            final GridBagConstraints c = new GridBagConstraints();

            c.gridx = 0;
            c.gridy = 1;

            final JPanel tempPanel = createButtonGrid.get();
            tempPanel.setBorder(BorderFactory.createLineBorder(Color.GREEN));
            grid.add(tempPanel, c);

        }

        BOTTOM_RIGHT:
        {

            final GridBagConstraints c = new GridBagConstraints();

            c.gridx = 1;
            c.gridy = 1;

            final JPanel tempPanel = createButtonGrid.get();
            tempPanel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
            grid.add(tempPanel, c);

        }

        return grid;

    }

}

当我运行这个时,事情已经与预期有点不同了。所有组件都在中间被挤压。

GridLayout
确保每个组件占据所有可用的垂直和水平空间。如果我要使用
GridBagLayout
,我需要这个。毕竟,我切换到
GridBagLayout
的全部原因是为了能够挤出更多一点水平宽度。我现在所拥有的只是倒退了一步。

所以,我再次仔细阅读了教程,这次彻底地阅读了以下引用。

填充

当组件的显示区域大于组件请求的大小时使用,以确定是否以及如何调整组件的大小。有效值(定义为 GridBagConstraints 常量)包括 NONE(默认值)、HORIZONTAL(使组件足够宽以水平填充其显示区域,但不更改其高度)、VERTICAL(使组件足够高以垂直填充其显示区域) ,但不改变其宽度),以及 BOTH(使组件完全填满其显示区域).

读到这里,我尝试为每个组件添加一个

c.fill = GridBagConstraints.BOTH;
。然而,结果是100%相同的。第一个版本和第二个版本没有区别。

第二次阅读时,我注意到以下引用。

GridBagLayout 将组件放置在行和列的网格中,允许指定的组件跨越多行或多列。并非所有行都必须具有相同的高度。同样,并非所有列都必须具有相同的宽度。本质上,GridBagLayout 将组件放置在网格中的矩形(单元格)中,然后 然后使用组件的首选大小来确定单元格应该有多大

读到这里,我开始尝试不同的首选尺寸。这确实产生了影响,但并不完全是我想要的。现在我的 GUI 无法正确调整大小。我提供的 PreferredSize 是组件所保持的大小。我需要我的组件占据所有水平空间。如果我的显示区域尺寸增大或减小,我需要我的组件随之增大或减小,同时保持彼此的比例。

因此,我尝试再次重读教程并发现以下引用。

例如,要让按钮4变得特别高,示例中有这样的代码:

c.ipady = 40;

所以,我尝试了ipadx,但它没有改变任何东西。它看起来和我的前两次尝试一样。

最后,我尝试再次重读教程,但似乎没有其他方法适合我的解决方案。

有什么建议吗?

java swing awt grid-layout gridbaglayout
1个回答
0
投票

我重新创建了你的 GUI 以获得以下内容。

当您展开窗口时,组件也会展开。

所有 Swing 应用程序都必须以调用

SwingUtilities
invokeLater
方法开始。此方法确保 Swing 组件在 Event Dispatch Thread 上创建并执行。

每个人

JPanel
使用
GridBagLayout
。主要
JPanel
使用
GridBagLayout

这是完整的可运行代码。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class GridBagLayoutTest5 implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new GridBagLayoutTest5());
    }

    @Override
    public void run() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createMainPanel(), BorderLayout.CENTER);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel createMainPanel() {
        JPanel panel = new JPanel(new GridBagLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;

        gbc.gridx = 0;
        gbc.gridy = 0;
        panel.add(createButtonPanel(Color.BLUE,
                "This is really long button text"), gbc);

        gbc.gridx++;
        panel.add(createButtonPanel(Color.RED, "This is button text"), gbc);

        gbc.gridx = 0;
        gbc.gridy++;
        panel.add(createButtonPanel(Color.BLUE,
                "This is really long button text"), gbc);

        gbc.gridx++;
        panel.add(createButtonPanel(Color.RED, "This is button text"), gbc);

        return panel;
    }

    private JPanel createButtonPanel(Color color, String text) {
        JPanel panel = new JPanel(new GridBagLayout());
        panel.setBorder(BorderFactory.createLineBorder(color, 5));
        
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;

        for (int index = 0; index < 16; index++) {
            gbc.gridx = index % 4;
            gbc.gridy = index / 4;
            panel.add(createTextButton(text), gbc);
        }

        return panel;
    }

    private JButton createTextButton(String text) {
        String s = "<html>" + text + "<br>" + text + "<br>";
        s += text + "<br>" + text + "<br></html>";
        JButton button = new JButton(s);
        return button;
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.