如何限制JScrollPane

时间:2017-08-04 02:53:04

标签: java swing

我使用JScrollPane在面板中有一个JLabelGridBagLayout个对象。每个标签都显示HTML文本,其中包含丰富的元素,这些元素在运行时会有所不同。

我希望所有标签都具有相同的宽度(由滚动窗格的宽度驱动),但高度会根据文本换行的内容而变化(由JLabel自动处理)。如果标签超出滚动窗格的高度,则应显示垂直滚动条。

以下是一些演示此问题的示例代码:

public class ScrollLabels extends JFrame {
    private final JPanel labelPanel = new JPanel(new GridBagLayout());
    private final GridBagConstraints c = new GridBagConstraints();

    public ScrollLabels() throws HeadlessException {
        super("Scroll Labels");
    }

    public void createUI() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JScrollPane scroller = new JScrollPane(labelPanel);
        add(scroller);
        c.gridx = 0;
        c.gridy = GridBagConstraints.RELATIVE;
        c.fill = GridBagConstraints.HORIZONTAL;
        addLabel("Here is <em>Rich Text</em>");
        addLabel("Here is <ul><li>A</li><li>List</li></ul>");
        addLabel("Here is <table><tr><th>A</th><th>Table></th></tr></table");
        addLabel("Here is more <em>Rich Text</em>");
        addLabel("Here is even more <b>Rich Text</b>");
        addLabel("Here is a long sentence that should wrap when the panel "
                + "is too small for the text.");
        pack();
    }

    private void addLabel(String text) {
        JLabel label = new JLabel("<html>" + text + "</html>");
        label.setBorder(BorderFactory.createEtchedBorder());
        labelPanel.add(label, c);
    }

    public static void main(String[] args) {
        ScrollLabels frame = new ScrollLabels();
        frame.createUI();
        frame.setVisible(true);
    }    
}

水平调整标签大小并在适当的位置显示滚动条。它没有做的是垂直调整标签大小以使它们适合滚动窗格。

以下是我尝试过的各种事情:

  • 更改GridBagConstraint值。如何扩展和收缩组件有很好的控制,但我看不到设置最小或最大宽度的方法。
  • JScrollPane滚动条策略设置为从不显示水平滚动条。这只是切断标签文本而不是包装文本。
  • 手动设置标签大小 - 即根据文本设置滚动窗格的宽度和高度。在给定固定宽度的情况下,我无法通过简单的方法获得丰富HTML文本的正确高度。在任何情况下,我都希望有一个可以完成工作的布局管理器,而不是手动编写首选尺寸。

我还没有尝试过的一件事就是创建一个自定义布局管理器。我怀疑这可能是正确的答案,但我想看看你们中是否有人有一个我没有看到的更简单的解决方案。

1 个答案:

答案 0 :(得分:2)

  

我希望所有标签都具有相同的宽度(由滚动窗格的宽度驱动),但高度根据其内容而变化

您需要在面板上实施Scrollable界面,并覆盖getScrollableTracksViewportWidth()方法以返回true。您还需要为接口的其他方法提供默认实现。

或者您可以使用Scrollable Panel提供允许您设置滚动属性的方法。