【问题标题】:Dynamic JTextArea in JScrollPane ends up under scroll barJScrollPane 中的动态 JTextArea 在滚动条下结束
【发布时间】:2018-01-25 14:19:28
【问题描述】:

我有一个带有 JScrollPane 的 JFrame,其中包含一个 JTextArea。滚动窗格配置为从不显示水平滚动条,并根据需要显示垂直滚动条。 随着文本区域中文本的增长,最终会出现垂直滚动条,隐藏部分文本区域。我希望滚动条在出现滚动条时根据需要调整其内容的大小。

我发现的一种解决方法是始终显示垂直滚动条,但这看起来不太好,因为它很少需要。

在我的系统(Windows 10)上输入足够多的文本后,下面的代码 sn-p 重现了该问题

import javax.swing.*;
import java.awt.*;
import static javax.swing.ScrollPaneConstants.*;

public class Test {
    public static void main(String[] args) {
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        panel.add(new JLabel("text"));
        panel.add(new JLabel("text"));
        panel.add(new JLabel("text"));

        JTextArea textArea = new JTextArea();
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        textArea.setText("This text fits");
        panel.add(textArea);

        JScrollPane scrollPane =
                new JScrollPane(panel, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_NEVER);

        JFrame frame = new JFrame("Title");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.getContentPane().add(scrollPane);

        frame.pack();
        frame.setVisible(true);
    }
}

【问题讨论】:

  • I would expect the scrollbar to resize its content as needed when the scrollbar appears. - 这不是滚动窗格的作用。随着添加到滚动窗格的组件大小的增加,滚动条出现。因此,您可以使用滚动条在滚动窗格中向上/向下滚动组件以查看所有组件。我怀疑你真的只希望文本区域上的滚动条所有组件都是可见的,然后当你添加更多文本时,文本区域中的文本会滚动。

标签: java swing jscrollpane jtextarea


【解决方案1】:

只是组件放置的问题。参考以下代码:

public TestFrame() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    setContentPane(contentPane);
    contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.X_AXIS));

    JScrollPane scrollPane = new JScrollPane();
    contentPane.add(scrollPane);

    JPanel panel = new JPanel();
    scrollPane.setColumnHeaderView(panel);
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

    JLabel lblNewLabel = new JLabel("text");
    panel.add(lblNewLabel);

    JLabel lblNewLabel_2 = new JLabel("text");
    panel.add(lblNewLabel_2);

    JLabel lblNewLabel_1 = new JLabel("text");
    panel.add(lblNewLabel_1);

    JTextArea textArea = new JTextArea();
    textArea.setLineWrap(true);
    textArea.setText("This text fits");
    scrollPane.setViewportView(textArea);
}

希望这会有所帮助。 :-)

【讨论】:

  • 实际上发生的事情是您将滚动窗格附加了 2 个组件,首先是 JPanel 本身,然后是 frame.getContentPane()。因此,当滚动条出现时,从逻辑上讲,您的滚动窗格位于隐藏您的部分文本的文本区域上方。 :-)
  • 据我所知,您的代码从未将带有标签的面板添加到滚动窗格中。我需要滚动窗格中的所有内容,包括标签和文本区域。我将我的内容添加到面板中,然后将其添加到滚动窗格中。然后将框架的内容设置为滚动窗格。
  • 嗨 Gotler,检查更新的代码。一切都和以前一样,只是在滚动窗格上添加了包含 3 个标签的面板。 :-)
【解决方案2】:

不显示水平滚动条并没有真正的帮助。

相反,您需要实现Scrollable 接口来告诉滚动窗格面板应该始终适合滚动窗格的宽度。这将导致文本区域中的文本在添加文本时正确换行。

您可以使用Scrollable Panel 代替实现Scrollable 接口,它允许您使用类的方法更改可滚动属性。

你只需要改变你的代码如下:

//JPanel panel = new JPanel();
ScrollablePanel panel = new ScrollablePanel();
panel.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );

【讨论】:

  • 就是这样!为我的内容创建一个可滚动的面板可以完美地显示所有内容。似乎我应该通读整个scrollpane tutorial。谢谢!
【解决方案3】:

重写 doLayout() 并做任何你想做的事情,在 doLayout() 处,你对如何处理你的子组件有最终决定权(在布局管理器的工作完成之后)。

但是需要先让textArea和scrollPane成为属性,因为后面需要引用:

private static JTextArea textArea;
private static JScrollPane scrollPane;

public static void main(String[] args) {
    JPanel panel = new JPanel() {
        @Override
        public void doLayout() {
            super.doLayout();

            if (scrollPane.getVerticalScrollBar().isVisible()) {
                textArea.setSize(textArea.getWidth() - 3, textArea.getHeight());
            }
        }
    };

【讨论】:

  • (1-) 没有理由重写 doLayout()。问题是如何创建 GUI。让布局管理器完成他们的工作。
  • 我认为 GUI 的创建方式没有任何问题,他希望标签和文本区域作为一个整体滚动,这就是他这样做的原因。在这里覆盖 doLayout() 并没有错,就像您自定义正在使用的原始布局一样,只是我的解决方案在没有子类化的情况下做到了这一点。顺便问一下,您认为应该如何更改 GUI 创建以实现他想要的?
  • 误读了问题。问题不在于 GUI 创建或布局。问题是组件如何在滚动窗格中显示。关闭水平滚动并没有真正起作用。但是,覆盖 doLayout() 仍然不是解决方案。让布局经理完成他们的工作。
【解决方案4】:

要解决问题,请更改:

JTextArea textArea = new JTextArea();

收件人:

JTextArea textArea = new JTextArea(1,20);

通过为文本区域提供大小提示,滚动窗格在添加更多文本时能够更好地处理它。

【讨论】:

  • 我最初有这样的提示,但它似乎无法解决问题。
  • 在这里完美运行。显示新代码(另一个 MCVE),带有更改和屏幕截图,我可能会重新审视这个问题。
  • 为什么要将面板添加到滚动窗格,而不是 textarea 到滚动窗格 && 滚动窗格底部的面板?
  • 尺寸提示后的代码:pastebin.com/VFRJw5g5。这就是我所看到的:imgur.com/a/Khm8Z。你可以(希望)看到滚动条下隐藏了两个字符。
猜你喜欢
  • 1970-01-01
  • 2011-02-10
  • 2022-11-03
  • 2012-07-02
  • 1970-01-01
  • 2016-09-03
  • 2020-07-31
  • 2011-05-20
  • 2014-06-11
相关资源
最近更新 更多