Introdução
A classe JTable é utilizada para vizualizar dados em grid no Swing e é um dos componentes mais complexos desse pacote. Alias o JTable possui até um pacote especial, que contém diversas classes para sua utilização: javax.swing.table.
A JTable é um componente MVC (Model-View-Controller): o seu trabalho é dividido em 3 partes:
Model
É a parte que cuida dos dados, quem controla e distribui os dados na jtable. É implementado pela interface TableModel ( AbstractTableModel e DefaultTableModel ). Ela é responsavel por fornecedor os dados para a tabela, a qual requisitará os dados atraves do método getValueAt, informando a linha e a coluna. Este método retorna um Object, ou seja, um objeto qualquer, que pode ser um Integer, uma String ou uma outra classe que você tenha implementado.
View
É a parte que cuida da apresentação. É implementado pela interface CellRenderer. É como a apresentação é dada celula a celula na tabela, o renderer deve ser fornecedido para uma celula especifica. Na JTable é possivel fornecer tanto um renderer para a tabela inteira como para uma coluna especifica. Assim como na tablemodel requisitará o valor na linha e coluna especifica, aqui ele requisitara o objeto que ira apresentar o dados, passando como parametro a linha, a coluna o valor (object), a tabela (jtable), se esta celula esta selecionada e se ela celula possui o foco. Este método é o getCellRendererComponent, que irá retornar um JComponent. O DefaultCellRenderer implementa o JLabel para apresentar os dados, que é a forma de apresentação mais comum para um valor.
Controller
É a parte que controla a apresentação dos dados na view. É a própria JTable.
Como a JTable ja vem implementada para usar os tipos defaults existentes e implementados, para criar uma JTable simples não é tão complicado. O unico problema é que voce acaba se engessando quando precisar de algum recurso mais "completo".
Como fazer na prática?
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
public class Principal extends JFrame {
protected JTable table;
protected JScrollPane scroller;
Principal() {
super("Exemplo grid");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initComponents();
pack();
setVisible(true);
}
public void initComponents() {
// matriz que conterá os dados
String[][] dados = new String [][]{
{"SP","Sao Paulo"},
{"RJ","Rio de Janeiro"},
{"RN","Rio Grande do Norte"},
{"PR","Parana"}
};
// nome das colunas
String[] colunas = new String []{"Estado","Cidade"};
// modelo padrão
DefaultTableModel modelo = new DefaultTableModel(dados, colunas);
// cria tabela com modelo
table = new JTable(modelo);
scroller = new JScrollPane(table);
// adiciona na tela (frame)
setLayout(new BorderLayout());
getContentPane().add(scroller, BorderLayout.CENTER);
}
public static void main(String args[]) {
new Principal();
}
}
Tela:

Como fazer a JTable não permitir edição?
Solução é simples, é necessário criar um objeto que estenda a classe DefaultTableModel e substitua o método isCellEditable.
Para fazer isso substitua a linha
DefaultTableModel modelo = new DefaultTableModel(dados, colunas);
Por:
DefaultTableModel modelo = new DefaultTableModel(){
public boolean isCellEditable(int rowIndex, int mColIndex){
return false;
}
};
modelo.setDataVector(dados, colunas);
Como não permitir que o usuário selecione várias linhas?
Para resolver é fácil:
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
Como adicionar linhas após ter criado a JTable?
Fazer um método para adicionar linhas em qualquer lugar da classe:
/**
* Método para adicionar uma nova linha na JTable
*/
public void adicionaLinha(String coluna1, String coluna2) {
// Obtem o modelo da JTable
DefaultTableModel modelo = (DefaultTableModel)table.getModel();
// Adiciona uma nova linha em branco no modelo
modelo.addRow( new String [] {coluna1, coluna2} );
}
Para usar, basta em qualquer lugar basta colocar:
adicionaLinha("SC", "SANTA CATARINA");