Creating a Java Table Using JTable

Child using a laptop
Sally Anscombe / Getty Images

Java provides a useful class called JTable that enables you to create tables when developing graphical user interfaces using the components of Java's Swing API. You can enable your users to edit the data or just view it. Note that the table doesn't actually contain data — it's entirely a display mechanism.

This step-by-step guide will show how to use the class

JTable
 to create a simple table.

Note: Like any Swing GUI, you'll need to make a container in which to display the 

JTable
 . If you're unsure how to do this then look at Creating a Simple Graphical User Interface

Using Arrays to Store the Table Data

A simple way to provide data for the

JTable
class is to use two arrays. The first holds the column names in a
String
array:
String[] columnNames = {"First Name", "Surname", "Country"
, "Event", "Place", "Time", "World Record" };

The second array is a two-dimensional object array that holds the data for the table. This array, for example, includes six Olympic swimmers:

Object[][] data = {
{"César Cielo", "Filho", "Brazil", "50m freestyle",1 , "21.30", false },
{"Amaury", "Leveaux", "France", "50m freestyle", 2, "21.45", false },
{"Eamon", "Sullivan", "Australia", "100m freestyle", 2, "47.32", false },
{"Michael", "Phelps", "USA", "200m freestyle", 1, "1:42.96", false },
{"Ryan", "Lochte", "USA", "200m backstroke", 1, "1:53.94", true },
{"Hugues", "Duboscq", "France", "100m breaststroke", 3, "59.37", false }
};

The key here is to make sure the two arrays have the same number of columns.

Constructing the JTable

Once you have the data in place, it's a simple task to create the table. Just call the

JTable
constructor and pass it the two arrays:
JTable table = new JTable(data, columnNames);

You will probably want to add scroll bars to ensure the user can see all the data. To do so, place the

JTable
into a
JScrollPane
:
JScrollPane tableScrollPane = new JScrollPane(table);

Now when the table is displayed, you will see the columns and rows of data and will have the capability to scroll up and down.

The JTable object provides an interactive table. If you double-click on any of the cells, you will be able to edit the contents — although any editing affects only the GUI, not the underlying data. (An event listener would need to be implemented to handle the changing of data.).

To change the widths of the columns, hover the mouse on the edge of a column header and drag it back and forth. To change the order of the columns, click and hold a column header, then drag it to the new position.

Sorting Columns

To add the ability to sort the rows, call the

setAutoCreateRowSorter
method:
table.setAutoCreateRowSorter(true);

When this method is set to true, you can click on a column header to sort the rows according to the contents of the cells under that column.

Changing the Appearance of the Table

To control the visibility of the grid lines, use the

setShowGrid
method:
table.setShowGrid(true);

To change the color of the table altogether, use the

setBackground
and
setGridColor
methods:
table.setGridColor(Color.YELLOW);

table.setBackground(Color.CYAN);

The column widths of the table are equal by default. If the container the table is in is re-sizeable, then the widths of the columns will expand and shrink and the container grows bigger or smaller. If a user resizes the column, then the width of columns to the right will change to accommodate the new column size.

The initial column widths can be set using the setPreferredWidth method or a column. Use the TableColumn class to first get a reference to the column, and then the setPreferredWidth method to set the size:

TableColumn eventColumn = table.getColumnModel().getColumn(3);

eventColumn.setPreferredWidth(150);

 

TableColumn placeColumn = table.getColumnModel().getColumn(4);

placeColumn.setPreferredWidth(5);

Selecting Rows

By default, the user can select the rows of the table in one of three ways:

  • To select a single row, select a table cell in that row.
  • To select continuous, multiple rows, drag the mouse over several rows or select the table cells with the shift cell pressed.
  • To select non-continuous, multiple rows, select table cells while holding down the control key (command key for Macs).

Using a Table Model

Using a couple of arrays for the data of a table can be useful if you want a simple String-based table which can be edited. If you look at the data array we created, it contains other data types than

Strings
- the
Place
column contains
ints
and the
World Record
column contains
booleans
. Yet both these columns are displayed as Strings. To change this behavior, create a table model.

A table model manages the data to be displayed in the table. To implement a table model, you can create a class that extends the

AbstractTableModel
class:
public abstract class AbstractTableModel extends Object implements TableModel, Serializable{

 public int getRowCount();

 public int getColumnCount();

 public Object getValueAt(int row, int column);

 public String getColumnName(int column;

 public boolean isCellEditable(int rowIndex, int columnIndex);

 public Class getColumnClass(int columnIndex);

}

The six methods above are those used in this step-by-step guide, but there are more methods defined by the

AbstractTableModel
class that are useful in manipulating the data in a
JTable
object. When extending a class to use the
AbstractTableModel,
 you are required to implement only the
getRowCount
,
getColumnCount
and
getValueAt
methods. 

Create a new class implementing those five methods shown above:

class ExampleTableModel extends AbstractTableModel{

 

 String[] columnNames = {"First Name", "Surname", "Country"

 , "Event", "Place", "Time", "World Record" };

 

 Object[][] data = {

 {"César Cielo", "Filho", "Brazil", "50m freestyle",1 , "21.30", false },

 {"Amaury", "Leveaux", "France", "50m freestyle", 2, "21.45", false },

 {"Eamon", "Sullivan", "Australia", "100m freestyle", 2, "47.32", false },

 {"Michael", "Phelps", "USA", "200m freestyle", 1, "1:42.96", false },

 {"Larsen", "Jensen", "USA", "400m freestyle", 3, "3:42.78", false },

 };

 

 @Override

 public int getRowCount()

 {

 return data.length;

 }

 

 @Override

 public int getColumnCount() 

 {

 return columnNames.length;

 }

 

 @Override

 public Object getValueAt(int row, int column)

 { 

 return data[row][column];

 }

 

 @Override

 public String getColumnName(int column) {

 return columnNames[column];

 }@Override

 public Class getColumnClass(int c) {

 return getValueAt(0, c).getClass();

 }@Override

 public boolean isCellEditable(int row, int column)

 {

 if (column == 1 || column == 2)

 {

 return false;

 }

 else

 {

 return true;

 }

 }

 }

It makes sense in this example for the

ExampleTableModel
class to hold the two strings containing the table data. Then, the
getRowCount,
 
getColumnCount
,
getValueAt
and
getColumnName
methods can use the arrays to provide the values for the table. Also, notice how the
isCellEditable
method has been written to disallow the first two columns to be edited.

Now, instead of using the two arrays to create the

JTable
object, we can use the
ExampleTableModel
class:
JTable table = new JTable(new ExampleTableModel());

When the code runs, you will see that the

JTable
object is using the table model because none of the table cells are editable, and the column names are being correctly used. If the
getColumnName
method had not been implemented, then the column names on the table would display as the default names of A, B, C, D, etc.

Let's now consider the method 

getColumnClass
. This alone makes the table model worth the implementation because it provides the
JTable
object with the data type contained within each column. If you remember, the object data array has two columns that aren't
String
data types: the
Place
column which contains ints, and the
World Record
column which contains
booleans
. Knowing these data types changes the functionality provided by the
JTable
object for those columns. Running the sample table code with the table model implemented means the
World Record
column will actually be a series of checkboxes.

Adding a ComboBox Editor

You can define custom editors for the cells in the table. For example, you could make a combo box an alternative to the standard text editing for a field.

Here's an example using 

JComboBox
the country field:
String[] countries = {"Australia", "Brazil", "Canada", "China"
,"France", "Japan", "Norway", "Russia", "South Korea"
, "Tunisia", "USA"};
JComboBox countryCombo = new JComboBox(countries);

To set the default editor for the country column, use the

TableColumn
class to get a reference to the country column, and the
setCellEditor
method to set the
JComboBox
as the cell editor:
TableColumn countryColumn = table.getColumnModel().getColumn(2);
countryColumn.setCellEditor(new DefaultCellEditor(countryCombo));