gpt4 book ai didi

java - GridBagLayout 不稳定的调整大小和显示

转载 作者:行者123 更新时间:2023-12-01 11:29:55 24 4
gpt4 key购买 nike

我正在制作一个在容器中使用 GridBagLayout 的程序。我的主要用途是有两个 JPanel,它们分别占据窗口水平空间的 75% 和 25%。但出于某种原因,两个面板看起来更像 90/10,并且在调整大小时,较小的面板的尺寸会迅速变化,介于其明显的最小尺寸和我认为所需的 25% 之间。

这是相关代码。

frmReedreadV = new JFrame();
frmReedreadV.setBounds(x, y, width, height);
frmReedreadV.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmReedreadV.getContentPane().setLayout(new BoxLayout(frmReedreadV.getContentPane(), BoxLayout.Y_AXIS));

JPanel stretchyPanel = new JPanel();
frmReedreadV.getContentPane().add(stretchyPanel);
stretchyPanel.setLayout(new CardLayout(0, 0));

JPanel textAndUsers = new JPanel(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;

gbc.weighty = 1;

textArea = new JTextArea();
textArea.setMargin(new Insets(2, 5, 5, 2));
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.setEditable(false);

scrollPane = new JScrollPane(textArea);
scrollPane.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));

gbc.weightx = 0.8;
textAndUsers.add(scrollPane, gbc);

list = new FriendsList(listUpdate);

gbc.weightx = 0.2;
textAndUsers.add(list.frmUserList, gbc);

stretchyPanel.add(textAndUsers);

FriendsList 是 JPanel 中包含的 JList。

主 CardLayout 内容 Pane 中还有其他按钮和文本字段,但这些不应影响此 GridBagLayout 内部的内容,对吗?

我制作了这个 JPanel 的另一个副本作为独立应用程序,它可以完美地显示和调整大小。请参阅此处:

JFrame frame = new JFrame();
frame.getContentPane().setLayout((new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS)));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 550, 600);

JPanel stretchyPane = new JPanel();
frame.getContentPane().add(stretchyPane);
stretchyPane.setLayout(new CardLayout(0, 0));

JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();

JTextArea text = new JTextArea();
text.setMargin(new Insets(2, 5, 5, 2));
JScrollPane panel1 = new JScrollPane(text);
FriendsList panel2 = new FriendsList(new Object());

c.fill = GridBagConstraints.BOTH;
c.weightx = .8;
c.weighty = 1;
panel.add(panel1, c);
c.weightx = .2;
//c.fill = GridBagConstraints.HORIZONTAL;
panel.add(panel2.frmUserList, c);

stretchyPane.add(panel);

frame.setVisible(true);

既然我已经将原始数据逐行复制到副本中,那么是什么导致了两者之间的差异?

最佳答案

weightx 和weighty 属性可能看起来像比例大小,但事实并非如此。事实上,它们决定了布局中额外空间的分配。

如果通过在 JFrame 上调用 pack() 将所有内容设置为其首选大小,则不会有额外的空间。这意味着在该状态下,weightx 和weighty 属性不起作用。

一旦用户开始将窗口大小调整得更大,就会出现额外的空间,只有那时 GridBagLayout 才会引用weightx和weighty属性来确定如何将额外的空间分配给每列和行。在那之前,如果重量x较小的组件的首选尺寸决定的话,那么重量x较小的组件完全有可能比重量x较大的组件更宽。

希望这个简单的程序能够演示这个概念。尝试使用鼠标(或键盘)将窗口大小调整得更宽,并观察每个文本字段如何增长:

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class GridBagProportions {
static void buildAndShowWindow() {
JTextField small = new JTextField("small (0.8)", 5);
JTextField large = new JTextField("LARGE (0.2)", 30);

small.setMinimumSize(small.getPreferredSize());
large.setMinimumSize(large.getPreferredSize());

JPanel panel = new JPanel(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets.left = 6;
gbc.insets.top = 6;
gbc.insets.bottom = 6;

gbc.weightx = 0.8;
panel.add(small, gbc);

gbc.weightx = 0.2;
gbc.insets.right = 6;
panel.add(large, gbc);

JFrame frame = new JFrame("GridBagLayout Proportions");
frame.getContentPane().add(panel);
frame.pack();

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
buildAndShowWindow();
}
});
}
}

那么对此可以采取什么措施呢?嗯,这是 GridBagLayout 无法做到的一种布局场景。我会尝试使用 SpringLayout :

SpringLayout layout = new SpringLayout();
JPanel textAndUsers = new JPanel(layout);

SpringLayout.Constraints scrollPaneConstraints =
new SpringLayout.Constraints(scrollPane);

Spring scrollPaneWidth = scrollPaneConstraints.getWidth();
SpringLayout.Constraints listConstraints =
new SpringLayout.Constraints(scrollPaneWidth,
scrollPaneConstraints.getY(),
Spring.scale(scrollPaneWidth, 0.25f),
scrollPaneConstraints.getHeight());

layout.putConstraint(SpringLayout.EAST, textAndUsers, 0,
SpringLayout.EAST, frmUserList);
layout.putConstraint(SpringLayout.SOUTH, textAndUsers, 0,
SpringLayout.SOUTH, scrollPane);

textAndUsers.add(scrollPane, scrollPaneConstraints);
textAndUsers.add(frmUserList, listConstraints);

请注意,listConstraints 的创建指定了一个宽度参数,即 Spring.scale(scrollPaneWidth, 0.25f)。这可确保列表始终是包含 JTextArea 的滚动 Pane 的四分之一宽。

SpringLayout 使用起来很棘手,因为您必须确保将布局容器的远边缘显式链接到子组件,因为 SpringLayout 不会自动增长以容纳所有子组件。这就是 putConstraint 调用所做的事情。

关于java - GridBagLayout 不稳定的调整大小和显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30495188/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com