当前位置: 首页 > 知识库问答 >
问题:

如何让JScrollPane填充所有剩余的可用空间

陆俊智
2023-03-14

我对荡秋千很陌生。我有一个基于外部输入动态生成UI的应用程序。在面板的顶部,有一个带有一些标题文本的JLabel,然后是一个按钮(告诉应用程序重新加载动态生成的内容),然后在下面是一个JScrollPane,其中包含所有动态生成的内容。我希望标签和按钮只占用所需的垂直空间,然后滚动窗格来填充所有剩余的可用空间。

我正在使用GridBagLayout,并在添加滚动窗格之前设置gbc.fill=BOTH。

我组装了一个SSCCE,当它第一次加载时,窗口看起来和我想要的一模一样。但如果我将窗口的大小调整得更小,我的期望是滚动窗格将继续占用所有可用空间,滚动条将出现。但事实是,只要我将窗口缩小一个像素,滚动窗格就会变得很小,内容几乎看不见。

我发现了如何让JScrollPane与其父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);
    }
}

共有1个答案

程冥夜
2023-03-14

所以,我在写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的作用有一个根本性的误解。由于没有为添加(...)的调用指定约束,我将所有三个组件添加到“CENTER”窗格中。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);
    }
}

外卖:

  • 始终将JScrollPane本身放在BorderLayout的中心。
  • 如果您不希望类似网格的内容在调整大小时动态扩展其“单元格填充”,请使用GridBagLayout,而不是GridLayout。
 类似资料:
  • 我有一个<代码> 窄的标题行 我想占用div剩余部分的图像。 如何使用纯CSS(无Javascript)实现这一点?我一直在尝试很多事情,运气不好。 这是我能得到的最接近的;图像偷偷溜出了的绿色边框 下面是我尝试使用,但失败了。

  • 问题内容: 我有2个div: 页面左侧有一个,右侧是一个。左侧的一个宽度固定,我希望右侧的一个填充剩余空间。 问题答案: 这似乎可以完成您想要的。

  • 我有一个基本的flexbox布局,如下所示。。 我试图使顶部的div填充剩余的空间,底部的div是动态的,因此高度根据文本的不同而变化。我的结果是这样的。。 在这种情况下,flexbox是最好的选择吗?

  • 我需要用div填充下的的剩余垂直空间。 我需要一个唯一的CSS解决方案。

  • 问题内容: 我需要填写 剩余的垂直空间 的下用DIV。 我只需要一个CSS解决方案。 问题答案: 您可以像这样在div 上执行此操作: 小提琴 CSS: 编辑:替代解决方案 根据您的布局和这些div中的内容,可以使它变得更简单,并且标记更少,如下所示: HTML: CSS:

  • 问题内容: +--------------------+ | | | | | | | | | 1 | | | | | | | | | +--------------------+ | | | | | | | | | 2 | | | | | | | | | +--------------------+ 如上所示的(1)的内容是未知的,因为它在动态生成的页面中可能会增加或减少。如上所示,第二个div(