如何使JTable列不包含JTextFields,而是包含JTextAreas?

请告诉我,如何使JTable列包含JTextAreas,因此当用户输入大量文本时,单元格的高度会增加,我们可以看到多行(单元格被扩展;结果,行也会扩展)

您需要根据JTextArea编写自己的单元格渲染器和编辑器:

  public class Start { public static class JTextPaneCellEditor extends AbstractCellEditor implements TableCellEditor, KeyListener { private JViewport viewport; private JTable table; private int row; private JTextPane pane; public JTextPaneCellEditor(){ viewport = new JViewport(); pane = new JTextPane(); viewport.add(pane); pane.addKeyListener(this); } @Override public Object getCellEditorValue(){ return pane.getText(); } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column){ this.table = table; this.row = row; pane.setText(value.toString()); int newHeight = (int)pane.getPreferredSize().getHeight(); if(table.getRowHeight(row) < newHeight){ table.setRowHeight(row, newHeight); } return pane; } @Override public boolean isCellEditable(EventObject e){ if (e instanceof MouseEvent) { return ((MouseEvent)e).getClickCount() >= 2; } return true; } @Override public void keyTyped(KeyEvent e){ table.setRowHeight(row, (int)pane.getPreferredSize().getHeight()); } @Override public void keyPressed(KeyEvent e){ if(e.getKeyCode() == KeyEvent.VK_ENTER){ stopCellEditing(); } } @Override public void keyReleased(KeyEvent e){ } } private static class JTextPaneCellRenderer extends JViewport implements TableCellRenderer { JTextPane pane; JTextPaneCellRenderer(){ pane = new JTextPane(); add(pane); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){ pane.setText(value.toString()); table.setRowHeight(row, (int)pane.getPreferredSize().getHeight()); return this; } } public static void main(String[] args){ JTable table = new JTable(new String[][]{{"String String String String StringString String String String StringString String String String StringString String String String StringString String String String String"}, {"String 2"}}, new String[]{"Column"}); table.setDefaultRenderer(Object.class, new JTextPaneCellRenderer()); table.setDefaultEditor(Object.class, new JTextPaneCellEditor()); JFrame test = new JFrame(); test.add(new JScrollPane(table)); test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); test.setSize(300, 300); test.setLocationRelativeTo(null); test.setVisible(true); } } 

编辑:添加视口以获得更好的大小。 但是在第一次编辑时,该行仍未展开。 有没有人有任何想法?

编辑2:我同意这些评论。 你想要的东西是可能的,但你需要未经测试的,hackish自定义实现。 如果您重新设计布局以排除此类JTable巫术,您将会感觉更好。

@Jakub Zaverka

我稍后会删除这个答案

 import java.awt.*; import javax.swing.*; import javax.swing.table.*; import javax.swing.text.*; public class AutoWrapTest { public JComponent makeUI() { String[] columnNames = {"TextAreaCellRenderer"}; Object[][] data = { {"123456789012345678901234567890"}, {"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddx"}, {"----------------------------------------------0"}, {">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>|"},}; 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(); } //http://tips4java.wordpress.com/2008/10/26/text-utilities/ 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()); JScrollPane sp = new JScrollPane(table); sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); 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.setSize(200, 200); f.setLocationRelativeTo(null); 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); setWrapStyleWord(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; } }