How do I programmatically select JTable’s rows?

This program shows you how to select some rows in the JTable programmatically. Below we demonstrate how to select rows using the setRowSelectionInterval() method, remove or clear row selection using removeRowSelectionInterval() method and use the addRowSelectionInterval() to add more rows to the previously selected rows.

package org.kodejava.swing;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.awt.*;

public class JTableRowSelectProgrammatically extends JPanel {
    public JTableRowSelectProgrammatically() {
        initializePanel();
    }

    public static void showFrame() {
        JPanel panel = new JTableRowSelectProgrammatically();
        panel.setOpaque(true);

        JFrame frame = new JFrame("JTable Row Selection");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setContentPane(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(JTableRowSelectProgrammatically::showFrame);
    }

    private void initializePanel() {
        setLayout(new BorderLayout());
        setPreferredSize(new Dimension(500, 500));

        final JTable table = new JTable(new MyTableModel());
        table.setFillsViewportHeight(true);
        JScrollPane pane = new JScrollPane(table);

        JLabel label1 = new JLabel("From row: ");
        final JTextField field1 = new JTextField(3);
        JLabel label2 = new JLabel("To row: ");
        final JTextField field2 = new JTextField(3);
        JButton select = new JButton("Select");
        JButton clear = new JButton("Clear");
        JButton add = new JButton("Add another one");

        // Enables row selection mode and disable column selection
        // mode.
        table.setRowSelectionAllowed(true);
        table.setColumnSelectionAllowed(false);

        // Select rows based on the input.
        select.addActionListener(event -> {
            int index1 = 0;
            int index2 = 0;
            try {
                index1 = Integer.parseInt(field1.getText());
                index2 = Integer.parseInt(field2.getText());
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }

            if (index1 <= 0 || index2 <= 0 ||
                    index1 > table.getRowCount() ||
                    index2 > table.getRowCount()) {
                JOptionPane.showMessageDialog(table, "Selection out of range!");
            } else {
                table.setRowSelectionInterval(index1 - 1, index2 - 1);
            }
        });

        // Clears row selection
        clear.addActionListener(e -> {
            table.removeRowSelectionInterval(0, table.getRowCount() - 1);
            field1.setText("");
            field2.setText("");
        });

        // Add one more row after the last selected row.
        add.addActionListener(event -> {
            int index2 = 0;
            try {
                index2 = Integer.parseInt(field2.getText());
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }

            index2 = index2 + 1;
            if (index2 <= table.getRowCount()) {
                table.addRowSelectionInterval(index2 - 1, index2 - 1);
                field2.setText(String.valueOf(index2));
            }
        });

        JPanel command = new JPanel(new FlowLayout());
        command.add(label1);
        command.add(field1);
        command.add(label2);
        command.add(field2);
        command.add(select);
        command.add(clear);
        command.add(add);

        add(pane, BorderLayout.CENTER);
        add(command, BorderLayout.SOUTH);
    }

    static class MyTableModel extends AbstractTableModel {
        private final String[] columns = {"ID", "NAME", "AGE", "A STUDENT?"};
        private final Object[][] data = {
                {1, "Alice", 20, Boolean.FALSE},
                {2, "Bob", 10, Boolean.TRUE},
                {3, "Carol", 15, Boolean.TRUE},
                {4, "Mallory", 25, Boolean.FALSE}
        };

        public int getRowCount() {
            return data.length;
        }

        public int getColumnCount() {
            return columns.length;
        }

        public Object getValueAt(int rowIndex, int columnIndex) {
            return data[rowIndex][columnIndex];
        }

        @Override
        public String getColumnName(int column) {
            return columns[column];
        }

        // This method is used by the JTable to define the default
        // renderer or editor for each cell. For example if you have
        // a boolean data it will be rendered as a check box. A
        // number value is right aligned.
        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return data[0][columnIndex].getClass();
        }
    }
}

Below is the screen capture of the program.

Programmatically Select JTable Rows

Programmatically Select JTable Rows

How do I allow row or column selection in JTable?

To allow a row selection or a column selection or both row and column selection in JTable component we can turn it on and off by calling the JTable‘s setRowSelectionAllowed() and JTable‘s setColumnSelectionAllowed() methods.

Both of these methods accept a boolean value indicating whether the selection is allowed or not allowed. Setting both of them to true allow us to select rows and columns from JTable.

package org.kodejava.swing;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumnModel;
import java.awt.*;

public class TableAllowColumnSelection extends JPanel {
    public TableAllowColumnSelection() {
        initializePanel();
    }

    public static void showFrame() {
        JPanel panel = new TableAllowColumnSelection();
        panel.setOpaque(true);

        JFrame frame = new JFrame("JTable Column Selection");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setContentPane(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(TableAllowColumnSelection::showFrame);
    }

    private void initializePanel() {
        this.setLayout(new BorderLayout());
        this.setPreferredSize(new Dimension(500, 500));

        JTable table = new JTable(new PremiereLeagueTableModel());
        TableColumnModel columnModel = table.getColumnModel();
        columnModel.getColumn(0).setPreferredWidth(200);

        // setting to false disallow row selection in the table model
        table.setRowSelectionAllowed(false);

        // setting to true allow column selection in the table model
        table.setColumnSelectionAllowed(true);

        JScrollPane pane = new JScrollPane(table);
        this.add(pane, BorderLayout.CENTER);
    }

    static class PremiereLeagueTableModel extends AbstractTableModel {
        // TableModel's column names
        private final String[] columnNames = {
                "CLUB", "MP", "W", "D", "L", "GF", "GA", "GD", "PTS"
        };

        // TableModel's data
        private final Object[][] data = {
                {"Chelsea", 8, 6, 1, 1, 16, 3, 13, 19},
                {"Liverpool", 8, 5, 3, 0, 22, 6, 16, 18},
                {"Manchester City", 8, 5, 2, 1, 16, 3, 13, 17},
                {"Brighton", 8, 4, 3, 1, 8, 5, 3, 15},
                {"Tottenham", 8, 5, 0, 3, 9, 12, -3, 15}
        };

        @Override
        public int getRowCount() {
            return data.length;
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public String getColumnName(int column) {
            return columnNames[column];
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return getValueAt(0, columnIndex).getClass();
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            return data[rowIndex][columnIndex];
        }
    }
}
JTable Row and Column Selection

JTable Row and Column Selection

How do I handle exceptions using try-catch block?

An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program’s instructions. When an abnormal situation occurs within a method, an Exception object is thrown. This object contains information about the error or unusual problems that occur.

Creating an exception object and handing it to the runtime system is called throwing an exception. If you want to deal with the exceptions where they occur, you can include three kinds of code blocks in a method to handle them. try, catch, and finally blocks.

  • The try block encloses code that may give rise to one or more exceptions.
  • The catch block encloses code that is intended to handle exceptions to a particular type that may be thrown in the associated try block.
  • The code in a finally block is always executed before the method ends, regardless of whether any exceptions are thrown in the try block.
package org.kodejava.basic;

public class ExceptionHandlerExample {

    public static void main(String[] args) {
        int x = 1, y = 0, z = 0;

        try {
            // divide by 0 will throw an exception
            z = ExceptionHandlerExample.divide(x, y);
            System.out.println("z = " + z);
        } catch (ArithmeticException e) {
            e.printStackTrace();
        } finally {
            System.out.println("Finally block is always executed.");
        }
    }

    /**
     * Divide the given first number by the second number.
     *
     * @param x the first number.
     * @param y the second number.
     * @return the result of division.
     * @throws RuntimeException when an exception occurs.
     */
    private static int divide(int x, int y) throws RuntimeException {
        return x / y;
    }
}

Here is what happening when we run the program:

java.lang.ArithmeticException: / by zero
    at org.kodejava.basic.ExceptionHandlerExample.divide(ExceptionHandlerExample.java:28)
    at org.kodejava.basic.ExceptionHandlerExample.main(ExceptionHandlerExample.java:10)
Finally block is always executed.

How do I set the JTable’s selection mode?

There are three selection modes available in the JTable component. The selection mode can be a single selection, a single interval selection or a multiple interval selection. To set the selection mode we call the JTable.setSelectionMode() method and pass one of the following value as the parameter:

  • ListSelectionModel.SINGLE_SELECTION
  • ListSelectionModel.SINGLE_INTERVAL_SELECTION
  • ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
package org.kodejava.swing;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumnModel;
import java.awt.*;

public class TableSelectionModeDemo extends JPanel {
    public TableSelectionModeDemo() {
        initializePanel();
    }

    public static void showFrame() {
        JPanel panel = new TableSelectionModeDemo();
        panel.setOpaque(true);

        JFrame frame = new JFrame("JTable Single Selection");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setContentPane(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(TableSelectionModeDemo::showFrame);
    }

    private void initializePanel() {
        this.setLayout(new BorderLayout());

        JTable table = new JTable(new PremiereLeagueTableModel());
        TableColumnModel columnModel = table.getColumnModel();
        columnModel.getColumn(0).setPreferredWidth(200);

        // Settings table selection mode. We can use the following
        // three constants to define the selection mode.
        //
        // - ListSelectionModel.SINGLE_SELECTION
        // - ListSelectionModel.SINGLE_INTERVAL_SELECTION
        // - ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
        table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

        JScrollPane pane = new JScrollPane(table);
        this.add(pane, BorderLayout.CENTER);
        this.setPreferredSize(new Dimension(500, 500));
    }

    static class PremiereLeagueTableModel extends AbstractTableModel {
        // TableModel's column names
        private final String[] columnNames = {
                "CLUB", "MP", "W", "D", "L", "GF", "GA", "GD", "PTS"
        };

        // TableModel's data
        private final Object[][] data = {
                {"Chelsea", 8, 6, 1, 1, 16, 3, 13, 19},
                {"Liverpool", 8, 5, 3, 0, 22, 6, 16, 18},
                {"Manchester City", 8, 5, 2, 1, 16, 3, 13, 17},
                {"Brighton", 8, 4, 3, 1, 8, 5, 3, 15},
                {"Tottenham", 8, 5, 0, 3, 9, 12, -3, 15}
        };

        public int getRowCount() {
            return data.length;
        }

        public int getColumnCount() {
            return columnNames.length;
        }

        public Object getValueAt(int rowIndex, int columnIndex) {
            return data[rowIndex][columnIndex];
        }
    }
}
JTable Selection Mode Demo

JTable Selection Mode Demo

How do I set or change JTable column width?

Each column of a JTable component is represented by the TableColumn class. The method for setting or changing the width of the column includes the setMinWidth(), setMaxWidth() and setPreferredWidth(). These methods are used to set the minimum, maximum and the preferred width of the column respectively.

When we set only the preferred width of a table column and the container get resized the preferred width will be used to recalculate the new column width to fill the available space, but the preferred width value itself does not change.

TableColumn object of a table can be obtained by calling table’s getColumnModel() method which return an instance of TableColumnModel. After having the TableColumModel in hand we can get the table’s column by calling the getColumn(int index) method and passes the index of the column.

package org.kodejava.swing;

import javax.swing.*;
import javax.swing.table.TableColumn;
import java.awt.*;

public class TableColumnWidthDemo extends JPanel {
    public TableColumnWidthDemo() {
        initializePanel();
    }

    public static void showFrame() {
        JPanel panel = new TableColumnWidthDemo();
        panel.setOpaque(true);

        // Creates and configures the JFrame component for our
        // program.
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setContentPane(panel);
        frame.setTitle("Premiere League - Season 2021-2022");
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(TableColumnWidthDemo::showFrame);
    }

    private void initializePanel() {
        // Defines table's column names.
        String[] columnNames = {
                "CLUB", "MP", "W", "D", "L", "GF", "GA", "GD", "PTS"
        };

        // Defines table's data.
        Object[][] data = {
                {"Chelsea", 8, 6, 1, 1, 16, 3, 13, 19},
                {"Liverpool", 8, 5, 3, 0, 22, 6, 16, 18},
                {"Manchester City", 8, 5, 2, 1, 16, 3, 13, 17},
                {"Brighton", 8, 4, 3, 1, 8, 5, 3, 15},
                {"Tottenham", 8, 5, 0, 3, 9, 12, -3, 15}
        };

        // Defines table's column width.
        int[] columnsWidth = {
                200, 25, 25, 25, 25, 25, 25, 25, 50
        };

        // Creates an instance of JTable and fill it with data and
        // column names information.
        JTable table = new JTable(data, columnNames);

        // Configures table's column width.
        int i = 0;
        for (int width : columnsWidth) {
            TableColumn column = table.getColumnModel().getColumn(i++);
            column.setMinWidth(width);
            column.setMaxWidth(width);
            column.setPreferredWidth(width);
        }

        JScrollPane scrollPane = new JScrollPane(table);
        table.setFillsViewportHeight(true);
        this.setLayout(new BorderLayout());
        this.add(scrollPane, BorderLayout.CENTER);
        this.setPreferredSize(new Dimension(500, 500));
    }
}

Here is the table created by the program above:

JTable Column Width Demo

JTable Column Width Demo