How to display multiple rows in JTable Cell
Multi-line cell JTable
can be easily used with customizable TableCellRenderer
. Use the following steps to create TableCellRenderer
.
Step 1: Create TableCellRenderer
The following code shows how to create multi-line values TableCellRenderer
for String[]
. Can be changed String[]
to a Vector
or another typeCollection
public class MultiLineTableCellRenderer extends JList<String> implements TableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
//make multi line where the cell value is String[]
if (value instanceof String[]) {
setListData((String[]) value);
}
//cell backgroud color when selected
if (isSelected) {
setBackground(UIManager.getColor("Table.selectionBackground"));
} else {
setBackground(UIManager.getColor("Table.background"));
}
return this;
}
}
Step 2: install TableCellRenderer
inJTable
MultiLineTableCellRenderer renderer = new MultiLineTableCellRenderer();
//set TableCellRenderer into a specified JTable column class
table.setDefaultRenderer(String[].class, renderer);
//or, set TableCellRenderer into a specified JTable column
table.getColumnModel().getColumn(columnIndex).setCellRenderer(renderer);
This is my screenshot:
source to share
It won't work if you are using DefaultTableModel
. You should use a custom model for your table that extends AbstractTableModel
and overrides the method getColumnClass()
, along with other abstract methods.
You will also set the table row height as mentioned in the comment above .
The official documentation from Oracle clarifies this.
source to share
Besides TableCellRenderer
based on JList<String>
as Channa Jayamuni suggests, you can also create a multi-line renderer on topDefaultTableCellRenderer
. The trick is to use the HTML feature of the component JLabel
and adjust the line height accordingly. This preserves more of the default renderer capabilities.
Enabling this renderer for all lines will do what you want in most cases:
setDefaultRenderer(String.class, new MultiLineCellRenderer());
The solution handles automatic line height to some extent . Those. this will not reduce the table row height if the content is updated with fewer rows. This is a rather tricky task as it depends on the content of any other cell in the same row.
/** Variant of DefaultTableCellRenderer that automatically switches
* to multi-line HTML when the value contains newlines. */
class MultiLineCellRenderer extends DefaultTableCellRenderer
{
@Override public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int column)
{ Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
int height = c.getPreferredSize().height;
if (table.getRowHeight(row) < height)
table.setRowHeight(row, height);
return c;
}
@Override protected void setValue(Object value)
{ if (value instanceof String)
{ String sVal = (String)value;
if (sVal.indexOf('\n') >= 0 && // any newline?
!(sVal.startsWith("<html>") && sVal.endsWith("</html>"))) // already HTML?
value = "<html><nobr>" + htmlEncodeLines(sVal) + "</nobr></html>";
}
super.setValue(value);
}
/** Encode string as HTML. Convert newlines to <br> as well.
* @param s String to encode.
* @return Encoded string. */
protected static String htmlEncodeLines(String s)
{ int i = indexOfAny(s, "<>&\n", 0); // find first char to encode
if (i < 0)
return s; // none
StringBuffer sb = new StringBuffer(s.length() + 20);
int j = 0;
do
{ sb.append(s, j, i).append(htmlEncode(s.charAt(i)));
i = indexOfAny(s, "<>&\n", j = i + 1);
} while (i >= 0);
sb.append(s, j, s.length());
return sb.toString();
}
private static String htmlEncode(char c)
{ switch (c) {
case '<': return "<";
case '>': return ">";
case '&': return "&";
case '\n': return "<br>";
default: return Character.toString(c);
} }
private static int indexOfAny(String s, String set, int start)
{ for (int i = start; i < s.length(); ++i)
if (set.indexOf(s.charAt(i)) >= 0)
return i;
return -1;
}
}
source to share
If any table has a large amount of data, the use of the scrollbar applies to the JTable. JScrollPane provides a scrollable scroll bar and you get all the content. A simple example using JTable:
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
public class ScrollableJTable{
public static void main(String[] args) {
new ScrollableJTable();
}
public ScrollableJTable(){
JFrame frame = new JFrame("Creating a Scrollable JTable!");
JPanel panel = new JPanel();
String data[][] =
{{"001","abc","xyz","wtwt","gwgw","tttr","rtrt"},
{"002","rwtr","ttrt","rtttr","trt","rtrt","trtrd"},
{"003","rtt","trt","trt","trrttr","trt","rtr"},
{"004","trt","trtt","trtrt","rtrtt","trt","trrt"},
{"001","rttr","trt","trt","trtr","trt","trttr"},
;
JTable table = new JTable(data,col);
JTableHeader header = table.getTableHeader();
header.setBackground(Color.yellow);
JScrollPane pane = new JScrollPane(table);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
panel.add(pane);
frame.add(panel);
frame.setSize(500,150);
frame.setUndecorated(true);
frame.getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Now you can modify this table according to your requirements.
source to share