修复JScrollPane的高度

时间:2017-01-13 07:53:04

标签: java swing

我不知道我面临的问题是否只针对我的情况,所以我写了一个简化版本,导致我的问题(以JLabel为样本组件)。

public class InterestingBehavior {

    static int direction = -4;
    static final boolean useScroll = true;
    static final String longString = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                                             + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

    public static void main(String[] args) {
        JFrame test = new JFrame("Test");
        test.setSize(500, 300);
        test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        test.setLayout(new BoxLayout(test.getContentPane(), BoxLayout.Y_AXIS));
        for (int i = 0; i < 10; i++)
            test.add(useScroll ? new JScrollPane(new JLabel(longString)) : new JLabel(longString));
        test.add(Box.createVerticalGlue()); //should use all available space

        final int min = 300, max = 600;
        new Timer(50, e -> {
            int h = test.getHeight();
            SwingUtilities.invokeLater(() -> test.setSize(test.getWidth(), h + direction));
            direction = h == min || h == max ? -direction : direction;
        }).start();

        test.setVisible(true);
    }

}

框架调整自身大小以显示我想要/不想要的内容。将JLabel添加到BoxLayout会使它们全部位于JFrame的顶部 - 这就是我想要的,因为我在面板中添加了垂直胶水。但是,如果我将JLabel包装在JScrollPane中,它会根据JFrame的高度决定自动垂直调整自身大小 - 如何避免此行为并将滚动窗格保持为恒定高度?

框架:

expanded scroll pane

调整大小后,变为

small pane

这不是我想要的。

如何将一个维度固定为子组件(视口)的维度?

1 个答案:

答案 0 :(得分:3)

问题是JScrollPane本身抓住了所有空间。 BoxLayout公平地分配JScrollPanes和垂直粘合剂之间的可用空间。

解决方案是使用例如限制JScrollPanel要求的垂直空间。 jScrollPane.setMaxmimumSize(new Dimension(1000, 50))

现在,你让每个ScrollPane正好抓住这个空间,这会在调整大小并实际需要绘制水平滚动条时导致奇怪的行为。因此,您可能希望拥有一个首选尺寸,例如jScrollPane.setPreferredSize(new Dimension(0, 50))也是。

这里有完整的例子:

    static int direction = -4;
    static final boolean useScroll = true;
    static final String longString = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                                             + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

    public static void main(String[] args) {
        JFrame test = new JFrame("Test");
        test.setSize(500, 300);
        test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        test.setLayout(new BoxLayout(test.getContentPane(), BoxLayout.Y_AXIS));
        for (int i = 0; i < 10; i++) {
            if(useScroll) {
                JScrollPane jScrollPane = new JScrollPane(new JLabel(longString));
                jScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
                jScrollPane.setMaximumSize(new Dimension(1000, 50));
                jScrollPane.setPreferredSize(new Dimension(0, 50));
                test.add(jScrollPane);
            } else {
                 test.add(new JLabel(longString));
            }
        }
        test.add(Box.createVerticalGlue()); //should use all available space

        final int min = 300, max = 600;
        new Timer(50, e -> {
            int h = test.getHeight();
            SwingUtilities.invokeLater(() -> test.setSize(test.getWidth(), h + direction));
            direction = h == min || h == max ? -direction : direction;
        }).start();

        test.setVisible(true);
    }