I am trying to implement a table cell editor which displays mutliple lines of text in a single cell, which also allows the user to tab through the cells and edit without clicking.
So I created a tablecelleditor with a JTextArea in a JScrollPane, which works well except for the tabbing through the table cells. The problem is that when the cell is selected, typing characters on the keyboard does not start an edit (like the default editor), and when you click to edit a cell then the tab-key inserts a tab into the text rather than move the cell selection. Returning a JTextArea rather than a JScrollPane solves those 2 problems but then if the JTextArea is too big for the table cell its a problem (I don't want the table row height to expand infinately). Here is sample code which illustrates my problem, its a table with 3 columns, column 0 uses the default editor, column 1 uses a JScrollPane with a JTextArea in it, and column2 just uses a JTextArea
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.table.TableCellEditor;
public class TableTest extends JFrame {
/**
*
*/
public TableTest() {
super("Table Test");
String data[][]={ {"0","1","2"},{"3","4","5"},{"6","7","8"}};
String columns[]= {"A","B","C"};
JTable table = new JTable(data,columns) {
};
table.putClientProperty("JTable.autoStartsEdit", Boolean.TRUE);
table.setCellSelectionEnabled(true);
table.getColumnModel().getColumn(1).setCellEditor(new MultiLineTableCellEditor());
table.getColumnModel().getColumn(2).setCellEditor(new MultiLineTableCellEditor2());
getContentPane().add(new JScrollPane(table));
getContentPane().add(new JButton("OK"), BorderLayout.SOUTH);
setBounds(100,100,500,500);
setVisible(true);
}
class MultiLineTableCellEditor extends AbstractCellEditor implements TableCellEditor
{
protected JTextArea myEditor;
protected JScrollPane myScrollPane;
public MultiLineTableCellEditor() {
myEditor = new JTextArea();
myEditor.setWrapStyleWord(true);
myEditor.setLineWrap(true);
myEditor.setOpaque(true);
myEditor.setRows(3);
myScrollPane = new JScrollPane(myEditor);
myScrollPane.setBorder(BorderFactory.createEmptyBorder());
myScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
myScrollPane.getVerticalScrollBar().setFocusable(false);
myScrollPane.getHorizontalScrollBar().setFocusable(false);
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column)
{
myEditor.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
myEditor.setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
myEditor.setText(value==null ? "" : value.toString());
myScrollPane.setBounds(0,0,table.getColumnModel().getColumn(column).getWidth(), 0);
int rowHeight = table.getRowHeight(row);
int thisHeight = myScrollPane.getPreferredSize().height+2;
if (thisHeight>rowHeight) table.setRowHeight(row, thisHeight);
return myScrollPane;
}
public Object getCellEditorValue() {
return myEditor.getText();
}
}
class MultiLineTableCellEditor2 extends MultiLineTableCellEditor
{
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column)
{
super.getTableCellEditorComponent(table,value,isSelected,row,column);
return myEditor;
}
}
public static void main(String args[]) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch(Exception e){}
TableTest test = new TableTest();
test.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}