JTextArea 在父缩小时不换行

JTextArea not wrapping when parent shrinks

我正在创建一个 Java 显示消息聊天记录的 Swing 应用程序。该帧仅包含一个 JScrollPane,其中包含一个 VerticalLayout,并且其中包含不定数量的 JTextArea,每个消息一个。 JTextArea 是不可编辑的,我使用它们而不是 JLabel 的唯一原因是我需要将文本换行。

作为测试,我创建了框架并添加了两条消息。

这是按预期工作的,组件形成一个连续的文本页面并环绕框架。

然后我增加框架的大小。

这仍然按预期工作,JScrollPaneJTextArea 已展开,文本已自行重新包装。

然后我将 window 缩小到更小的尺寸。

这没有按预期工作。 JScrollPane 保持最大尺寸,单词不换行。我怎样才能使框架在宽度方向上缩小时,JScrollPaneJTextArea 也会缩小?

我已经尝试过的东西:

编辑:最小可验证示例,产生与上述相同的效果

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import org.jfree.ui.tabbedui.VerticalLayout;

public class MessagingFrame extends JFrame {

    private JPanel textPanel;

    public MessagingFrame() {
        // Create display area
        textPanel = new JPanel();
        textPanel.setLayout(new VerticalLayout());
        // Wrap text panel in scroll pane
        JScrollPane scrollPane = new JScrollPane(textPanel);
        // Add scroll pane
        add(scrollPane);
        // Size center and display
        setSize(500, 500);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public void addMessage(String message) {
        JTextArea textArea = new JTextArea(message);
        textArea.setEditable(false);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        textPanel.add(textArea);
        textPanel.updateUI();
    }

    public static void main(String[] args) {
        MessagingFrame frame = new MessagingFrame();
        frame.addMessage("According to all known laws of aviation, there is no way a bee should be able to fly. Its wings are too small to get its fat little body off the ground. The bee, of course, flies anyway because bees don’t care what humans think is impossible.");
        frame.addMessage("We begin on Christmas Eve with me, Mark, and my roommate, Roger. We live in an industrial loft on the corner of 11th street and Avenue B, the top floor of what was once a music publishing factory. Old rock 'n' roll posters hang on the walls. They have Roger's picture advertising gigs at CBGB's and the Pyramid Club. We have an illegal wood burning stove; its exhaust pipe crawls up to a skylight. All of our electrical appliances are plugged into one thick extension cord which snakes its way out a window. Outside, a small tent city has sprung up in the lot next to our building. Inside, we are freezing because we have no heat.");
    }

}

谢谢!

您需要在添加到滚动面板的面板上实现Scrollable接口,以便getScrollableTracksViewportWidth()方法returns true.

这将强制视口中的组件始终与视口大小相同,而不是添加到视口的组件的宽度。

实现接口时,需要实现接口的所有方法。

或者一个简单的解决方案是使用 Scrollable Panel 为您实现接口,您只需设置您想要的属性。

所以基本代码是:

ScrollablePanel panel = new ScrollablePanel( new VerticalLayout());
panel.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );
panel.add(...);
JScrollPane scrollPane = new JScrollPane( panel );

Wrapping each JTextArea in a JPanel and giving the panel a BoxLayout or BorderLayout

您应该能够直接将文本区域添加到面板。 VerticalLayout 似乎使每个组件尽可能宽。

textPanel.updateUI();

不要使用用于 LAF 更改的 updateUI()。当您从可见的 GUI 中 add/remove 组件时,基本代码为:

panel.add();
panel.revalidate();
panel.repaint();