Java 设置JTextArea的高度而不是宽度

Java 设置JTextArea的高度而不是宽度,java,swing,layout-manager,jtextarea,boxlayout,Java,Swing,Layout Manager,Jtextarea,Boxlayout,我在JPanel中有多个JTextAreas。我正在使用BoxLayout使它们垂直对齐并填充容器的宽度 这是可行的,但它们似乎也会扩展到整个高度 我真正想要的是一个简单的文本区域,它可以包装文本,在这里我可以控制宽度,但允许高度随着添加更多行而动态缩放。上述方法正是我在这方面的最佳尝试。如果有一个解决方案使用了不同的布局管理器、不同的文本组件等,那么这个解决方案是有效的 下面的最小可验证示例: public static void main(String[] args) { JFram

我在
JPanel
中有多个
JTextArea
s。我正在使用
BoxLayout
使它们垂直对齐并填充容器的宽度

这是可行的,但它们似乎也会扩展到整个高度

我真正想要的是一个简单的文本区域,它可以包装文本,在这里我可以控制宽度,但允许高度随着添加更多行而动态缩放。上述方法正是我在这方面的最佳尝试。如果有一个解决方案使用了不同的布局管理器、不同的文本组件等,那么这个解决方案是有效的

下面的最小可验证示例:

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setPreferredSize(new Dimension(300, 300));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel textAreas = new JPanel();
    textAreas.setLayout(new BoxLayout(textAreas, BoxLayout.Y_AXIS));

    JTextArea area1 = new JTextArea();
    area1.append("this is a string");
    area1.setLineWrap(true);
    area1.setWrapStyleWord(true);
    textAreas.add(area1);

    JTextArea area2 = new JTextArea("and another that is much longer, so that it wraps to the next line");
    area2.setLineWrap(true);
    area2.setWrapStyleWord(true);
    textAreas.add(area2);

    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setViewportView(textAreas);

    frame.add(scrollPane);
    frame.pack();
    frame.setVisible(true);
}
我自己做过这方面的研究,包括查看不同的布局管理器(),并在网站上查看其他问题,但我运气不太好

TLDR:我可以使布局的每个元素都有一个与内容相对应的高度,但有一个固定的宽度吗?如果是,怎么做

我真正想要的是一个简单的文本区域,它可以包装文本,在这里我可以控制宽度,但允许高度随着添加更多行而动态缩放

BoxLayout符合最大尺寸,因此文本区域将增大以填充面板中的所有可用空间。您可以使用以下方法覆盖
getMaximumSize()
方法以返回首选高度:

JTextArea area1 = new JTextArea()
{
    public Dimension getMaximumSize()
    {
        Dimension d = super.getMaximumSize();
        d.height = getPreferredSize().height;

        return d;
    }
};
它是有效的

不是真的。将框架加宽,文本将展开。然后收缩框架并显示滚动条。即文本不会再次换行

您需要做的是强制添加到滚动窗格的面板与视口的宽度相同。这将使包装工作正常

您可以通过在面板上实现
可滚动
界面来实现这一点。具体来说,您需要重写
getScrollableTracksViewportWidth()
方法以返回
true

或者更简单的解决方案是使用类,该类允许您设置面板的属性以控制此行为

您可以将
JPanel
替换为
ScrollablePanel

//JPanel textAreas = new JPanel();
ScrollablePanel textAreas = new ScrollablePanel();
textAreas.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );
编辑:

如果有使用不同布局管理器的解决方案

无需覆盖文本区域的
getMaximumSize()
方法,并且在使用
可滚动面板时,您应该能够使用以下布局管理器

GridBagLayout
允许您指定“weightx”约束。这将允许组件填充面板中的所有可用空间

或者,如果您不喜欢指定GridBagLayout的所有约束,则可以使用支持组件按其首选大小进行垂直/水平布局的

您只需使用以下命令强制构件填充水平空间:

//textAreas.setLayout(new BoxLayout(textAreas, BoxLayout.Y_AXIS));
RelativeLayout rl = new RelativeLayout(RelativeLayout.Y_AXIS);
rl.setFill( true );
textAreas.setLayout(rl);
我真正想要的是一个简单的文本区域,它可以包装文本,在这里我可以控制宽度,但允许高度随着添加更多行而动态缩放

BoxLayout符合最大尺寸,因此文本区域将增大以填充面板中的所有可用空间。您可以使用以下方法覆盖
getMaximumSize()
方法以返回首选高度:

JTextArea area1 = new JTextArea()
{
    public Dimension getMaximumSize()
    {
        Dimension d = super.getMaximumSize();
        d.height = getPreferredSize().height;

        return d;
    }
};
它是有效的

不是真的。将框架加宽,文本将展开。然后收缩框架并显示滚动条。即文本不会再次换行

您需要做的是强制添加到滚动窗格的面板与视口的宽度相同。这将使包装工作正常

您可以通过在面板上实现
可滚动
界面来实现这一点。具体来说,您需要重写
getScrollableTracksViewportWidth()
方法以返回
true

或者更简单的解决方案是使用类,该类允许您设置面板的属性以控制此行为

您可以将
JPanel
替换为
ScrollablePanel

//JPanel textAreas = new JPanel();
ScrollablePanel textAreas = new ScrollablePanel();
textAreas.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );
编辑:

如果有使用不同布局管理器的解决方案

无需覆盖文本区域的
getMaximumSize()
方法,并且在使用
可滚动面板时,您应该能够使用以下布局管理器

GridBagLayout
允许您指定“weightx”约束。这将允许组件填充面板中的所有可用空间

或者,如果您不喜欢指定GridBagLayout的所有约束,则可以使用支持组件按其首选大小进行垂直/水平布局的

您只需使用以下命令强制构件填充水平空间:

//textAreas.setLayout(new BoxLayout(textAreas, BoxLayout.Y_AXIS));
RelativeLayout rl = new RelativeLayout(RelativeLayout.Y_AXIS);
rl.setFill( true );
textAreas.setLayout(rl);