在 Java 中使用 GridBagLayout 时防止 Swing 组件偏离中心

Posted

技术标签:

【中文标题】在 Java 中使用 GridBagLayout 时防止 Swing 组件偏离中心【英文标题】:Preventing Swing Components from Becoming Off-Centered when using GridBagLayout in Java 【发布时间】:2017-08-04 18:14:08 【问题描述】:

我正在尝试使用 Java 中的 Swing 组件制作一个简单的 GUI。但是,由于其他组件的尺寸,一些组件会偏离中心。我正在使用 GridBagConstraints.CENTER 将这些组件居中,但似乎仅相对于它们所在的 Grid 单元格使它们居中。

我遇到的具体问题如下图所示。我需要“文件名:”旁边的 JTextField 具有一定的长度。但是,当我将其设为一定长度时,它会导致其他行中的其他组件偏离中心。保持所有组件居中的唯一方法似乎是让两个 JTextField 的长度相同。

总的来说,我对 Swing 和 Java GUI 有点陌生,所以我可能缺少一些基本概念,但我还没有从我的搜索中找到这个特定问题的答案。

Image Showing the Components becoming Off-Centered when the JTextField length changes

>

//Initialize global Swing objects
JFrame frame = new JFrame("Game Server V2.0 build 019827427");
JPanel panel = new JPanel();
JButton runButton = new JButton("Start Server");
JButton stopButton = new JButton("Stop Server");
JButton sendButton = new JButton("Send File");
JTextField portField = new JTextField("999", 5);
JTextField fileField = new JTextField("fileToSend.txt", 14);
JLabel portLabel = new JLabel("Port:  ");
JLabel fileLabel = new JLabel("File Name:  ");
JLabel statusLabel = new JLabel("Status: Disconnected");

public void run()

    //Set layout and constraints
    panel.setLayout(new GridBagLayout()); 
    GridBagConstraints gc = new GridBagConstraints();

    //Add Swing components to panel using GridBagLayout with the GridBagConstraints we've specified
    gc.weightx = 0.5;
    gc.weighty = 0.5;

    gc.gridx = 0;
    gc.gridy = 0;
    gc.gridwidth = 1;
    gc.anchor = GridBagConstraints.LINE_END;
    panel.add(portLabel, gc);

    gc.gridx = 1;
    gc.gridy = 0;
    gc.gridwidth = 1;
    gc.anchor = GridBagConstraints.LINE_START;
    panel.add(portField, gc); 

    gc.gridx = 0;
    gc.gridy = 1;
    gc.gridwidth = 1;
    gc.anchor = GridBagConstraints.LINE_END;
    panel.add(fileLabel, gc);

    gc.gridx = 1;
    gc.gridy = 1;
    gc.gridwidth = 1;
    gc.anchor = GridBagConstraints.LINE_START;
    panel.add(fileField, gc);

    gc.gridx = 0;
    gc.gridy = 2;
    gc.gridwidth = 2;
    gc.anchor = GridBagConstraints.CENTER;
    panel.add(sendButton, gc);

    gc.gridx = 0;
    gc.gridy = 3;
    gc.gridwidth = 1;
    panel.add(runButton, gc);

    gc.gridx = 1;
    gc.gridy = 3;
    gc.gridwidth = 1;
    panel.add(stopButton, gc);

    gc.gridx = 0;
    gc.gridy = 4;
    gc.gridwidth = 2;
    panel.add(statusLabel, gc);

    frame.add(panel);
    frame.setSize(480, 280);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);


【问题讨论】:

GridBagContraints.CENTER 正是为此而设计的:将单元格中的组件中心(垂直和水平)居中。 您应该将 frame.setSize 替换为 frame.pack()。您的 GridBagLayout 没有足够的空间来布置您的组件。 but it seems to keep them centered only relative to the Grid cell that they are contained within. - 正确,组件位于单元格内。我不知道“居中”对您意味着什么。绘制一个 ascii 图,显示您希望组件如何显示。也许您希望在单元格的左边缘显示“开始”按钮,在右边缘显示“停止”按钮? 我想我真正想要的是两列单元格的宽度相等,而不是根据内容而变化。在我的具体示例中,尽管单元格中有足够的空间供 JTextField 占用,但由于 JTextField 右列正在加宽。我不确定这是为什么。 1) 为了尽快获得更好的帮助,请发帖 minimal reproducible example 或 Short, Self Contained, Correct Example。 2) 提示:添加@camickr(或重要的@)以通知该人有新评论。 【参考方案1】:

我想我真正想要的是两列单元格的宽度相等,

因此,您应该在各自的列中拥有“开始”和“停止”按钮。然后应该有一个 1.0 的 weightx 以允许然后扩展。它们应该居中。

注意:它们不会完全居中,因为开始按钮的宽度会比停止按钮稍大,因此会有一些额外的像素空间。

对于所有其他数据行,您需要为每一行添加一个组件。然后每个组件需要一个 2 的网格宽度。每个组件都将居中。由于前两行包含两个组件,您需要创建一个面板并将组件添加到面板中。然后使用 GridBagLayout 将面板添加到面板中。

【讨论】:

【参考方案2】:

如果gbc.fillNone,则gbc.gridweightxgbc.gridweighty 没有意义。只有字段应该获得额外的空间 (fill == HORIZONTAL and weightx != 0)

【讨论】:

你说的不是真的。如果你给一个组件额外的空间并修改约束的锚点,你会看到组件没有显示在某个位置。 你是对的,但这不是人们通常想要的。我应该用“没有用”而不是“没有意义”来表达。

以上是关于在 Java 中使用 GridBagLayout 时防止 Swing 组件偏离中心的主要内容,如果未能解决你的问题,请参考以下文章

在 Java 中使用 GridBagLayout 时防止 Swing 组件偏离中心

Java GridBagLayout 不起作用

Java gridbaglayout 使用带有可拖动 jpanel 的滚动窗格

Java GridBagLayout组件不会到达指定位置

GridBagLayout Java 中的边距/填充

谁能解释一下Java中GridBagLayout的使用?