Java 使JScrollPane中JList单元格渲染器中的JTextArea调整大小以滚动视图宽度、内容高度

Java 使JScrollPane中JList单元格渲染器中的JTextArea调整大小以滚动视图宽度、内容高度,java,swing,jtextarea,Java,Swing,Jtextarea,如果标题有点混乱,很抱歉。情况如下: 我在JScrollPane中有一个JList。每个列表项(实现为自定义的ListCellRenderer)包含一个带有一些标签的JFrame,最重要的是一个JTextArea。文本区域包含一些需要跨多行换行的文本,以便用户不需要在滚动窗格中水平滚动。我不想让文本区域自己滚动,我只想让它扩展到需要的垂直空间 如果这有助于理解我试图实现的目标,下面是IntelliJ swing UI设计器的屏幕截图: 我希望正文文本区域(及其面板)扩展到所需的垂直空间 保存文

如果标题有点混乱,很抱歉。情况如下:

我在
JScrollPane
中有一个
JList
。每个列表项(实现为自定义的
ListCellRenderer
)包含一个带有一些标签的
JFrame
,最重要的是一个
JTextArea
。文本区域包含一些需要跨多行换行的文本,以便用户不需要在滚动窗格中水平滚动。我不想让文本区域自己滚动,我只想让它扩展到需要的垂直空间

如果这有助于理解我试图实现的目标,下面是IntelliJ swing UI设计器的屏幕截图:

我希望
正文
文本区域(及其面板)扩展到所需的垂直空间

保存文本的组件不必是文本区域,我尝试了一个
JTextPane
,但也不起作用。文本不需要是可编辑的

我已经将文本区域设置为换行(使用
setLineWrap
setWrapStyleWord
),并使用
sethorizontalcrollbarpolicy
禁用滚动窗格上的水平滚动

以下是一个最小的可复制示例:

import javax.swing.*;
导入java.awt.*;
导入java.util.array;
公共类TextAreaListTest实现ListCellRenderer{
//任意长字符串
私有静态最终字符串LORUM_IPSUM=“”
奥雷姆·伊普苏姆·多洛尔·塞特·塞特·塞特·塞特·塞特·塞特·塞特·塞特·塞特·塞特·塞特·莫里斯·坦普尔·塞特·塞特·塞特·塞特·塞特·塞特·塞特·塞特·塞特·塞特·塞特·。
我的生命在流苏里,我的生命在流苏里,我的生命在流苏里,我的生命在流苏里,我的生命在流苏里,我的生命在流苏里,我的生命在流苏里,我的生命在流苏里,我的生命在流苏里
莫里斯·埃吉特(Mauris eget)是一位著名的作家,他是一位自由主义者,
pulvinar facilisis erat.Aliquam euismod nulla and dictum.Etiam non ullamcorper sem.nulla efficitur,
我是尤伊斯莫,我是康格,我是自由人,我是自由人
珀鲁斯门。莫里斯权杖只是一辆非奥奇车,塞德·马蒂斯·萨皮恩·库鲁斯。埃尼安在波特提托
多洛。埃尼安·尤伊斯莫德·马萨和自由女神埃格斯塔斯,在《tincidunt vehicula ex》一书中,一个
解决方案只是一个共同的问题,它是一个共同的问题。
""";
@凌驾

公共组件getListCellRenderComponent(JList这里有一个几乎可以使用的hack。我编译为Java8标准

我为每个值计算
JTextArea
的大小。计算有点不精确,取决于
getRootComponent
方法中设置的
JPanel
的首选大小,以及
JTextArea
中文本使用的字体

这是我测试的代码

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.util.Arrays;

import javax.swing.DefaultListModel;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;

public class TextAreaListTest implements ListCellRenderer<String> {
    // Arbitrary long string
    private static final String LORUM_IPSUM = "Lorem ipsum dolor sit amet, consectetur "
            + "adipiscing elit. Sed sit amet est eget mauris tempus vehicula. "
            + "Nunc aliquet quis mi vitae fringilla. Aliquam laoreet eu metus "
            + "sit amet iaculis. Curabitur imperdiet eu est et lobortis. Mauris "
            + "eget est id lorem iaculis dictum. Aenean nisi libero, consectetur "
            + "quis enim sed, pulvinar facilisis erat. Aliquam euismod nulla et "
            + "dictum dictum. Etiam non ullamcorper sem. Nulla efficitur, quam "
            + "cursus molestie euismod, dui lorem congue mi, placerat blandit "
            + "turpis ex id libero. Nullam sit amet porta purus. Mauris scelerisque "
            + "justo non orci vehicula, sed mattis sapien cursus. Aenean at porttitor "
            + "dolor. Aenean euismod massa et libero egestas, sed lacinia eros aliquet. "
            + "In tincidunt vehicula ex, a sollicitudin justo consequat ac. In in "
            + "purus ut ligula sollicitudin porta quis eu neque. Aliquam erat volutpat.";

    private static JPanel rootPanel;
    
    @Override
    public Component getListCellRendererComponent(JList<? extends String> list, 
            String value, int index, boolean isSelected, boolean cellHasFocus) {
        int width = rootPanel.getWidth() / 6;
        int lines = value.length() / width + 1;
        
        JTextArea textArea = new JTextArea(lines, width / 2);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        textArea.setText(value);

        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        panel.add(new JLabel("Header label"), BorderLayout.BEFORE_FIRST_LINE);
        panel.add(textArea, BorderLayout.CENTER);
        return panel;
    }

    public static JComponent getRootComponent() {
        DefaultListModel<String> listModel = new DefaultListModel<>();
        listModel.addAll(Arrays.asList("A short string", LORUM_IPSUM, 
                "A second short string", LORUM_IPSUM));

        JList<String> list = new JList<>();
        list.setModel(listModel);
        list.setCellRenderer(new TextAreaListTest());

        JScrollPane scrollPane = new JScrollPane(list);
        
        rootPanel = new JPanel(new BorderLayout());
        rootPanel.setPreferredSize(new Dimension(400, 400));
        rootPanel.add(scrollPane, BorderLayout.CENTER);
        return rootPanel;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("TextArea List Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(getRootComponent(), BorderLayout.CENTER);
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);
            }
        });
    }
}
导入java.awt.BorderLayout;
导入java.awt.Component;
导入java.awt.Dimension;
导入java.util.array;
导入javax.swing.DefaultListModel;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JList;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JTextArea;
导入javax.swing.ListCellRenderer;
导入javax.swing.SwingUtilities;
公共类TextAreaListTest实现ListCellRenderer{
//任意长字符串
私有静态最终字符串LORUM_IPSUM=“Lorem IPSUM Door sit amet,Concertetur”
+“一位精英,坐在我的车上。”
+“我的生命在流苏,我的生命在流苏”
+“坐在阿梅特·亚库利斯(amet iaculis)、库拉比图尔(Curabitur imperdiet)和洛博蒂斯(lobortis)、莫里斯(Mauris)”
+“这是我的至理名言,是自由主义者的至理名言”
+“这是一个很好的例子,是一个很好的例子。”
+“我的名言不是乌拉姆·科珀的,我的名言是无效的”
+“我的朋友们,我的朋友们,我的朋友们”
+“turpis ex id libero.Nullam坐在purus门上,Mauris scelerisque”
+“只有非奥奇人的车辆,塞德·马蒂斯·萨皮恩·库苏斯。埃尼安在港口”
+“多洛·埃尼安·尤伊斯莫·马萨和自由女神埃格斯塔斯,塞德·拉西尼亚·厄洛斯·阿利奎特。”
+“在tincidunt Vehiclula ex中,一辆仅用于交流的汽车”
+“这是一种新的生活方式,是一种生活方式。”;
私有静态JPanel根面板;
@凌驾

公共组件GetListCellRenderComponent(JLI使用单列JTable。JTable已经支持允许每行具有单独高度的概念,这使得渲染更容易。请参阅:注意,渲染器不应该一直创建组件的实例。您应该有一个单独的文本区域和面板,然后只需替换文本区域中的文本。感谢您的回答,un幸运的是,这并不能完全起作用:列表项最初确实采用了正确的大小,但在调整框架大小时,它们的高度不会改变,并且它们遇到了与我的示例相同的问题。