根据内容展开JList行高

时间:2011-08-01 16:02:59

标签: java swing height row jlist

我有一个简单的问题让我疯狂。

我有一个JList,并希望它的单元格根据其内容进行扩展,这是可变长度的文本。

所以我创建了一个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;
}

但是单元格只有一个文本行高,而JTextArea的其余部分被截断。如果我添加

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

我的行高为70,我可以看到更多JTextArea的文本,但仍然不是一切。

有没有办法让JList扩展其单元格,以便显示JTextArea的整个内容?

3 个答案:

答案 0 :(得分:5)

可能有最简单,最好的方式,我认为JTable一个TableColumn(并且没有TableHeader)在所有情况下都更好JList,这是你的Render MacOX version

然后输出

enter image description here

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;
    }
}

答案 1 :(得分:2)

不确定是否有一种优雅的方式。 我所知道的一种方式如下: 在getListCellRendererComponent()

  • 将JLabel用于渲染器
  • 将相关文字转换为HTML和 使用一些逻辑将<br>插入到所需的文本中。
  • 然后将文本设置为JLabel组件的文本并返回。

答案 2 :(得分:1)

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