我对Swing很新。我有一个应用程序,可以根据外部输入动态生成UI。在面板的顶部,有一个带有一些标题文本的JLabel,然后是一个按钮(告诉应用程序重新加载动态生成的东西),然后在下面是一个包含所有动态生成的东西的JScrollPane。我希望标签和按钮只占用所需的垂直空间,然后滚动窗格以填充所有剩余的可用空间。
我使用GridBagLayout,并在添加滚动窗格之前设置gbc.fill = BOTH。
我已经整理了一个SSCCE,当它第一次加载时,窗口看起来就像我想要的那样。但是,如果我将窗口调整得更小,我的期望是滚动窗格将继续消耗所有可用空间,并且会出现滚动条。但恰巧的是,只要我将窗口缩小甚至一个像素,滚动窗格就会变得很小,其内容几乎不可见。
我找到了How to get a JScrollPane to resize with its parent JPanel,但是当JScrollPane不是独生子女时,这并不起作用。可以这么说。
我做错了什么?
SSCCE:
public class SwingTest {
public static void main(String[] args) {
JPanel bigPanel = new JPanel();
bigPanel.setLayout(new GridLayout(10, 10));
for (int i = 0; i < 100; i++) {
bigPanel.add(new JCheckBox("Item " + i));
}
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
JFrame mainWindow = new JFrame("Swing Test");
mainWindow.setLayout(new GridBagLayout());
mainWindow.add(new JLabel("Heading"), gbc);
mainWindow.add(new JButton("Button"), gbc);
gbc.fill = GridBagConstraints.BOTH;
mainWindow.add(new JScrollPane(bigPanel), gbc);
mainWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
mainWindow.setLocationByPlatform(true);
mainWindow.pack();
mainWindow.setVisible(true);
}
}
答案 0 :(得分:0)
所以,我在写SSCCE时想到了这一点。 (有趣的是如何发生!)
根据我链接的相关问题,我尝试使用BorderLayout:
public class SwingTest {
public static void main(String[] args) {
JFrame mainWindow = new JFrame("Swing Test");
mainWindow.setLayout(new BorderLayout());
mainWindow.add(new JLabel("Heading"));
mainWindow.add(new JButton("Button"));
JPanel bigPanel = new JPanel();
bigPanel.setLayout(new GridLayout(10, 10));
for (int i = 0; i < 100; i++) {
bigPanel.add(new JCheckBox("Item " + i));
}
mainWindow.add(new JScrollPane(bigPanel));
mainWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
mainWindow.setLocationByPlatform(true);
mainWindow.pack();
mainWindow.setVisible(true);
}
}
但那不起作用,因为我认为我对BorderLayout的作用有一个根本的误解。通过不对我的add(...)调用指定约束,我将所有三个组件添加到&#34; CENTER&#34;窗格。 BorderLayout的目的是容纳一个随容器大小缩放的单个组件,并且您可以将其他东西放在边缘(即边框)上,这些东西将保持固定大小。每个位置只能有一个组件,所以通过将所有三个组件添加到CENTER,我只剩下我添加的最后一个组件。我需要将我的标题和按钮包装在JPanel中并将其放在顶部边缘:
public class SwingTest {
public static void main(String[] args) {
JPanel top = new JPanel();
top.setLayout(new BoxLayout(top, BoxLayout.PAGE_AXIS));
top.add(new JLabel("Heading"));
top.add(new JButton("Button"));
JPanel bigPanel = new JPanel(new GridLayout(10, 10));
for (int i = 0; i < 100; i++) {
bigPanel.add(new JCheckBox("Item " + i));
}
JFrame mainWindow = new JFrame("Swing Test");
mainWindow.setLayout(new BorderLayout());
mainWindow.add(top, PAGE_START);
mainWindow.add(new JScrollPane(bigPanel), CENTER);
mainWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
mainWindow.setLocationByPlatform(true);
mainWindow.pack();
mainWindow.setVisible(true);
}
}
之后组件的行为正确,但是当窗口变得足够大以至于不需要滚动时,复选框的网格会扩展以适应空间,这是我不想要的。我只是想把它钉在左上角。以下是解决问题的原因:
public class SwingTest {
public static void main(String[] args) {
JPanel top = new JPanel();
top.setLayout(new BoxLayout(top, BoxLayout.PAGE_AXIS));
top.add(new JLabel("Heading"));
top.add(new JButton("Button"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = NONE;
JPanel bigPanel = new JPanel(new GridBagLayout());
for (int i = 0; i < 10; i++) {
gbc.gridx = RELATIVE;
gbc.gridy = i;
gbc.anchor = NORTHWEST;
for (int j = 0; j < 10; j++) {
bigPanel.add(new JCheckBox("Item " + (10 * i + j)), gbc);
}
}
// add a panel to the right side to prevent the grid from growing horizontally
gbc.fill = BOTH;
gbc.weightx = 1;
bigPanel.add(new JPanel(), gbc);
// add another panel to the bottom to prevent the grid from growing vertically
gbc.gridy = RELATIVE;
gbc.gridx = 0;
gbc.weightx = 0;
gbc.weighty = 1;
bigPanel.add(new JPanel(), gbc);
JFrame mainWindow = new JFrame("Swing Test");
mainWindow.setLayout(new BorderLayout());
mainWindow.add(top, PAGE_START);
mainWindow.add(new JScrollPane(bigPanel), CENTER);
mainWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
mainWindow.setLocationByPlatform(true);
mainWindow.pack();
mainWindow.setVisible(true);
}
}
外卖: