JTextArea in JTable as cellrenderer
Does anyone know how to use JTextArea to display/edit data in the JTable?
Many thanks,
Pippen
I have just solved the problem by writting a cellerenderer and a celleditor on the JTextArea column of the JTable, disabling the "Enter" keystroke event on the table and enabling the "Enter/CR" event on the column alone to insert the break action. Good For you!
The code is not so pretty but it works. A wise man who frequently posts in JDC forums once said something like this:
any solution that works is a good solution
BTW, if you have other workaround, pls also let me know.Thanks but no thanks...... I have written my own editors and renderers a long time ago. For a picture of my cell spanning editor, see link shown below:
http://www.aokabc.com/help/TextPane.png
;o)
V.V.
Similar Messages
-
JTextArea inside Jtable - Tab, Focus issues
I am facing the following problems with JTextArea inside Jtable Cell
1. blinking cursor not visible on the cell(0,0) first time the UI is shown, although it has the focus
2. blinking cursor not visible on the 5th column (JTextArea) when it receives the focus nor the characters are visible when i start typing. i have to manually double click to force the focus to shift to the cell.
3. focus does not shit out of the 5th column (JTextArea) after pressing the tab key or enter key once. i have to do that twice to force the focus out.
Following is the code which i have implemented. Please let me know what is being missed out to rectify the above problems.
Thanks.
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class test extends JFrame {
JTable table;
public test() {
table = new JTable(15, 5) {
public boolean isCellEditable(int row, int column) {
return column % 2 == 0;
// return true;
public void changeSelection(final int row, final int column,
boolean toggle, boolean extend) {
super.changeSelection(row, column, toggle, extend);
if (editCellAt(row, column)) {
getEditorComponent().requestFocusInWindow();
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
TextAreaRenderer textAreaRenderer = new TextAreaRenderer();
TextAreaEditor textEditor = new TextAreaEditor();
table.getColumnModel().getColumn(4).setCellRenderer(textAreaRenderer);
table.getColumnModel().getColumn(4).setCellEditor(textEditor);
JTextField tf = new JTextField();
tf.setBorder(BorderFactory.createEmptyBorder());
table.setDefaultEditor(Object.class, new DefaultCellEditor((tf)));
JScrollPane scrollPane = new JScrollPane(table);
DefaultCellEditor dce = (DefaultCellEditor) table
.getDefaultEditor(Object.class);
dce.setClickCountToStart(1);
getContentPane().add(scrollPane);
InputMap im = table
.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
// Have the enter key work the same as the tab key
KeyStroke tab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
im.put(enter, im.get(tab));
// Disable the right arrow key
KeyStroke right = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0);
im.put(right, "none");
// Override the default tab behaviour
// Tab to the next editable cell. When no editable cells goto next cell.
final Action oldTabAction = table.getActionMap().get(im.get(tab));
Action tabAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
oldTabAction.actionPerformed(e);
JTable table = (JTable) e.getSource();
int rowCount = table.getRowCount();
int columnCount = table.getColumnCount();
int row = table.getSelectedRow();
int column = table.getSelectedColumn();
while (!table.isCellEditable(row, column)) {
column += 1;
if (column == columnCount) {
column = 0;
row += 1;
if (row == rowCount) {
row = 0;
// Back to where we started, get out.
if (row == table.getSelectedRow()
&& column == table.getSelectedColumn()) {
break;
table.changeSelection(row, column, false, false);
table.getActionMap().put(im.get(tab), tabAction);
table.setSurrendersFocusOnKeystroke(true);
public static void main(String[] args) {
test frame = new test();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
import java.awt.Component;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class TextAreaRenderer extends JTextArea implements TableCellRenderer {
private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer();
/** map from table to map of rows to map of column heights */
private final Map cellSizes = new HashMap();
public TextAreaRenderer() {
setLineWrap(true);
setWrapStyleWord(true);
public Component getTableCellRendererComponent(//
JTable table, Object obj, boolean isSelected, boolean hasFocus,
int row, int column) {
// set the colours, etc. using the standard for that platform
adaptee.getTableCellRendererComponent(table, obj, isSelected, hasFocus,
row, column);
setForeground(adaptee.getForeground());
setBackground(adaptee.getBackground());
setBorder(adaptee.getBorder());
setFont(adaptee.getFont());
setText(adaptee.getText());
// This line was very important to get it working with JDK1.4
TableColumnModel columnModel = table.getColumnModel();
setSize(columnModel.getColumn(column).getWidth(), 100000);
int height_wanted = (int) getPreferredSize().getHeight();
addSize(table, row, column, height_wanted);
height_wanted = findTotalMaximumRowSize(table, row);
if (height_wanted != table.getRowHeight(row)) {
table.setRowHeight(row, height_wanted);
return this;
private void addSize(JTable table, int row, int column, int height) {
Map rows = (Map) cellSizes.get(table);
if (rows == null) {
cellSizes.put(table, rows = new HashMap());
Map rowheights = (Map) rows.get(new Integer(row));
if (rowheights == null) {
rows.put(new Integer(row), rowheights = new HashMap());
rowheights.put(new Integer(column), new Integer(height));
* Look through all columns and get the renderer. If it is also a
* TextAreaRenderer, we look at the maximum height in its hash table for
* this row.
private int findTotalMaximumRowSize(JTable table, int row) {
int maximum_height = 0;
Enumeration columns = table.getColumnModel().getColumns();
while (columns.hasMoreElements()) {
TableColumn tc = (TableColumn) columns.nextElement();
TableCellRenderer cellRenderer = tc.getCellRenderer();
if (cellRenderer instanceof TextAreaRenderer) {
TextAreaRenderer tar = (TextAreaRenderer) cellRenderer;
maximum_height = Math.max(maximum_height, tar
.findMaximumRowSize(table, row));
return maximum_height;
private int findMaximumRowSize(JTable table, int row) {
Map rows = (Map) cellSizes.get(table);
if (rows == null)
return 0;
Map rowheights = (Map) rows.get(new Integer(row));
if (rowheights == null)
return 0;
int maximum_height = 0;
for (Iterator it = rowheights.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
int cellHeight = ((Integer) entry.getValue()).intValue();
maximum_height = Math.max(maximum_height, cellHeight);
return maximum_height;
import java.awt.KeyboardFocusManager;
import java.awt.event.FocusEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;
import javax.swing.DefaultCellEditor;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class TextAreaEditor extends DefaultCellEditor {
public TextAreaEditor() {
super(new JTextField());
final JTextArea textArea = new JTextArea();
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setBorder(null);
Set forwardTraversalKeys = new HashSet();
forwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
textArea.setFocusTraversalKeys(
KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
forwardTraversalKeys);
Set backwardTraversalKeys = new HashSet();
backwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
InputEvent.SHIFT_MASK));
textArea.setFocusTraversalKeys(
KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
backwardTraversalKeys);
scrollPane.getVerticalScrollBar().setFocusable(false);
scrollPane.getVerticalScrollBar().setFocusable(false);
editorComponent = scrollPane;
delegate = new DefaultCellEditor.EditorDelegate() {
public void setValue(Object value) {
textArea.setText((value != null) ? value.toString() : "");
public Object getCellEditorValue() {
return textArea.getText();
public void lostFocus() {
stopCellEditing();
--------------------------------------------I am facing the following problems with JTextArea inside Jtable Cell
1. blinking cursor not visible on the cell(0,0) first time the UI is shown, although it has the focus
2. blinking cursor not visible on the 5th column (JTextArea) when it receives the focus nor the characters are visible when i start typing. i have to manually double click to force the focus to shift to the cell.
3. focus does not shit out of the 5th column (JTextArea) after pressing the tab key or enter key once. i have to do that twice to force the focus out.
Following is the code which i have implemented. Please let me know what is being missed out to rectify the above problems.
Thanks.
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class test extends JFrame {
JTable table;
public test() {
table = new JTable(15, 5) {
public boolean isCellEditable(int row, int column) {
return column % 2 == 0;
// return true;
public void changeSelection(final int row, final int column,
boolean toggle, boolean extend) {
super.changeSelection(row, column, toggle, extend);
if (editCellAt(row, column)) {
getEditorComponent().requestFocusInWindow();
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
TextAreaRenderer textAreaRenderer = new TextAreaRenderer();
TextAreaEditor textEditor = new TextAreaEditor();
table.getColumnModel().getColumn(4).setCellRenderer(textAreaRenderer);
table.getColumnModel().getColumn(4).setCellEditor(textEditor);
JTextField tf = new JTextField();
tf.setBorder(BorderFactory.createEmptyBorder());
table.setDefaultEditor(Object.class, new DefaultCellEditor((tf)));
JScrollPane scrollPane = new JScrollPane(table);
DefaultCellEditor dce = (DefaultCellEditor) table
.getDefaultEditor(Object.class);
dce.setClickCountToStart(1);
getContentPane().add(scrollPane);
InputMap im = table
.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
// Have the enter key work the same as the tab key
KeyStroke tab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
im.put(enter, im.get(tab));
// Disable the right arrow key
KeyStroke right = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0);
im.put(right, "none");
// Override the default tab behaviour
// Tab to the next editable cell. When no editable cells goto next cell.
final Action oldTabAction = table.getActionMap().get(im.get(tab));
Action tabAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
oldTabAction.actionPerformed(e);
JTable table = (JTable) e.getSource();
int rowCount = table.getRowCount();
int columnCount = table.getColumnCount();
int row = table.getSelectedRow();
int column = table.getSelectedColumn();
while (!table.isCellEditable(row, column)) {
column += 1;
if (column == columnCount) {
column = 0;
row += 1;
if (row == rowCount) {
row = 0;
// Back to where we started, get out.
if (row == table.getSelectedRow()
&& column == table.getSelectedColumn()) {
break;
table.changeSelection(row, column, false, false);
table.getActionMap().put(im.get(tab), tabAction);
table.setSurrendersFocusOnKeystroke(true);
public static void main(String[] args) {
test frame = new test();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
import java.awt.Component;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class TextAreaRenderer extends JTextArea implements TableCellRenderer {
private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer();
/** map from table to map of rows to map of column heights */
private final Map cellSizes = new HashMap();
public TextAreaRenderer() {
setLineWrap(true);
setWrapStyleWord(true);
public Component getTableCellRendererComponent(//
JTable table, Object obj, boolean isSelected, boolean hasFocus,
int row, int column) {
// set the colours, etc. using the standard for that platform
adaptee.getTableCellRendererComponent(table, obj, isSelected, hasFocus,
row, column);
setForeground(adaptee.getForeground());
setBackground(adaptee.getBackground());
setBorder(adaptee.getBorder());
setFont(adaptee.getFont());
setText(adaptee.getText());
// This line was very important to get it working with JDK1.4
TableColumnModel columnModel = table.getColumnModel();
setSize(columnModel.getColumn(column).getWidth(), 100000);
int height_wanted = (int) getPreferredSize().getHeight();
addSize(table, row, column, height_wanted);
height_wanted = findTotalMaximumRowSize(table, row);
if (height_wanted != table.getRowHeight(row)) {
table.setRowHeight(row, height_wanted);
return this;
private void addSize(JTable table, int row, int column, int height) {
Map rows = (Map) cellSizes.get(table);
if (rows == null) {
cellSizes.put(table, rows = new HashMap());
Map rowheights = (Map) rows.get(new Integer(row));
if (rowheights == null) {
rows.put(new Integer(row), rowheights = new HashMap());
rowheights.put(new Integer(column), new Integer(height));
* Look through all columns and get the renderer. If it is also a
* TextAreaRenderer, we look at the maximum height in its hash table for
* this row.
private int findTotalMaximumRowSize(JTable table, int row) {
int maximum_height = 0;
Enumeration columns = table.getColumnModel().getColumns();
while (columns.hasMoreElements()) {
TableColumn tc = (TableColumn) columns.nextElement();
TableCellRenderer cellRenderer = tc.getCellRenderer();
if (cellRenderer instanceof TextAreaRenderer) {
TextAreaRenderer tar = (TextAreaRenderer) cellRenderer;
maximum_height = Math.max(maximum_height, tar
.findMaximumRowSize(table, row));
return maximum_height;
private int findMaximumRowSize(JTable table, int row) {
Map rows = (Map) cellSizes.get(table);
if (rows == null)
return 0;
Map rowheights = (Map) rows.get(new Integer(row));
if (rowheights == null)
return 0;
int maximum_height = 0;
for (Iterator it = rowheights.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
int cellHeight = ((Integer) entry.getValue()).intValue();
maximum_height = Math.max(maximum_height, cellHeight);
return maximum_height;
import java.awt.KeyboardFocusManager;
import java.awt.event.FocusEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;
import javax.swing.DefaultCellEditor;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class TextAreaEditor extends DefaultCellEditor {
public TextAreaEditor() {
super(new JTextField());
final JTextArea textArea = new JTextArea();
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setBorder(null);
Set forwardTraversalKeys = new HashSet();
forwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
textArea.setFocusTraversalKeys(
KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
forwardTraversalKeys);
Set backwardTraversalKeys = new HashSet();
backwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
InputEvent.SHIFT_MASK));
textArea.setFocusTraversalKeys(
KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
backwardTraversalKeys);
scrollPane.getVerticalScrollBar().setFocusable(false);
scrollPane.getVerticalScrollBar().setFocusable(false);
editorComponent = scrollPane;
delegate = new DefaultCellEditor.EditorDelegate() {
public void setValue(Object value) {
textArea.setText((value != null) ? value.toString() : "");
public Object getCellEditorValue() {
return textArea.getText();
public void lostFocus() {
stopCellEditing();
-------------------------------------------- -
Reposting - JTextArea inside Jtable - Tab, Focus issues
Sorry for reposting this again...I didn't format the code in my previous post.
I am facing the following problems with JTextArea inside Jtable Cell
1. blinking cursor not visible on the cell(0,0) first time the UI is shown, although it has the focus
2. blinking cursor not visible on the 5th column (JTextArea) when it receives the focus nor the characters are visible when i start typing. i have to manually double click to force the focus to shift to the cell.
3. focus does not shit out of the 5th column (JTextArea) after pressing the tab key or enter key once. i have to do that twice to force the focus out.
Following is the code which i have implemented. Please let me know what is being missed out to rectify the above problems.
Thanks.
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class test extends JFrame {
JTable table;
public test() {
table = new JTable(15, 5) {
public boolean isCellEditable(int row, int column) {
return column % 2 == 0;
// return true;
public void changeSelection(final int row, final int column,
boolean toggle, boolean extend) {
super.changeSelection(row, column, toggle, extend);
if (editCellAt(row, column)) {
getEditorComponent().requestFocusInWindow();
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
TextAreaRenderer textAreaRenderer = new TextAreaRenderer();
TextAreaEditor textEditor = new TextAreaEditor();
table.getColumnModel().getColumn(4).setCellRenderer(textAreaRenderer);
table.getColumnModel().getColumn(4).setCellEditor(textEditor);
JTextField tf = new JTextField();
tf.setBorder(BorderFactory.createEmptyBorder());
table.setDefaultEditor(Object.class, new DefaultCellEditor((tf)));
JScrollPane scrollPane = new JScrollPane(table);
DefaultCellEditor dce = (DefaultCellEditor) table
.getDefaultEditor(Object.class);
dce.setClickCountToStart(1);
getContentPane().add(scrollPane);
InputMap im = table
.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
// Have the enter key work the same as the tab key
KeyStroke tab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
im.put(enter, im.get(tab));
// Disable the right arrow key
KeyStroke right = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0);
im.put(right, "none");
// Override the default tab behaviour
// Tab to the next editable cell. When no editable cells goto next cell.
final Action oldTabAction = table.getActionMap().get(im.get(tab));
Action tabAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
oldTabAction.actionPerformed(e);
JTable table = (JTable) e.getSource();
int rowCount = table.getRowCount();
int columnCount = table.getColumnCount();
int row = table.getSelectedRow();
int column = table.getSelectedColumn();
while (!table.isCellEditable(row, column)) {
column += 1;
if (column == columnCount) {
column = 0;
row += 1;
if (row == rowCount) {
row = 0;
// Back to where we started, get out.
if (row == table.getSelectedRow()
&& column == table.getSelectedColumn()) {
break;
table.changeSelection(row, column, false, false);
table.getActionMap().put(im.get(tab), tabAction);
table.setSurrendersFocusOnKeystroke(true);
public static void main(String[] args) {
test frame = new test();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
import java.awt.Component;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class TextAreaRenderer extends JTextArea implements TableCellRenderer {
private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer();
/** map from table to map of rows to map of column heights */
private final Map cellSizes = new HashMap();
public TextAreaRenderer() {
setLineWrap(true);
setWrapStyleWord(true);
public Component getTableCellRendererComponent(//
JTable table, Object obj, boolean isSelected, boolean hasFocus,
int row, int column) {
// set the colours, etc. using the standard for that platform
adaptee.getTableCellRendererComponent(table, obj, isSelected, hasFocus,
row, column);
setForeground(adaptee.getForeground());
setBackground(adaptee.getBackground());
setBorder(adaptee.getBorder());
setFont(adaptee.getFont());
setText(adaptee.getText());
// This line was very important to get it working with JDK1.4
TableColumnModel columnModel = table.getColumnModel();
setSize(columnModel.getColumn(column).getWidth(), 100000);
int height_wanted = (int) getPreferredSize().getHeight();
addSize(table, row, column, height_wanted);
height_wanted = findTotalMaximumRowSize(table, row);
if (height_wanted != table.getRowHeight(row)) {
table.setRowHeight(row, height_wanted);
return this;
private void addSize(JTable table, int row, int column, int height) {
Map rows = (Map) cellSizes.get(table);
if (rows == null) {
cellSizes.put(table, rows = new HashMap());
Map rowheights = (Map) rows.get(new Integer(row));
if (rowheights == null) {
rows.put(new Integer(row), rowheights = new HashMap());
rowheights.put(new Integer(column), new Integer(height));
* Look through all columns and get the renderer. If it is also a
* TextAreaRenderer, we look at the maximum height in its hash table for
* this row.
private int findTotalMaximumRowSize(JTable table, int row) {
int maximum_height = 0;
Enumeration columns = table.getColumnModel().getColumns();
while (columns.hasMoreElements()) {
TableColumn tc = (TableColumn) columns.nextElement();
TableCellRenderer cellRenderer = tc.getCellRenderer();
if (cellRenderer instanceof TextAreaRenderer) {
TextAreaRenderer tar = (TextAreaRenderer) cellRenderer;
maximum_height = Math.max(maximum_height, tar
.findMaximumRowSize(table, row));
return maximum_height;
private int findMaximumRowSize(JTable table, int row) {
Map rows = (Map) cellSizes.get(table);
if (rows == null)
return 0;
Map rowheights = (Map) rows.get(new Integer(row));
if (rowheights == null)
return 0;
int maximum_height = 0;
for (Iterator it = rowheights.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
int cellHeight = ((Integer) entry.getValue()).intValue();
maximum_height = Math.max(maximum_height, cellHeight);
return maximum_height;
import java.awt.KeyboardFocusManager;
import java.awt.event.FocusEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;
import javax.swing.DefaultCellEditor;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class TextAreaEditor extends DefaultCellEditor {
public TextAreaEditor() {
super(new JTextField());
final JTextArea textArea = new JTextArea();
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setBorder(null);
Set forwardTraversalKeys = new HashSet();
forwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
textArea.setFocusTraversalKeys(
KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
forwardTraversalKeys);
Set backwardTraversalKeys = new HashSet();
backwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
InputEvent.SHIFT_MASK));
textArea.setFocusTraversalKeys(
KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
backwardTraversalKeys);
scrollPane.getVerticalScrollBar().setFocusable(false);
scrollPane.getVerticalScrollBar().setFocusable(false);
editorComponent = scrollPane;
delegate = new DefaultCellEditor.EditorDelegate() {
public void setValue(Object value) {
textArea.setText((value != null) ? value.toString() : "");
public Object getCellEditorValue() {
return textArea.getText();
public void lostFocus() {
stopCellEditing();
}Sorry for reposting this again...I didn't format the code in my previous post.
I am facing the following problems with JTextArea inside Jtable Cell
1. blinking cursor not visible on the cell(0,0) first time the UI is shown, although it has the focus
2. blinking cursor not visible on the 5th column (JTextArea) when it receives the focus nor the characters are visible when i start typing. i have to manually double click to force the focus to shift to the cell.
3. focus does not shit out of the 5th column (JTextArea) after pressing the tab key or enter key once. i have to do that twice to force the focus out.
Following is the code which i have implemented. Please let me know what is being missed out to rectify the above problems.
Thanks.
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class test extends JFrame {
JTable table;
public test() {
table = new JTable(15, 5) {
public boolean isCellEditable(int row, int column) {
return column % 2 == 0;
// return true;
public void changeSelection(final int row, final int column,
boolean toggle, boolean extend) {
super.changeSelection(row, column, toggle, extend);
if (editCellAt(row, column)) {
getEditorComponent().requestFocusInWindow();
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
TextAreaRenderer textAreaRenderer = new TextAreaRenderer();
TextAreaEditor textEditor = new TextAreaEditor();
table.getColumnModel().getColumn(4).setCellRenderer(textAreaRenderer);
table.getColumnModel().getColumn(4).setCellEditor(textEditor);
JTextField tf = new JTextField();
tf.setBorder(BorderFactory.createEmptyBorder());
table.setDefaultEditor(Object.class, new DefaultCellEditor((tf)));
JScrollPane scrollPane = new JScrollPane(table);
DefaultCellEditor dce = (DefaultCellEditor) table
.getDefaultEditor(Object.class);
dce.setClickCountToStart(1);
getContentPane().add(scrollPane);
InputMap im = table
.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
// Have the enter key work the same as the tab key
KeyStroke tab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
im.put(enter, im.get(tab));
// Disable the right arrow key
KeyStroke right = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0);
im.put(right, "none");
// Override the default tab behaviour
// Tab to the next editable cell. When no editable cells goto next cell.
final Action oldTabAction = table.getActionMap().get(im.get(tab));
Action tabAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
oldTabAction.actionPerformed(e);
JTable table = (JTable) e.getSource();
int rowCount = table.getRowCount();
int columnCount = table.getColumnCount();
int row = table.getSelectedRow();
int column = table.getSelectedColumn();
while (!table.isCellEditable(row, column)) {
column += 1;
if (column == columnCount) {
column = 0;
row += 1;
if (row == rowCount) {
row = 0;
// Back to where we started, get out.
if (row == table.getSelectedRow()
&& column == table.getSelectedColumn()) {
break;
table.changeSelection(row, column, false, false);
table.getActionMap().put(im.get(tab), tabAction);
table.setSurrendersFocusOnKeystroke(true);
public static void main(String[] args) {
test frame = new test();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
import java.awt.Component;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class TextAreaRenderer extends JTextArea implements TableCellRenderer {
private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer();
/** map from table to map of rows to map of column heights */
private final Map cellSizes = new HashMap();
public TextAreaRenderer() {
setLineWrap(true);
setWrapStyleWord(true);
public Component getTableCellRendererComponent(//
JTable table, Object obj, boolean isSelected, boolean hasFocus,
int row, int column) {
// set the colours, etc. using the standard for that platform
adaptee.getTableCellRendererComponent(table, obj, isSelected, hasFocus,
row, column);
setForeground(adaptee.getForeground());
setBackground(adaptee.getBackground());
setBorder(adaptee.getBorder());
setFont(adaptee.getFont());
setText(adaptee.getText());
// This line was very important to get it working with JDK1.4
TableColumnModel columnModel = table.getColumnModel();
setSize(columnModel.getColumn(column).getWidth(), 100000);
int height_wanted = (int) getPreferredSize().getHeight();
addSize(table, row, column, height_wanted);
height_wanted = findTotalMaximumRowSize(table, row);
if (height_wanted != table.getRowHeight(row)) {
table.setRowHeight(row, height_wanted);
return this;
private void addSize(JTable table, int row, int column, int height) {
Map rows = (Map) cellSizes.get(table);
if (rows == null) {
cellSizes.put(table, rows = new HashMap());
Map rowheights = (Map) rows.get(new Integer(row));
if (rowheights == null) {
rows.put(new Integer(row), rowheights = new HashMap());
rowheights.put(new Integer(column), new Integer(height));
* Look through all columns and get the renderer. If it is also a
* TextAreaRenderer, we look at the maximum height in its hash table for
* this row.
private int findTotalMaximumRowSize(JTable table, int row) {
int maximum_height = 0;
Enumeration columns = table.getColumnModel().getColumns();
while (columns.hasMoreElements()) {
TableColumn tc = (TableColumn) columns.nextElement();
TableCellRenderer cellRenderer = tc.getCellRenderer();
if (cellRenderer instanceof TextAreaRenderer) {
TextAreaRenderer tar = (TextAreaRenderer) cellRenderer;
maximum_height = Math.max(maximum_height, tar
.findMaximumRowSize(table, row));
return maximum_height;
private int findMaximumRowSize(JTable table, int row) {
Map rows = (Map) cellSizes.get(table);
if (rows == null)
return 0;
Map rowheights = (Map) rows.get(new Integer(row));
if (rowheights == null)
return 0;
int maximum_height = 0;
for (Iterator it = rowheights.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
int cellHeight = ((Integer) entry.getValue()).intValue();
maximum_height = Math.max(maximum_height, cellHeight);
return maximum_height;
import java.awt.KeyboardFocusManager;
import java.awt.event.FocusEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;
import javax.swing.DefaultCellEditor;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class TextAreaEditor extends DefaultCellEditor {
public TextAreaEditor() {
super(new JTextField());
final JTextArea textArea = new JTextArea();
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setBorder(null);
Set forwardTraversalKeys = new HashSet();
forwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
textArea.setFocusTraversalKeys(
KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
forwardTraversalKeys);
Set backwardTraversalKeys = new HashSet();
backwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
InputEvent.SHIFT_MASK));
textArea.setFocusTraversalKeys(
KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
backwardTraversalKeys);
scrollPane.getVerticalScrollBar().setFocusable(false);
scrollPane.getVerticalScrollBar().setFocusable(false);
editorComponent = scrollPane;
delegate = new DefaultCellEditor.EditorDelegate() {
public void setValue(Object value) {
textArea.setText((value != null) ? value.toString() : "");
public Object getCellEditorValue() {
return textArea.getText();
public void lostFocus() {
stopCellEditing();
} -
Document Listener for JTextArea in JTable
I am trying to implement a DocumentListener for JTextArea in JTable, but its not happening.
Can someone tell me what's wrong. SSCCE below.
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.text.Document;
public class MyTable_TextArea extends JTable {
private DefaultTableModel defaultTableModel;
private Object[][] dataArray;
private Object[] columnNameArray;
public final int TEXT_COLUMN = 0;
// column headers
public static final String TEXT_COLUMN_HEADER = "Text";
// text area
TextFieldRenderer3 textFieldRenderer3;
* constructor
* @param variableNameArray
* @param columnNameArray
public MyTable_TextArea(Object[][] variableNameArray, Object[] columnNameArray) {
this.dataArray = variableNameArray;
this.columnNameArray = columnNameArray;
defaultTableModel = new DefaultTableModel(variableNameArray, columnNameArray);
this.setModel(defaultTableModel) ;
// text field
textFieldRenderer3 = new TextFieldRenderer3();
MyDocumentListener myListener = new MyDocumentListener();
textFieldRenderer3.getDocument().addDocumentListener(myListener);
TableColumn modelColumn = this.getColumnModel().getColumn(TEXT_COLUMN);
modelColumn.setCellRenderer(textFieldRenderer3);
* nested class
class MyDocumentListener implements DocumentListener {
String newline = "\n";
public void insertUpdate(DocumentEvent e) {
System.out.println ("insert update");
updateLog(e, "inserted into");
public void removeUpdate(DocumentEvent e) {
System.out.println ("remove update");
updateLog(e, "removed from");
public void changedUpdate(DocumentEvent e) {
//Plain text components do not fire these events
public void updateLog(DocumentEvent e, String action) {
Document doc = (Document)e.getDocument();
int changeLength = e.getLength();
textFieldRenderer3.append(
changeLength + " character" +
((changeLength == 1) ? " " : "s ") +
action + doc.getProperty("name") + "." + newline +
" Text length = " + doc.getLength() + newline);
* @param args
public static void main(String[] args) {
try{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
catch (Exception e){
e.printStackTrace();
String[] columnNameArray = {
TEXT_COLUMN_HEADER,
"1",
"2",
Object[][] dataArray = { {"", "", ""}, };
final MyTable_TextArea panel = new MyTable_TextArea(dataArray, columnNameArray);
final JFrame frame = new JFrame();
frame.getContentPane().add(new JScrollPane(panel));
frame.setTitle("My Table");
frame.setPreferredSize(new Dimension(500, 200));
frame.addWindowListener(new WindowAdapter(){
@Override
public void windowClosing(WindowEvent e) {
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocation(300, 200);
frame.pack();
frame.setVisible(true);
class TextFieldRenderer3 extends JTextArea implements TableCellRenderer {
Icon defaultIcon;
boolean isChecked = false;
public TextFieldRenderer3() {
System.out.println ("TextFieldRenderer()");
setToolTipText("Double click to type");
@Override
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
System.out.println ("TextFieldRenderer.getTableCellRendererComponent() row/column: " + row + "\t"+ column);
return this;
}I've implemented in the cell editor. I don't see how to get the value being typed (and nothing appears in the text area)
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.EventObject;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.event.CellEditorListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.text.Document;
public class MyTable_TextArea extends JTable {
private DefaultTableModel defaultTableModel;
private Object[][] dataArray;
private Object[] columnNameArray;
public final int TEXT_COLUMN = 0;
// column headers
public static final String TEXT_COLUMN_HEADER = "Text";
// text area
TextAreaEditor textAreaEditor;
* constructor
* @param variableNameArray
* @param columnNameArray
public MyTable_TextArea(Object[][] variableNameArray, Object[] columnNameArray) {
this.dataArray = variableNameArray;
this.columnNameArray = columnNameArray;
defaultTableModel = new DefaultTableModel(variableNameArray, columnNameArray);
this.setModel(defaultTableModel) ;
// text field
textAreaEditor = new TextAreaEditor();
MyDocumentListener myListener = new MyDocumentListener();
textAreaEditor.getDocument().addDocumentListener(myListener);
TableColumn modelColumn = this.getColumnModel().getColumn(TEXT_COLUMN);
modelColumn.setCellEditor(textAreaEditor);
* nested class
class MyDocumentListener implements DocumentListener {
String newline = "\n";
public void insertUpdate(DocumentEvent e) {
System.out.println ("insert update");
updateLog(e, "inserted into");
public void removeUpdate(DocumentEvent e) {
System.out.println ("remove update");
updateLog(e, "removed from");
public void changedUpdate(DocumentEvent e) {
//Plain text components do not fire these events
public void updateLog(DocumentEvent e, String action) {
Document doc = (Document)e.getDocument();
int changeLength = e.getLength();
textAreaEditor.append(
changeLength + " character" +
((changeLength == 1) ? " " : "s ") +
action + doc.getProperty("name") + "." + newline +
" Text length = " + doc.getLength() + newline);
* @param args
public static void main(String[] args) {
try{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
catch (Exception e){
e.printStackTrace();
String[] columnNameArray = {
TEXT_COLUMN_HEADER,
"1",
"2",
Object[][] dataArray = { {"", "", ""}, };
final MyTable_TextArea panel = new MyTable_TextArea(dataArray, columnNameArray);
final JFrame frame = new JFrame();
frame.getContentPane().add(new JScrollPane(panel));
frame.setTitle("My Table");
frame.setPreferredSize(new Dimension(500, 200));
frame.addWindowListener(new WindowAdapter(){
@Override
public void windowClosing(WindowEvent e) {
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocation(300, 200);
frame.pack();
frame.setVisible(true);
class TextAreaEditor extends JTextArea implements TableCellEditor {
Icon defaultIcon;
boolean isChecked = false;
public TextAreaEditor() {
System.out.println ("TextAreaEditor()");
setToolTipText("Double click to type");
@Override
public Component getTableCellEditorComponent(JTable arg0,
Object arg1,
boolean arg2,
int arg3,
int arg4) {
System.out.println ("TextAreaEditor() arg1: " + arg1 + "arg2: " + arg2 + " arg3: " + arg3 + " arg4: " + arg4 );
return null;
@Override
public void addCellEditorListener(CellEditorListener arg0) {
System.out.println ("TextAreaEditor().addCellEditorListener");
@Override
public void cancelCellEditing() {
System.out.println ("TextAreaEditor().cancelCellEditing");
@Override
public Object getCellEditorValue() {
System.out.println ("TextAreaEditor().getCellEditorValue");
return null;
@Override
public boolean isCellEditable(EventObject arg0) {
System.out.println ("TextAreaEditor().isCellEditable");
return true;
@Override
public void removeCellEditorListener(CellEditorListener arg0) {
System.out.println ("TextAreaEditor().removeCellEditorListener");
@Override
public boolean shouldSelectCell(EventObject arg0) {
System.out.println ("TextAreaEditor().shouldSelectCell");
return false;
@Override
public boolean stopCellEditing() {
System.out.println ("TextAreaEditor().stopCellEditing");
return false;
} -
How to create a cell column with JTextArea in JTable
I am developing an Application using Java Swings. I need to use JTextArea in my JTable. I need the code to do so. I also want to show the scrollbars in the JTextArea.
Any efforts in this regard would be of great help. Thanks in advance.
Thanks
Alaguhave a look at
http://forum.java.sun.com/thread.jsp?forum=57&thread=134412 -
How to add JTextArea in JTable
Hi..
I want to add JTextArea in my table in one of the column of JTable. I have already written a code which implements TablecellEditor and TableCellRenderer. I have already succeeded to set textarea in one cell for multiple line but when i go to another cell my previous value disappears. Can anybody tell me the solution.I think the reason that this is happening, is that you have to override the setValue method in TableModel, inorder for the value to be displayed correctly.
Another thing.
I too am trying to implement a textarea as one of the cells in a col.
But the problem is that when I create my celleditor extends TextArea and implements TableCellEditor, and compile it says that all eventLsiteners are already implemented .
And if I just extend the AbstractCellEditor, and return it in the method getCellEditor, it says incompatible types.
Can you tell me how to implement a CustomCellEditor
Thanks, -
Floating Height of JTextArea (as Renderer/Editor) in a JTable Cell
Hey Folks,
I'm kinda struggling with JTextAreas...
There is this JTable, which consists of three colums (practically there are two - the other one's an ID-Field...) and only one
of them ist editable für users.
Left column is a commentary column which has a max of 150 characters - Right column fills automaticly with a user/date stamp.
The main function is that on showing the table, old comments will be retrieved from database and new ones can be entered.
This works all fine and is no matter of subject...
The core of my problem is that there seems to be no straigh-forward way of determine a proper linecount from (a wordwrapped!) JTextArea.
After a long search in the net, i found this approach:
private static ArrayList<String> getWrappedLines(JTextArea myTextArea) {
ArrayList<String> linesList = new ArrayList<String>();
int length = myTextArea.getDocument().getLength();
int offset = 0;
try {
while (offset < length) {
int end = Utilities.getRowEnd(myTextArea, offset);
if (end < 0) {
break;
// Include the last character on the line
end = Math.min(end + 1, length);
String line =
myTextArea.getDocument().getText(offset, end - offset);
// Remove the line break character
if (line.endsWith("\n")) {
line = line.substring(0, line.length() - 1);
linesList.add(line);
offset = end;
} catch (BadLocationException e) {
System.err.println("Bad Location at TextArea");
return linesList;
} This code reads the content of a JTextArea an separates wrapped lines in an array.
With manual line breaks ("\n") I get Exceptions (Bad Location) which isn't too bad, because
I was trying to ban manual line breaks anyway...
The above given method retrieves the lines, while the next sets the new Height (line count multiplied by Font Height) to the row.
public static void setOptimalRowHeight(JTable table, JTextArea textArea, int row, int column) {
if (
row >= 0 &&
column == VerwaltungsnotizController.IND_VNO_NOTIZ
int fontHeight =
textArea.getFontMetrics(textArea.getFont()).getHeight();
ArrayList<String> wrappedLines = getWrappedLines(textArea);
int nrOfLines = wrappedLines.size();
int oldSize = table.getRowHeight(row);
int newSize = (fontHeight * nrOfLines) + 5;
if (newSize != oldSize) {
table.setRowHeight(row, newSize);
public static void setOptimalRowHeight(JTable table, JTextArea textArea) {
int row = table.getSelectedRow();
int column = table.getSelectedColumn();
if (
row >= 0 &&
column == VerwaltungsnotizController.IND_VNO_NOTIZ
setOptimalRowHeight(table, textArea, row, column);
}The above combined Sources are used by two classes, which are "tied" to the table.
One is the CellEditor (which works almost fine); the other one is the CellRenderer (which fails miserably!)
CellEditor (with Listener):
public class VnoCellEditor extends AbstractCellEditor implements TableCellEditor {
private VnoTextArea textArea;
private JTable table;
public VnoCellEditor (JTable table) {
this.table = table;
textArea = new VnoTextArea(table);
textArea.setMaximumInputLength(VerwaltungsnotizController.MAX_INPUT_VNO);
textArea.addKeyListener(new TextAreaEnterAdapter());
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
Document document = textArea.getDocument();
document.addDocumentListener(new VnoTextAreaDocListener(table, textArea));
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row,
int column) {
if (value instanceof String) {
textArea.setText((String)value);
} else if (value instanceof Integer) {
Integer intValue = (Integer)value;
textArea.setText(intValue.toString());
} else {
Object objValue = value;
textArea.setText(objValue.toString());
System.err.println("Editor - get Component");
return textArea;
public Object getCellEditorValue() {
return textArea.getText();
public class VnoTextAreaDocListener implements DocumentListener {
private JTable table;
private JTextArea textArea;
public VnoTextAreaDocListener(JTable table, JTextArea textArea) {
this.table = table;
this.textArea = textArea;
public void insertUpdate(DocumentEvent e) {
VnoTableRowHeightHelper.setOptimalRowHeight(table, textArea);
public void removeUpdate(DocumentEvent e) {
VnoTableRowHeightHelper.setOptimalRowHeight(table, textArea);
public void changedUpdate(DocumentEvent e) {
//Plain text components don't fire these events
}As said the editor works almost as planned. On every Keystroke made in Edit-Mode of the table, insertUpdate() or removeUpdate()
is being called, corresponding to the type of Keystroke ... (duh!)
The Helpers method is called and the row-height is set real nicely.
!But!
when i navigate into an other row, a removeUpdate()-event is beeing thrown and due to the mechanism the cell selection
gets somehow mixed around and row-heights get switched.
Maybe this could get improved, but i don't se my error - which wouldn't be nescessary if this event wasn't thrown.
(for what I don't see a reason anyway ... !)
CellRenderer:
public class VnoCellRenderer implements TableCellRenderer {
private VnoTextArea textArea;
private int Row = -1;
private int Column = -1;
private VnoTableModel jtmVno;
public VnoCellRenderer(JTable table) {
this.jtmVno = (VnoTableModel)table.getModel();
textArea = new VnoTextArea(table);
textArea.setLayout(new BorderLayout());
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
public VnoTextArea getTextArea() {
return textArea;
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected,
boolean hasFocus, int row,
int column) {
Row = row;
Column = column;
String tmpValue = null;
if (value instanceof String) {
tmpValue = (String)value;
} else if (value instanceof Integer) {
tmpValue = ((Integer)value).toString();
} else {
tmpValue = value.toString();
// FARBEN:
// Normalmodus
if (jtmVno == null) {
System.err.println("Table Model noch nicht initialisiert!");
textArea.setBackground(Color.LIGHT_GRAY);
} else {
if (jtmVno.isCellEditable(Row, Column)) {
textArea.setBackground(Color.WHITE);
} else {
textArea.setBackground(Color.LIGHT_GRAY);
textArea.setForeground(Color.BLACK);
// Für ausgewählte Zeile
if (isSelected && !hasFocus) {
textArea.setBackground(CommonConstants.SELECTION_COLOR_BLUE);
textArea.setForeground(Color.WHITE);
textArea.setText(tmpValue);
textArea.setEditable(true);
if (Column == VerwaltungsnotizController.IND_VNO_NOTIZ) {
VnoTableRowHeightHelper.setOptimalRowHeight(table, textArea, row, column);
return textArea;
}Okay, this is where the shit hits the fan!
Since with renderers there is no manual content mutation, row-height-settings are not done with listeners.
I put this at the very end of the getTableCellRendererComponent(), which is called every time a cell gets rendered.
The main problem here is that at this point my methods can't determine any linewraps at all!
getWrappedLines() always returns an empty Array (since Utilities.getRowEnd() returns "-1" beforehand...).
I'm afraid that my methods are called way too early - at a point were the rendering is not completed or has not even started.
And to accomplish my desired tasks the fully rendered JTextArea would be needed ... ?!
I have very limited swing experience, so I can only guess about this core features ...
But i this is the case - my methods should be called later on the rendered cell. But how? from which component?
Btw: I have written my own JTextArea to limit the input size
public class VnoTextArea extends JTextArea {
private JTable table;
private int _maximumInputLength = 0;
public VnoTextArea(JTable table) {
this.table = table;
public void setMaximumInputLength(int maximumInputLength) {
if (maximumInputLength != 0) {
_maximumInputLength = maximumInputLength;
super.setDocument(new PlainDocument() {
public void insertString(int offset, String string, AttributeSet attributeSet) throws BadLocationException {
StringBuffer buffer = new StringBuffer(string);
int size = VnoTextArea.this.getText().length();
int bufferSize = buffer.length();
if ((size + bufferSize) > _maximumInputLength) {
buffer.delete((_maximumInputLength - size), bufferSize);
if (size < _maximumInputLength) {
super.insertString(offset, buffer.toString(), attributeSet);
} else {
Toolkit.getDefaultToolkit().beep();
}I'm sorry for not providing a running example, but it's a pretty huge project...
Providing all dependencies would go far beyond the scope.
(and there are many sources which I'm not allowed to post)
But I hope my examples get down to the core of my problem!
I also tried different approaches:
- using getPreferredSize() of the JTextArea (seemed to do nothing useful at all?!)
- using getLineCount/() of the TextArea (only counts "\n" ...)
- guessing that every row consist of an average of 20 characters cumpute by myself (low-tech, buggy but fast - unsatisfying)
With my above mentioned approach I got by far the best results (partially) - but I'm at my wits' end.
I don't know it any better... And i have tried for days without improvement.
What would you do?
vielen Dank im Voraus schon mal für eventuelle Mühen,
Hayeno solution - just a couple of comments:
- never ever change the calling table in a renderer, I mean really NEVER
- instead, listen to table events and resize the row height as appropriate
- JTextArea has a somehow weird prefSize calculation (forgot the details, so don't nail me :), so you have to manually set one dimension and then ask the area to calculate the other. In your renderer, you can do something like:
Component getTableCellRendererComponent(....) {
int columnWidth = table.getColumnModel().getColumn(column).getWidth();
textArea.setSize(columnWidth, Short.MAX_VALUE);
... here do the normal config
// then somewhere else, triggered by appropriate change events
void updateRowHeight(JTable table, int row) {
int height = table.getRowHeight();
foreach column {
TableCellRenderer r = table.getCellRenderer(row, column);
Component c = table.prepareCellRenderer(r, row, column);
height = Math.max(height, c.getPreferredSize().height);
table.setRowHeight(row, height);
} HTH - ein bißchen wenigstens :-)
Jeanette -
Tab transversal while using JTextArea as a JTable cell editor..
I'm working on a project that will use a JTable with a JTextArea cell editor to create a chart for classroom scheduling. Searching on Google, I found a way to use a JTextArea as a cell editor and render the cell properly. However, when editing a cell, pressing the Tab key inserts a tab, rather than leaving the cell and going to the next one, as happens with just a regular JTable. In fact, none of the keyboard shortcuts that work on a JTable work once the JTextArea cell editor is used. Does anyone know of any way to resolve this? Below is some code I'm using to create a sample GUI, just to verify that I can do this. Another question is would it be easier to use a bunch of JLabels and JTextAreas, remove the padding from those JTextAreas, and try to allow for Tab transversals between stand-alone JTextAreas, rather than JTextAreas as JTable cell editors?
Thanks!
package edu.elon.table;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
public class GUI
private JFrame frame;
private String[] columnNames = {"Classroom", "8:00-9:10", "9:25-10:35",
"10:50-12:00", "12:15-1:25", "1:40-2:50", "1:40-3:20 (MW)",
"3:35-5:15 (MW)", "5:30-7:10 (MW)"};
private Object[][] data = {columnNames,
{"ALAM 201 (42)\nENG 110 LAB", "", "", "", "", "", "", "", ""},
{"ALAM 202 (42)\nDP/DVD", "", "", "", "", "", "", "", ""},
{"ALAM 203 (38)\nDP/DVD", "", "", "", "", "", "", "", ""},
{"ALAM 205 (40)\n", "", "", "", "", "", "", "", ""},
{"ALAM 206 (39)\nSINK, TV/VCR", "", "", "", "", "", "", "", ""},
{"ALAM 207 (40+)\nDP/DVD", "", "", "", "", "", "", "", ""},
{"ALAM 214 (38)\nTV/VCR", "", "", "", "", "", "", "", ""},
{"ALAM 215 (42)\nTV/VCR", "", "", "", "", "", "", "", ""},
{"ALAM 216 (42)\n", "", "", "", "", "", "", "", ""},
{"ALAM 301 (40)\nTV/VCR", "", "", "", "", "", "", "", ""},
{"ALAM 302 (38)\nDP/DVD", "", "", "", "", "", "", "", ""},
{"ALAM 304 (35)\nFRENCH", "", "", "", "", "", "", "", ""},
{"ALAM 314 (30)\nDP, PSY, COMPUTER ASSISTED", "", "", "", "", "", "",
{"ALAM 315 (40)\nPC LAB, DP/DVD", "", "", "", "", "", "", "", ""}};
private JTable table;
public GUI()
frame = new JFrame();
table = new JTable(data, columnNames);
table.setRowHeight(table.getRowHeight()*2);
TableColumnModel cModel = table.getColumnModel();
TextAreaRenderer renderer = new TextAreaRenderer();
TextAreaEditor editor = new TextAreaEditor();
for (int i = 0; i < cModel.getColumnCount(); i++)
cModel.getColumn(i).setCellRenderer(renderer);
cModel.getColumn(i).setCellEditor(editor);
frame.setLayout(new GridLayout(1,0));
frame.add(table);
frame.pack();
frame.setVisible(true);
public static void main (String[] args)
GUI gui = new gui();
* Written by Dr. Heinz Kabutz, found through online newsletter via Google.
class TextAreaRenderer extends JTextArea
implements TableCellRenderer {
private final DefaultTableCellRenderer adaptee =
new DefaultTableCellRenderer();
/** map from table to map of rows to map of column heights */
private final Map cellSizes = new HashMap();
public TextAreaRenderer() {
setLineWrap(true);
setWrapStyleWord(true);
public Component getTableCellRendererComponent(//
JTable table, Object obj, boolean isSelected,
boolean hasFocus, int row, int column) {
// set the colours, etc. using the standard for that platform
adaptee.getTableCellRendererComponent(table, obj,
isSelected, hasFocus, row, column);
setForeground(adaptee.getForeground());
setBackground(adaptee.getBackground());
setBorder(adaptee.getBorder());
setFont(adaptee.getFont());
setText(adaptee.getText());
// This line was very important to get it working with JDK1.4
TableColumnModel columnModel = table.getColumnModel();
setSize(columnModel.getColumn(column).getWidth(), 100000);
int height_wanted = (int) getPreferredSize().getHeight();
addSize(table, row, column, height_wanted);
height_wanted = findTotalMaximumRowSize(table, row);
if (height_wanted != table.getRowHeight(row)) {
table.setRowHeight(row, height_wanted);
return this;
private void addSize(JTable table, int row, int column,
int height) {
Map rows = (Map) cellSizes.get(table);
if (rows == null) {
cellSizes.put(table, rows = new HashMap());
Map rowheights = (Map) rows.get(new Integer(row));
if (rowheights == null) {
rows.put(new Integer(row), rowheights = new HashMap());
rowheights.put(new Integer(column), new Integer(height));
* Look through all columns and get the renderer. If it is
* also a TextAreaRenderer, we look at the maximum height in
* its hash table for this row.
private int findTotalMaximumRowSize(JTable table, int row) {
int maximum_height = 0;
Enumeration columns = table.getColumnModel().getColumns();
while (columns.hasMoreElements()) {
TableColumn tc = (TableColumn) columns.nextElement();
TableCellRenderer cellRenderer = tc.getCellRenderer();
if (cellRenderer instanceof TextAreaRenderer) {
TextAreaRenderer tar = (TextAreaRenderer) cellRenderer;
maximum_height = Math.max(maximum_height,
tar.findMaximumRowSize(table, row));
return maximum_height;
private int findMaximumRowSize(JTable table, int row) {
Map rows = (Map) cellSizes.get(table);
if (rows == null) return 0;
Map rowheights = (Map) rows.get(new Integer(row));
if (rowheights == null) return 0;
int maximum_height = 0;
for (Iterator it = rowheights.entrySet().iterator();
it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
int cellHeight = ((Integer) entry.getValue()).intValue();
maximum_height = Math.max(maximum_height, cellHeight);
return maximum_height;
* Written by Dr. Heinz Kabutz, found through online newsletter via Google.
class TextAreaEditor extends DefaultCellEditor
public TextAreaEditor() {
super(new JTextField());
final JTextArea textArea = new JTextArea();
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setBorder(null);
editorComponent = scrollPane;
delegate = new DefaultCellEditor.EditorDelegate() {
public void setValue(Object value)
textArea.setText((value != null) ? value.toString() : "");
public Object getCellEditorValue()
return textArea.getText();
}Using the KeyEvent manager and playing around with the JTextArea, I was able to get a JTable using JTextAreas as the cell editors that worked very close to the way the regular JTable works. You have to hit Tab twice to shift focus to another cell, or hit Tab once and then an arrow key. Also, Alt-Enter will allow you to enter a cell for editing. All of the changes were made to the TextAreaEditor class, which should now read as follows:
class TextAreaEditor extends DefaultCellEditor implements KeyListener
private int lastKeyCode;
public TextAreaEditor(final JTable table) {
super(new JTextField());
lastKeyCode = KeyEvent.CTRL_DOWN_MASK;
final JTextArea textArea = new JTextArea();
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
textArea.addKeyListener(this);
textArea.setFocusable(true);
textArea.setFocusAccelerator((char) KeyEvent.VK_ENTER);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setBorder(null);
scrollPane.setFocusable(false);
editorComponent = scrollPane;
delegate = new DefaultCellEditor.EditorDelegate() {
public void setValue(Object value) {
textArea.setText((value != null) ? value.toString() : "");
public Object getCellEditorValue() {
return textArea.getText();
public void keyTyped(KeyEvent ke)
// TODO Auto-generated method stub
public void keyPressed(KeyEvent ke)
if (ke.getKeyCode() == KeyEvent.VK_TAB)
ke.consume();
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.focusNextComponent();
return;
if (ke.getKeyCode() == KeyEvent.VK_TAB && ke.isShiftDown())
ke.consume();
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.focusPreviousComponent();
return;
if ((lastKeyCode == KeyEvent.CTRL_DOWN_MASK) &&
(ke.getKeyCode() == KeyEvent.VK_ENTER))
ke.consume();
editorComponent.requestFocus();
else
lastKeyCode = ke.getKeyCode();
public void keyReleased(KeyEvent ke)
// TODO Auto-generated method stub
} -
here is the code
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import java.util.*;
import java.awt.print.PrinterJob;
import java.awt.print.*;
// Java extension packages
import javax.swing.*;
import javax.swing.table.*;
class DisplayQueryResultsDOD extends JFrame implements Printable,ActionListener
ResultSetTableModelDOD tableModel;
JTextArea queryArea;
JTable resultTable;
// create ResultSetTableModel and GUI
DisplayQueryResultsDOD()
super( "Displaying Query Results" );
// Cloudscape database driver class name
String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
// URL to connect to books database
String url = "jdbc:odbc:MyDataSource";
// query to select entire authors table
String query = "SELECT * FROM person";
// create ResultSetTableModel and display database table
try
// create TableModel for results of query
// SELECT * FROM authors
tableModel =
new ResultSetTableModelDOD( driver, url, query );
// set up JTextArea in which user types queries
queryArea = new JTextArea( query, 3, 100 );
queryArea.setWrapStyleWord( true );
queryArea.setLineWrap( true );
JScrollPane scrollPane = new JScrollPane( queryArea,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );
// set up JButton for submitting queries
JButton submitButton = new JButton( "Submit Query" );
// create Box to manage placement of queryArea and
Box box = Box.createHorizontalBox();
box.add( scrollPane );
box.add( submitButton );
// create JTable delegate for tableModel
JTable resultTable = new JTable( tableModel );
// place GUI components on content pane
Container c = getContentPane();
c.add( box, BorderLayout.NORTH );
c.add( new JScrollPane( resultTable ),
BorderLayout.CENTER );
// create event listener for submitButton
submitButton.addActionListener(
new ActionListener()
public void actionPerformed( ActionEvent e )
// perform a new query
try
tableModel.setQuery( queryArea.getText() );
// catch SQLExceptions that occur when
// performing a new query
catch ( SQLException sqlException )
JOptionPane.showMessageDialog( null,sqlException.toString(),"Database error",JOptionPane.ERROR_MESSAGE );
} // end actionPerformed
} // end ActionListener inner class
// set window size and display window
JMenuBar menuBar = new JMenuBar();
JMenu filemenu= new JMenu("File");
JMenu submenux=new JMenu("Open");
JMenuItem np=new JMenuItem("Launch Panel");
submenux.add(np);
//openmenuitem.addActionListener(this);
submenux.setActionCommand("Open");
submenux.setMnemonic('O');
filemenu.add(submenux);
menuBar.add(filemenu);
JMenuItem printItem = new JMenuItem("Print");
printItem.setMnemonic('P');
filemenu.add(printItem);
JMenuItem ExitItem = new JMenuItem("Exit");
ExitItem.setMnemonic('x');
filemenu.add(ExitItem);
JMenu viewmenu=new JMenu("View");
JMenuItem repItem=new JMenuItem("Reports");
JMenu submenu=new JMenu("sort by");
submenu.add(new JMenuItem("Marital Status"));
submenu.add(new JMenuItem("Rank"));
submenu.add(new JMenuItem("Tribe"));
submenu.add(new JMenuItem("Educational Level"));
viewmenu.add(submenu);
menuBar.add(viewmenu);
setJMenuBar(menuBar);
printItem.addActionListener(this);
ExitItem.addActionListener
new ActionListener()
public void actionPerformed(ActionEvent ae)
System.exit(0);
setSize( 1500,900);
// setVisible( true );
} // end try
// catch ClassNotFoundException thrown by
// ResultSetTableModel if database driver not found
catch ( ClassNotFoundException classNotFound )
JOptionPane.showMessageDialog( null,"Cloudscape driver not found", "Driver not found",JOptionPane.ERROR_MESSAGE );
System.exit( 1 ); // terminate application
// catch SQLException thrown by ResultSetTableModel
// if problems occur while setting up database
// connection and querying database
catch ( SQLException sqlException )
JOptionPane.showMessageDialog( null,sqlException.toString(),"Database error", JOptionPane.ERROR_MESSAGE );
System.exit( 1 ); // terminate application
} // end DisplayQueryResults constructor
public void actionPerformed(ActionEvent e)
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setPrintable(this);
if (printJob.printDialog())
try
printJob.print();
catch (Exception ex)
ex.printStackTrace();
public int print(Graphics g, PageFormat pf, int page) throws
PrinterException {
if (page > 0) { /* We have only one page, and 'page' is zero-based */
return NO_SUCH_PAGE;
/* User (0,0) is typically outside the imageable area, so we must
* translate by the X and Y values in the PageFormat to avoid clipping
Graphics2D g2d = (Graphics2D)g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
/* Now print the window and its visible contents */
resultTable.printAll(g);
/* tell the caller that this page is part of the printed document */
return PAGE_EXISTS;
// execute application
public static void main( String args[] )
DisplayQueryResultsDOD app = new DisplayQueryResultsDOD();
app.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
} // end class DisplayQueryResults
I get an exception
pls helpI included this statement only to check if it would print or not, because before that I tried printing the table without setting the size. Anyway, when I tried the same code under Windows it worked fine. Talking about platform independent...:-)
-
How to print a JTable in Java Swing ?
Hi,
I have an application written in java swing.Now I want to write a print module that prints some details.The details includes the JTextArea and JTable that changes in size dynamically.One solution i found is to put them in a panel and print that panel.But it is static.The size of JTable and JTextArea changes, according to the given input.Please give me a solution for this.Printing is a bit of a nightmare, actually. Most of the trouble is layout. Basically a Printable is passed a page number and a graphics context and has to work out what components go on that page and where. It can't depend on the pages being requested in sequence.
You can call getPrintable from a JTable, and you can call that through your own Printable in order to add extra pages. However you can't ask a Printable how many pages it's going to produce, you just have to invoke it and see if it returns a code to say that the page is out of range.
And the Printable JTable generates is very limited, the table has to occupy full pages, you can't tell it to start in a different place on the first page, or find out how much space it's used on the last page. The headers and footers generate JTable's own idea of a page number, not yours.
You can call print() on most Swing components, but you'll need to set their size and location first, and/or mess with the transformation in the graphics context. -
Hello, i am trying to display an image.gif in a JTable using cellrenderer but i always get an error message. Everybodys help its always accepted.
I did paste just a few parts of the code since its very long. In the cellrenderer class i have scored out those 3 lines.
In all the books that i have read ( quite a few there is not a single full coded program that shows how to insert a picture in a cell of the table).
What i am trying to do is, when creating the table insert all pictures in all cells and then with a loop insert the relevant data.
In other words the picture should appear only in cells containing no data.
planner = new JTable(getFieldValues(),setColumnNames());
planner.setRowHeight(30);
planner.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
planner.setRowSelectionAllowed(true);
planner.setColumnSelectionAllowed(true);
planner.setDefaultRenderer(ImageIcon.class,new cellrenderer());
class cellrenderer implements TableCellRenderer
public Component getTableCellRendererComponent (JTable planner, Object xw, boolean isSelected,boolean hasFocus, int row, int column)
String cd;
cd="xx.gif";
//xw= new ImageIcon(cd);
//panel.setBackground(ImageIcon(xw));
//setImage(new ImageIcon(cd));
return panel;
JPanel panel=new JPanel();Thanks for the code, it does compile but it does not display the image.
Maybe if you give a look at the whole code it will be easier.
You said to use MyTableRenderer() but maybe you meant MyCellRenderer().
What do you think ?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import java.io.*;
import java.beans.*;
import javax.imageio.*;
public class yearPlannerBean extends JFrame implements ListSelectionListener,ActionListener,Serializable
private String dayNames[] = {"Saturday","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday"};
private String engMonths[] = {"January","February","March","April","May","June","July","August","September","October","November","December"};
private String spaMonths[] = {"Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"};
private String spadays[]={"S�bado", "Domingo", "Lunes", "Martes", "Mi�rcoles", "Jueves", "Viernes"};
private String itaMonths[] = {"Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno","luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre"};
private String itadays[]={"Sabato","Domenica","Lunedi","Martedi","Mercoledi","Giovedi","Venerdi"};
private Object fieldValues[][];
private String panelTitle;
private JPanel container;
private JPanel languages;
private JPanel choice;
private JTable planner;
private String days[];
private JScrollPane scrollPane;
private int month;
private int noOfDays;
private int year;
private Zellar zell;
private PropertyChangeSupport support;
private Image icon;
private next bbnext;
private previous bbpre;
private JLabel lan;
private JLabel curry;
private JTextField curye;
private JList linlist;
public yearPlannerBean()
panelTitle = ("Year Planner");
setTitle(panelTitle);
setSize(300,300);
month = 0;
noOfDays = 0;
year = 2003;
zell = new Zellar(1,month,year);
container = new JPanel();
container.setLayout(new BorderLayout());
languages = new JPanel();
choice= new JPanel();
lan= new JLabel("Select Language: ");
String[] words={"English","Italian","Spanish"};
JList linlist= new JList(words);
JScrollPane sc =new JScrollPane(linlist);
linlist.addListSelectionListener(this);
planner = new JTable(getFieldValues(),setColumnNames());
planner.setRowHeight(100);
planner.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
planner.setRowSelectionAllowed(true);
planner.setColumnSelectionAllowed(true);
//myTable.setDefaultRenderer(Object.class, new MyTableRenderer());
planner.setDefaultRenderer(Object.class,new MyCellRenderer());
scrollPane = new JScrollPane(planner);
bbnext= new next();
bbpre=new previous();
bbnext.addActionListener(this);
bbpre.addActionListener(this);
getContentPane().setLayout(new BorderLayout());
container.add(scrollPane,BorderLayout.CENTER);
curry= new JLabel("Current Year");
curye= new JTextField(5);
curye.setText(Integer.toString(year));
choice.add(bbpre);
choice.add(bbnext);
languages.add(curry);
languages.add(curye);
languages.add(lan);
languages.add(linlist);
container.add(choice,BorderLayout.SOUTH);
container.add(languages,BorderLayout.NORTH);
setContentPane(container);
pack();
addWindowListener(new WindowAdapter()
public void windowClosing(WindowEvent e)
System.exit(0);
}//End constructor
public String[] setColumnNames()
days = new String[38];
int count = 0;
int index = 0;
for (index = 0; index < 38; index++)
if (index == 0)
days[index] = "";
else
days[index] = dayNames[count];
if (count != 6)
count++;
else
count = 0;
return days;
}//End getColumnNames
public Object[][] getFieldValues()
int countY = 0;
int countX = 0;
String firstDay = "";
int dayInt;
int dayCount = 0;
int tempCount = 0;
fieldValues = new Object[12][38];
for (countX = 0; countX < 38; countX++)
for (countY = 0; countY < 12; countY++)
monthToInt(engMonths[countY]);
firstDay = zell.getFirstDay(month,year);
dayInt = dayToInt(firstDay);
for (month = 1; month < 12; month++)
tempCount = 1;
for (dayCount = dayInt; dayCount < (noOfDays+dayInt); dayCount++)
if (countX == 0)
fieldValues[countY][countX] = engMonths[countY];
else
//fieldValues.setCellRenderer(new acellrenderer());
fieldValues[countY][dayCount]="" + tempCount;//setIcon(new ImageIcon(icon));
tempCount++;
return fieldValues;
}//End getFieldValues
public void monthToInt(String monthIn)
boolean temp = false;
if (monthIn == "January")
month = 1;
noOfDays = 31;
else
if (monthIn == "February")
month = 2;
if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)))
noOfDays = 29;
else
noOfDays = 28;
else
if (monthIn == "March")
month = 3;
noOfDays = 31;
else
if (monthIn == "April")
month = 4;
noOfDays = 30;
else
if (monthIn == "May")
month = 5;
noOfDays = 31;
else
if (monthIn == "June")
month = 6;
noOfDays = 30;
else
if (monthIn == "July")
month = 7;
noOfDays = 31;
else
if (monthIn == "August")
month = 8;
noOfDays = 31;
else
if (monthIn == "September")
month = 9;
noOfDays = 30;
else
if (monthIn == "October")
month = 10;
noOfDays = 31;
else
if (monthIn == "November")
month = 11;
noOfDays = 30;
else
if (monthIn == "December")
month = 12;
noOfDays = 31;
}//End monthToInt
public int dayToInt(String dayIn)
int dayOut = 0;
if (dayIn == "Saturday")
dayOut = 1;
else
if (dayIn == "Sunday")
dayOut = 2;
else
if (dayIn == "Monday")
dayOut = 3;
else
if (dayIn == "Tuesday")
dayOut = 4;
else
if (dayIn == "Wednesday")
dayOut = 5;
else
if (dayIn == "Thursday")
dayOut = 6;
else
if (dayIn == "Friday")
dayOut = 7;
return dayOut;
}//End dayToInt
/*class acellrenderer extends DefaultTableCellRenderer
public acellrenderer()
super();
public Component getTableCellRendererComponent (JTable planner)
Component component=super.getTableCellRenderer();
String filepa;
filepa="caley.GIF";
ImageIcon nn;
component.setIcon(new ImageIcon(filepa));
return component;
static class MyCellRenderer extends DefaultTableCellRenderer
{ final Icon icon = new ImageIcon("caley.gif");
public MyCellRenderer ()
super();
public void setValue(Object value)
if(value == null)
{ setText("");
setIcon(icon);
else
setText(String.valueOf(value));
public void actionPerformed(ActionEvent event)
Object source=event.getSource();
int a;
if (source==bbnext)
// button next pressed
a=Integer.parseInt(curye.getText());
curye.setText(Integer.toString(a+1));
else
if (source==bbpre)
// button previous pressed
a=Integer.parseInt(curye.getText());
curye.setText(Integer.toString(a-1));
private int getindex(String astring)
int index=-1;
if(astring.toUpperCase().equals("ENGLISH"))
index=0;
else
if (astring.toUpperCase().equals("ITALIAN"))
index=1;
else
index=2;
return index;
public void valueChanged(ListSelectionEvent event)
JList source=(JList)event.getSource();
Object asel;
int index;
if (source==linlist)
asel=linlist.getSelectedValue();
index=getindex((String)asel);
if (index==0)
// set header in English;
else
if (index==1)
// set header in Italian;
else
if (index==2)
// set header in Spanish;
public static void main(String args[])
yearPlannerBean test = new yearPlannerBean();
test.setVisible(true);
}//End Main
}//End class -
How to implement Line number in JTextArea
Hi
I have seen some JTextArea with Line numbers How to do it
ThankxI'm playing around with trying to make a Line Number component that will work with JTextArea, JTextPane, JTable etc. I'm not there yet, but this version works pretty good with JTextArea. At least it will give you some ideas.
Good luck.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.*;
public class LineNumber extends JComponent
private final static Color DEFAULT_BACKGROUND = new Color(230, 163, 4);
private final static Color DEFAULT_FOREGROUND = Color.black;
private final static Font DEFAULT_FONT = new Font("monospaced", Font.PLAIN, 12);
// LineNumber height (abends when I use MAX_VALUE)
private final static int HEIGHT = Integer.MAX_VALUE - 1000000;
// Set right/left margin
private final static int MARGIN = 5;
// Line height of this LineNumber component
private int lineHeight;
// Line height of this LineNumber component
private int fontLineHeight;
private int currentRowWidth;
// Metrics of this LineNumber component
private FontMetrics fontMetrics;
* Convenience constructor for Text Components
public LineNumber(JComponent component)
if (component == null)
setBackground( DEFAULT_BACKGROUND );
setForeground( DEFAULT_FOREGROUND );
setFont( DEFAULT_FONT );
else
setBackground( DEFAULT_BACKGROUND );
setForeground( component.getForeground() );
setFont( component.getFont() );
setPreferredSize( 9999 );
public void setPreferredSize(int row)
int width = fontMetrics.stringWidth( String.valueOf(row) );
if (currentRowWidth < width)
currentRowWidth = width;
setPreferredSize( new Dimension(2 * MARGIN + width, HEIGHT) );
public void setFont(Font font)
super.setFont(font);
fontMetrics = getFontMetrics( getFont() );
fontLineHeight = fontMetrics.getHeight();
* The line height defaults to the line height of the font for this
* component. The line height can be overridden by setting it to a
* positive non-zero value.
public int getLineHeight()
if (lineHeight == 0)
return fontLineHeight;
else
return lineHeight;
public void setLineHeight(int lineHeight)
if (lineHeight > 0)
this.lineHeight = lineHeight;
public int getStartOffset()
return 4;
public void paintComponent(Graphics g)
int lineHeight = getLineHeight();
int startOffset = getStartOffset();
Rectangle drawHere = g.getClipBounds();
// System.out.println( drawHere );
// Paint the background
g.setColor( getBackground() );
g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height);
// Determine the number of lines to draw in the foreground.
g.setColor( getForeground() );
int startLineNumber = (drawHere.y / lineHeight) + 1;
int endLineNumber = startLineNumber + (drawHere.height / lineHeight);
int start = (drawHere.y / lineHeight) * lineHeight + lineHeight - startOffset;
// System.out.println( startLineNumber + " : " + endLineNumber + " : " + start );
for (int i = startLineNumber; i <= endLineNumber; i++)
String lineNumber = String.valueOf(i);
int width = fontMetrics.stringWidth( lineNumber );
g.drawString(lineNumber, MARGIN + currentRowWidth - width, start);
start += lineHeight;
setPreferredSize( endLineNumber );
public static void main(String[] args)
JFrame frame = new JFrame("LineNumberDemo");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
JPanel panel = new JPanel();
frame.setContentPane( panel );
panel.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
panel.setLayout(new BorderLayout());
JTextArea textPane = new JTextArea();
JScrollPane scrollPane = new JScrollPane(textPane);
panel.add(scrollPane);
scrollPane.setPreferredSize(new Dimension(300, 250));
LineNumber lineNumber = new LineNumber( textPane );
lineNumber.setPreferredSize(99999);
scrollPane.setRowHeaderView( lineNumber );
frame.pack();
frame.setVisible(true); -
Hello all,
i am trying to extend the JTable class to create a table in which i can enter numbers. I would also like to channge the default renderer so i can change the colours of the cell lines. Aslo, i would like to add colum headers and row headers. I want the colum and row headers to be namesd after the dimensions passed to the new Table class. This may seem trivial to some, but i cant seem to get it going. I know i should have to extend the abstract table model, but i dont know what to put into it.
The only bit of code i have got going so far which definatly works in the class definition. I cant seem to find any good documentation about how to do the abogve...the sun tutorial only confuses me..could anyone please please help.
Thanks in advance, regards, Rupesh
public class SpreadTable extends JTable {
private CellRenderer _renderer;
public SpreadTable(int x, int y){
super(x,y);
setCellSelectionEnabled(true);
public boolean isCellEditable(int row, int column) {return true;}Hi - thanks for your post. I would be eager to see some of your furure results. I have been trying to get my Table to have editable cells, and trying to get the cells to be of a different size, and colour, and have finally come up with some code, but it doesnt seem to work. This error i get is
.\SpreadTable.java:58: cannot resolve symbol
symbol : method getTableCellRendererComponent (SpreadTable.CellRenderer,java.l
ng.Object,boolean,boolean,int,int)
location: class javax.swing.JLabel
super.getTableCellRendererComponent(this, value, isSelected, ha
Focus, row, column);
^
1 error
Here is the code.
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class SpreadTable extends JTable {
private CellRenderer renderer;
public SpreadTable(int x, int y){
super(x,y);
setCellSelectionEnabled(true);
renderer = new CellRenderer();
try {
setDefaultRenderer(Class.forName("java.lang.Object" ), renderer );
} catch (ClassNotFoundException ex) {
System.out.println("SpreadSheet() Can't modify renderer");
TableColumn aColumn = getColumnModel().getColumn(0);
TableCellRenderer aRenderer = getTableHeader().getDefaultRenderer();
Component aComponent = aRenderer.getTableCellRendererComponent(this,
aColumn.getHeaderValue(),
false, false, -1, 0);
public boolean isCellEditable(int row, int column) {return true;}
public class CellRenderer extends JLabel implements TableCellRenderer {
private LineBorder selectBorder;
private EmptyBorder emptyBorder;
private Dimension dim;
public CellRenderer() {
super();
emptyBorder = new EmptyBorder(1, 2, 1, 2);
selectBorder = new LineBorder(Color.red);
setOpaque(true);
setHorizontalAlignment(SwingConstants.CENTER);
dim = new Dimension();
dim.height = 22;
dim.width = 100;
setSize(dim);
public Component getTableCellRendererComponent (JTable table, Object value,
boolean isSelected,
boolean hasFocus,
int row, int column) {
super.getTableCellRendererComponent(this, value, isSelected, hasFocus, row, column);
if (isSelected) {
setBorder(selectBorder);
} else {
setBorder(emptyBorder);
return this;
} -
here is my problem I want my Log Files Filename to be created with respect to the Current Date..e.g. say today is May 24,2007....then the created log file will display in c;/ as c:/2007-05-24.csv....then if I'll use the application say in June 05..another file will be created c:/2007-06-05.
BufferedWriter out = new BufferedWriter(new FileWriter("c:/Filename.csv", true));
out.write(" AutoArchive-Process Started at ");
Calendar c = new GregorianCalendar();
out.write(c.getTime().toString());
out.close();thank you so much ..got it....one more question though how will i display the contents of this file and file directory in a jTestArea or JTable...let's say it will display the content of "c:/AutoArchive2007-05-24.csv" in a jTextarea or jTable....
user:jeff AutoArchive-Process Started at Thu May 24 15:41:54 GMT+08:00 2007
and ended at Thu May 24 15:41:54 GMT+08:00 2007
----------------------------------------------------------------------------------------------------- -
Number of of lines in af row.
Hi Experts.
I need some help. I'm trying to display JTextAreas in a table using the TableCellRenderer interface. My problem is that I have to display more than one line in each row (I need linewrap). I think the tables cell size prevents the expansion of the JTextArea. I've posted my code and marked the important places:
package box;
import java.applet.*;
import java.sql.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import com.borland.jbcl.layout.*;
import java.util.ArrayList;
import javax.swing.table.TableCellRenderer;
public class GUI
extends Applet {
boolean isStandalone = false;
BorderLayout borderLayout1 = new BorderLayout();
JTextField tArea1 = new JTextField();
Label tArea2 = new Label();
JButton jButton1 = new JButton();
JLabel jLabel1 = new JLabel();
JLabel jLabel2 = new JLabel();
JPanel rightPanel = new JPanel();
JPanel leftPanel = new JPanel();
JPanel leftTopPanel = new JPanel();
JPanel leftBotPanel = new JPanel();
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
Thread graphFrame;
dbInterface db = new dbInterface();
Connection dbConn = null;
//Get a parameter value
public String getParameter(String key, String def) {
return isStandalone ? System.getProperty(key, def) :
(getParameter(key) != null ? getParameter(key) : def);
//Construct the applet
public void init() {
int lastValue;
jbInit();
lastValue = db.getLatest(dbConn);
String temp = Integer.toString(lastValue);
showText(temp);
//Component initialization
private void jbInit() {
dbConn = db.dbConnect();
this.setLayout(new XYLayout());
tArea1.setBackground(Color.lightGray);
tArea1.setBorder(null);
tArea1.setDisabledTextColor(Color.white);
tArea1.setText("56");
tArea1.setHorizontalAlignment(JLabel.CENTER);
tArea2.setAlignment(Label.CENTER);
tArea2.setBackground(Color.lightGray);
tArea2.setText("");
tArea2.addMouseListener(new GUI_tArea2_mouseAdapter(this));
jButton1.setText("Set temperature");
jButton1.addMouseListener(new GUI_jButton1_mouseAdapter(this));
jButton1.addActionListener(new GUI_jButton1_actionAdapter(this));
jLabel1.setText("From db");
jLabel2.setText("UI");
String[] columnNames = {"test"};
Object[][] data = {{new JTextArea("Max f sf sf sf a fas f dsf s fds f dsf ds")}, {new JTextArea("test")}};
JTable table = new JTable(data, columnNames);
table.setDefaultRenderer(Object.class, new TableRenderer());
leftPanel.setLayout(new XYLayout());
rightPanel.setLayout(new XYLayout());
leftTopPanel.setLayout(new XYLayout());
leftBotPanel.setLayout(new XYLayout());
rightPanel.add(tArea1, new XYConstraints(50, 50, 30, 20));
rightPanel.add(jLabel1, new XYConstraints(50, 30, -1, -1));
rightPanel.add(jButton1, new XYConstraints(50, 80, 120, 22));
rightPanel.add(tArea2, new XYConstraints(140, 50, 30, 20));
rightPanel.add(jLabel2, new XYConstraints(140, 30, -1, -1));
splitPane.setLeftComponent(leftPanel);
splitPane.setRightComponent(rightPanel);
splitPane.setDividerLocation(150);
splitPane.setDividerSize(6);
JScrollPane scrollPane = new JScrollPane(table);
leftTopPanel.add(scrollPane, new XYConstraints(0,0,149,200));
leftPanel.add(leftTopPanel, new XYConstraints(0, 0, 150,200));
this.add(splitPane, new XYConstraints(0,0,400,300));
private void showText(final String text) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
tArea2.setText(text);
// Check if the new value crosses the specified limits
checkBounds(tArea2);
public void checkBounds(Label tArea2) {
// Parses the value in the tArea2 as an integer
int value = Integer.parseInt(tArea2.getText());
// Check if the limit is passe
if (value > 100) {
tArea2.setBackground(Color.red);
else {
tArea2.setBackground(Color.lightGray);
} class TableRenderer extends JLabel implements TableCellRenderer {
public TableRenderer() {
setOpaque(true);
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
JTextArea textA = (JTextArea) value;
textA.setLineWrap(true);
System.out.println("renderer");
textA.setBackground(Color.red);
return textA;
} public void jButton1_actionPerformed(ActionEvent e) {
String input = tArea1.getText();
showText(input);
public void tArea2_mouseClicked(MouseEvent e) {
this._disable();
graphFrame = new Thread(new graphForm(this));
graphFrame.start();
public void tArea2_mouseEntered(MouseEvent e) {
setCursor(new Cursor(Cursor.HAND_CURSOR));
public void tArea2_mouseExited(MouseEvent e) {
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
class GUI_jButton1_actionAdapter
implements ActionListener {
private GUI adaptee;
GUI_jButton1_actionAdapter(GUI adaptee) {
this.adaptee = adaptee;
public void actionPerformed(ActionEvent e) {
adaptee.jButton1_actionPerformed(e);
class GUI_jButton1_mouseAdapter
extends MouseAdapter {
private GUI adaptee;
GUI_jButton1_mouseAdapter(GUI adaptee) {
this.adaptee = adaptee;
class GUI_tArea2_mouseAdapter
extends MouseAdapter {
private GUI adaptee;
GUI_tArea2_mouseAdapter(GUI adaptee) {
this.adaptee = adaptee;
public void mouseEntered(MouseEvent e) {
adaptee.tArea2_mouseEntered(e);
public void mouseClicked(MouseEvent e) {
adaptee.tArea2_mouseClicked(e);
public void mouseExited(MouseEvent e) {
adaptee.tArea2_mouseExited(e);
}Search the Swing forum. This question has been asked twice in the last couple of days.
Maybe you are looking for
-
Hi i took my macbook pro to an apple store because it would not start correctly. The veredict was that the logic board was dead. As this is a very expensive item to replace, I have decided I will buy a new one but I am currently overseas, and will wa
-
Is it possible AT ALL to make fglrx work with the ATI RV505?!
I have an ATI X1550 graphics card based on the chipset in the topic subject... I wish my PC wasn't half-height, so I could go get a real graphics card.... but I have what I have for now, and I guess I should settle for it. So, the problem in question
-
iMessage is not working.... Jabber has disappeared from bottom left corner....
-
How to run procedure in sql navigator?
Hi, Can anyone tell me how can i run stored procedures in a package from SQL NAVIGATOR? Thank you
-
Ack! I saved changes in a sub-vi! Now it doesn't work
I don't know how I managed to do this... I got click-happy I guess. I changed the "Open/Create/Replace File" while trying to get it to work a little differently... then when I closed it I accidentally saved it (trigger finger was a little shaky dismo