在 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.fill
是None
,则gbc.gridweightx
和gbc.gridweighty
没有意义。只有字段应该获得额外的空间 (fill == HORIZONTAL and weightx != 0
)
【讨论】:
你说的不是真的。如果你给一个组件额外的空间并修改约束的锚点,你会看到组件没有显示在某个位置。 你是对的,但这不是人们通常想要的。我应该用“没有用”而不是“没有意义”来表达。以上是关于在 Java 中使用 GridBagLayout 时防止 Swing 组件偏离中心的主要内容,如果未能解决你的问题,请参考以下文章
在 Java 中使用 GridBagLayout 时防止 Swing 组件偏离中心