Creating a Java Table Using JTable

Child using a laptop
Sally Anscombe / Getty Images
01
of 04

The JTable Class

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 classJTable 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 - Part I

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.

02
of 04

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, click on a table cell in that row.
  • To select continuous, multiple rows, drag the mouse over several rows or click the table cells with the shift cell pressed.
  • To select non-continuous, multiple rows, click on table cells while holding down the control key (command key for Macs).

03
of 04

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.

04
of 04

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));