Java JTable Tricks
Java's JTable is a GUI component that has been around for many many years. While a bit difficult to work with, it's almost a mandatory component in an application that displays a lot of data.
In this post I share some nice tricks for working with JTables in Java applications.
Scrolling
A JTable by itself does not provide any scrolling when handling a lot of data. To fix this, we need to place the table inside a JScrollPane component. Additionally, we can place this JScrollPane into a JPanel in our window:
myPanel.add(new JScrollPane(myTable,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED)
);
Notice how we are specifying vertical and horizontal scrollbars on a as needed basis.
Adding New Blank Rows
Adding new blank rows at run time is easy. We can use the addRow() method from the table's model:
DefaultTableModel model = (DefaultTableModel) myTable.getModel();
model.addRow(new Object[] {});
Removing Selected Rows
We can make a selection of multiple rows and delete them at runtime:
int numRows = myTable.getSelectedRows().length;
DefaultTableModel model = (DefaultTableModel) myTable.getModel();
for (int i = 0; i < numRows; i++) {
model.removeRow(myTable.getSelectedRow());
}
myTable.clearSelection();
File Type Cells
Let's say we want to associate a file to each record from the table. To do this, we can add a special column that will contain the File object, and to select this file we want to use the super useful JFileChooser component.
To achieve this, we need to set a custom cell editor to the column. Assuming we know the index of this special column, we can set it like this:
myTable.getColumnModel().getColumn(index).setCellEditor(new FileChooserCellEditor());
We will have to manually create and define this FileChooserCellEditor class in a FileChooserCellEditor.java file:
| import java.awt.Color; | |
| import java.awt.Component; | |
| import java.awt.Font; | |
| import java.io.File; | |
| import javax.swing.DefaultCellEditor; | |
| import javax.swing.JButton; | |
| import javax.swing.JFileChooser; | |
| import javax.swing.JTable; | |
| import javax.swing.JTextField; | |
| import javax.swing.SwingUtilities; | |
| import javax.swing.filechooser.FileNameExtensionFilter; | |
| import javax.swing.table.TableCellEditor; | |
| public class FileChooserCellEditor extends DefaultCellEditor implements TableCellEditor { | |
| private static final int CLICK_COUNT_TO_START = 2; | |
| private JButton button; | |
| private JFileChooser fileChooser; | |
| private String selectedFile = ""; | |
| public FileChooserCellEditor(FileNameExtensionFilter filter) { | |
| super(new JTextField()); | |
| setClickCountToStart(CLICK_COUNT_TO_START); | |
| button = new JButton(); | |
| button.setBackground(Color.white); | |
| button.setFont(button.getFont().deriveFont(Font.PLAIN)); | |
| button.setBorder(null); | |
| fileChooser = new JFileChooser(); | |
| fileChooser.setFileFilter(filter); | |
| } | |
| @Override | |
| public Object getCellEditorValue() { | |
| return selectedFile; | |
| } | |
| @Override | |
| public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { | |
| if (value != null) { | |
| selectedFile = value.toString(); | |
| } | |
| SwingUtilities.invokeLater(new Runnable() { | |
| public void run() { | |
| fileChooser.setSelectedFile(new File(selectedFile)); | |
| if (fileChooser.showOpenDialog(button) == JFileChooser.APPROVE_OPTION) { | |
| selectedFile = fileChooser.getSelectedFile().getAbsolutePath(); | |
| } | |
| fireEditingStopped(); | |
| } | |
| }); | |
| button.setText(selectedFile); | |
| return button; | |
| } | |
| } |
With this implementation you can now double click on the cell, and a nice file chooser will appear. After selecting the file, its absolute path value will be assigned and shown in the cell.