当父缩小时,JTextArea不会换行

时间:2016-03-02 02:29:22

标签: java swing jscrollpane jtextarea

(部分是this的后续行动)

我正在创建一个显示消息聊天记录的Java swing应用程序。该框架只包含一个JScrollPane VerticalLayout,其中包含JTextArea个无限数量,每条消息一个。{1}}。 JTextArea是不可编辑的,我使用它们而不是JLabel的唯一原因是因为我需要包装文本。

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

enter image description here

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

然后我增加了框架的大小。

enter image description here

这仍然按预期工作,JScrollPaneJTextArea已展开,文字已自行重新填充。

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

enter image description here

这不符合预期。 JScrollPane保持最大尺寸,单词不包装。我怎样才能使框架在宽度方向上缩小时,JScrollPaneJTextArea也会缩小?

我已经尝试过的事情:

  • 使用JScrollPane
  • 实例化JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
  • 为每个JTextArea提供BoxLayoutBorderLayout
  • JTextArea中的每个JPanel包裹起来,并为面板提供BoxLayoutBorderLayout
  • 在调整事件大小时重新验证/重新绘制JScrollPane
  • 在调整事件大小时调用setSize(Dimension d) JScrollPane getSize() JFrame

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

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.");
    }

}

谢谢!

1 个答案:

答案 0 :(得分:2)

您需要在添加到滚动面板的面板上实施Scrollable界面,以便getScrollableTracksViewportWidth()方法返回true

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

实现界面时,您需要实现界面的所有方法。

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

所以基本代码是:

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

将每个JTextArea包装在JPanel中,并为面板提供BoxLayout或BorderLayout

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

  

textPanel.updateUI();

请勿使用适用于LAF更改的updateUI()。从可见GUI添加/删除组件时,基本代码为:

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