【问题标题】:How do I limit the width of components of a JScrollPane如何限制 JScrollPane 组件的宽度
【发布时间】:2017-08-04 02:53:03
【问题描述】:

我在使用GridBagLayout 的面板中有一个JScrollPane 和多个JLabel 对象。每个标签都显示具有丰富元素的 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 文本的正确高度。在任何情况下,我都希望有一个可以完成这项工作的布局管理器,而不是手动编码首选尺寸。

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

【问题讨论】:

  • “使用GridBagLayout 的面板中有许多JLabel 对象。每个标签都显示HTML 文本” 不确定它是否适用于此用途-case,但我通常会使用样式指定宽度。例如。如this answer所示。

标签: java swing


【解决方案1】:

我希望所有标签都具有相同的宽度(由滚动窗格的宽度驱动),但高度取决于它们的内容

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

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

【讨论】:

  • 感谢您的帮助我不知道 Scrollable。这似乎是正确的做法。如果需要任何包装,我仍然有一个问题,即面板会跳转到最小宽度。你以前见过这个问题吗?如果没有,我会做一些挖掘并发布一个新问题,如果我无法弄清楚。
  • @sprinter,它是调整面板大小以适应视口的解决方案。 I still have an issue that the panel jumps to minimum width - 不,面板宽度不会改变。面板上标签的大小可能会发生变化。这就是 GridBagLayout 的工作原理。如果组件的大小不能适合提供的区域,则使用组件的最小大小。也许您可以使用自定义 JLabel 并覆盖 getMinimumSize() 方法以使宽度成为父容器的大小?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-23
  • 1970-01-01
  • 2010-11-14
  • 2011-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多