根据内容展开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的整个内容?

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

那么输出应该是

在此处输入图像描述

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

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

  • 将JLabel用于渲染器
  • 将有问题的文本转换为HTML并使用一些逻辑将
    插入到所需的文本中。
  • 然后将文本设置为JLabel组件的文本并返回。

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