简体   繁体   English

根据内容展开JList行高

[英]Expand JList row height depending on content

I have a simple problem which totally drives me crazy. 我有一个简单的问题让我疯狂。

I have a JList, and would like its cells to expand depending on their content, which is text of variable length. 我有一个JList,并希望它的单元格根据其内容进行扩展,这是可变长度的文本。

So I created a CustomCellRenderer like so: 所以我创建了一个CustomCellRenderer,如下所示:

@Override
public Component getListCellRendererComponent(final JList list, final Object value, final int index, final boolean isSelected, final boolean hasFocus)
{
    final String text = (String) value;

    final JTextArea ta = new JTextArea();
    ta.setText(text);
    ta.setFont(new Font("Dialog", Font.PLAIN, (int) Theme.FONTSIZE_TEXT));
    ta.setForeground(Theme.FONTCOLOR_CONTENT);
    ta.setLineWrap(true);
    ta.setWrapStyleWord(true);
    ta.setColumns(0);
    ta.setBorder(BorderFactory.createEmptyBorder(10, Theme.PADDING, 0, 0));
    return ta;
}

but the cells are only one text line high and the rest of the JTextArea is cut off. 但是单元格只有一个文本行高,而JTextArea的其余部分被截断。 If I add 如果我加

ta.setPreferredSize(new Dimension(0, 70));

I get a row height of 70 and I can see more of the JTextArea's text, but still not everything. 我的行高为70,我可以看到更多JTextArea的文本,但仍然不是一切。

Is there any way to make JList expand its cells so that the whole content of the JTextArea is displayed? 有没有办法让JList扩展其单元格,以便显示JTextArea的整个内容?

there are maybe easiest and nicest way, I think that JTable with one TableColumn (and without TableHeader)in all cases better as JList , here is your Render MacOX version 可能有最简单和最好的方式,我认为JTable与一个TableColumn(并且没有TableHeader)在所有情况下都更好地作为JList ,这里是你的Render MacOX版本

then output should be 那么输出应该是

在此输入图像描述

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.*;
//http://tips4java.wordpress.com/2008/10/26/text-utilities/
public class AutoWrapTest {

    public JComponent makeUI() {
        String[] columnNames = {" Text Area Cell Renderer "};
        Object[][] data = {
            {"123456789012345678901234567890"},
            {"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddx"},
            {"----------------------------------------------0"},
            {">>>>>>>>>>>>>dddddddddddddddddddddddddddddddddddddddddddddddddd"
                + "dddddddxdddddddddddddddddddddddddddddddddddddddddddddd"
                + "dddddddddddx>>>>>>>>>>>>>>>>>>>>>>>>>|"},
            {">>>>>>>>>>>>ddddddddddddddddddddddddddddddddddddddddddddddddddd"
                + "ddddddx>>>>>>>>>>>>>>>>>>>>>>>>>>|"},
            {"a|"},
            {">>>>>>>>bbbb>>>>>>>>>>>>>>>>>>>|"},
            {">>>>>>>>>>>>>>>>>>|"},
            {">>>>>>>>>>>>>dddddddddddddddddddddddddddddddddddddddddddddddddd"
                + "dddddddxdddddddddddddd123456789012345678901234567890dddddd"
                + "dddddddddddddddddddddddddddddddddddddx>>>>>>>>>>>>>>>>>>>>"
                + ">>>>>|"},
            {">>>>>>>>>>>>>dddddddddddddd123456789012345678901234567890dddddd"
                + "dddddddddddddddddddddddddddddddddddddxdddddddddddddd123456"
                + "789012345678901234567890dddddddddddddddddddddddddddddddddd"
                + "ddddd123456789012345678901234567890ddddx>>>>>>>>>>>>>>>>>>"
                + ">>>>>>>|"},};
        TableModel model = new DefaultTableModel(data, columnNames) {

            private static final long serialVersionUID = 1L;

            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };
        JTable table = new JTable(model) {

            private static final long serialVersionUID = 1L;

            @Override
            public void doLayout() {
                TableColumn col = getColumnModel().getColumn(0);
                for (int row = 0; row < getRowCount(); row++) {
                    Component c = prepareRenderer(col.getCellRenderer(), row, 0);
                    if (c instanceof JTextArea) {
                        JTextArea a = (JTextArea) c;
                        int h = getPreferredHeight(a) + getIntercellSpacing().height;
                        if (getRowHeight(row) != h) {
                            setRowHeight(row, h);
                        }
                    }
                }
                super.doLayout();
            }

            private int getPreferredHeight(JTextComponent c) {
                Insets insets = c.getInsets();
                View view = c.getUI().getRootView(c).getView(0);
                int preferredHeight = (int) view.getPreferredSpan(View.Y_AXIS);
                return preferredHeight + insets.top + insets.bottom;
            }
        };
        table.setEnabled(false);
        table.setShowGrid(false);
        table.setTableHeader(null);
        table.getColumnModel().getColumn(0).setCellRenderer(new TextAreaCellRenderer());
        //table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane sp = new JScrollPane(table);
        sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        sp.setPreferredSize(new Dimension(250, 533));
        JPanel p = new JPanel(new BorderLayout());
        p.add(sp);
        return p;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }

    public static void createAndShowGUI() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.getContentPane().add(new AutoWrapTest().makeUI());
        f.setLocation(100, 100);
        f.pack();
        f.setVisible(true);
    }
}

class TextAreaCellRenderer extends JTextArea implements TableCellRenderer {

    private static final long serialVersionUID = 1L;
    private final Color evenColor = new Color(230, 240, 255);

    public TextAreaCellRenderer() {
        super();
        setLineWrap(true);
        setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        if (isSelected) {
            setForeground(table.getSelectionForeground());
            setBackground(table.getSelectionBackground());
        } else {
            setForeground(table.getForeground());
            setBackground(table.getBackground());
            setBackground((row % 2 == 0) ? evenColor : getBackground());
        }
        setFont(table.getFont());
        setText((value == null) ? "" : value.toString());
        return this;
    }
}

Not sure if there is an elegant way. 不确定是否有一种优雅的方式。 One way that I know works is as follows : In getListCellRendererComponent() 我所知道的一种方法如下:在getListCellRendererComponent()

  • Use JLabel for the renderer 将JLabel用于渲染器
  • Convert the text in question to HTML and use some logic to insert <br> in to the text where desired. 将有问题的文本转换为HTML并使用一些逻辑将<br>插入到所需的文本中。
  • Then set the text as text for the JLabel component and return. 然后将文本设置为JLabel组件的文本并返回。

尝试使用JList的setFixedCellHeight()方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM