Como preencher JTable coluna por coluna?

Pessoal, se eu não conseguir ajuda aqui, não sei mais onde, nem com a galera do trabalho consegui.

Tenho que preencher uma JTable com dados do BD. Estava com o DefaultTableModel, mudei implementando um model próprio seguindo algumas dicas na net e do GUJ.

O cenário é o seguinte:
Tenho as seguintes tabelas no banco:
horários (Classe Horario): Será a coluna de horários
agenda (Classe Agenda): Cada registro (objeto) será uma coluna
Funcionarios(Classe Funcionario): O total de funcionários será o total de colunas.

A primeira coluna da JTable, tenho que preencher com os horários da tabela de horários e o título dessa coluna deve ser HORÁRIO.
Os demais nomes das colunas devem ser os nomes dos funcionários da tabela de funcionários, ou seja, se mudar a quantidade de funcionários, as colunas também mudam.
Até aí, consegui colocar o nome certo nas colunas, pois passo o size() do tamanho da lista de funcionários, mas o processo de preenchimento da JTtable é linha por linha e pra conseguir preencher corretamente, tenho que preencher coluna por coluna, pois cada coluna seria um objeto diferente e pelo que entendi, na JTable, cada linha que representa um objeto.

A tabela agenda.

Essa JTable é somente para visualização, mas tem que ser assim, ou seja, o miolo da tabela vão os horários agendados marcados com um X. Veja a imagem abaixo:

Não consigo entender o funcionamento, se tiverem algum código, mesmo que simples, ajudarão muito. Não é folga, mas já estou a muuuuuuito tempo e não estou conseguindo fazer. Já olhei vários tutos, mas tá complicado.
http://code.google.com/p/towel/wiki/ObjectTableModel
http://www.guj.com.br/articles/147

Fiz a classe abaixo de um exemplo na net.

[code]
import java.util.List;

import javax.swing.table.AbstractTableModel;

import br.com.sistemasalaoloja.classes.Agenda;
import br.com.sistemasalaoloja.classes.Funcionarios;

public class AgendaTableModel extends AbstractTableModel{

private static final long serialVersionUID = 1L;
/* Array de Strings com o nome das colunas. */
private String[] colunas;
private List<String> listaHorarios;
private List<Agenda> listaAgenda;
private List<Funcionarios> listaFuncionarios;

public AgendaTableModel(String[] col, List<String> lista, List<Agenda> listaAg, List<Funcionarios> listaFunc){
	colunas = col;
	listaHorarios = lista;
	listaAgenda = listaAg;
	listaFuncionarios = listaFunc;
}

@Override
public int getColumnCount() {
	// Está retornando o tamanho do array "colunas".
	return colunas.length;
}

@Override
public int getRowCount() {
	// Retorna o tamanho da lista de funcionários.
	return listaAgenda.size();
}

/** Retorna o nome da coluna no índice especificado.
 * Este método é usado pela JTable para saber o texto do cabeçalho. */
public String getColumnName(int columnIndex){
	// Retorna o conteúdo do Array que possui o nome das colunas no índice especificado.
	System.out.println("Coluna " + columnIndex + ": " + colunas[columnIndex]);
	return colunas[columnIndex];
}

/* Retorna a classe dos elementos da coluna especificada.
 * Este método é usado pela JTable na hora de definir o editor da célula. */
@Override
public Class<?> getColumnClass(int columnIndex) {
	return colunas[columnIndex].getClass();
}


/** Retorna o valor da célula especificada
 * pelos índices da linha e da coluna. */
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
	
	return listaHorarios;
	/*Agenda agenda = listaAgenda.get(rowIndex);
	
	return agenda.getNomeFunc();*/
}

/** Seta o valor da célula especificada
 * pelos índices da linha e da coluna.
 * Aqui ele está implementado para não fazer nada,
 * até porque este table model não é editável. */
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
}

/** Retorna um valor booleano que define se a célula em questão
 * pode ser editada ou não.
 * Este método é utilizado pela JTable na hora de definir o editor da célula.
 * Neste caso, estará sempre retornando false, não permitindo que nenhuma
 * célula seja editada. */
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
	return false;
}

////////////////////////////////////////////////////////////
// Os métodos declarados até aqui foram as implementações //
// de TableModel, que são continuamente utilizados        //
// pela JTable para definir seu comportamento,            //
// por isso o nome Table Model (Modelo da Tabela).        //
//                                                        //
// A partir de agora, os métodos criados serão            //
// particulares desta classe. Eles serão úteis            //
// em algumas situações.                                  //
////////////////////////////////////////////////////////////

/** Retorna o funcionário da linha especificada. */
public String getHorario(int indiceLinha){
	return listaHorarios.get(indiceLinha);
}

/** Adiciona um registro. */
public void addHorario(String horario) {
	// Adiciona o registro.
	listaHorarios.add(horario);

	// Pega a quantidade de registros e subtrai um para achar
	// o último índice. É preciso subtrair um, pois os índices
	// começam pelo zero.
	int ultimoIndice = getRowCount() - 1;

	// Reporta a mudança. O JTable recebe a notificação
	// e se redesenha permitindo que visualizemos a atualização.
	fireTableRowsInserted(ultimoIndice, ultimoIndice);
}

public void addLinha(String addLinha){
	listaHorarios.add(addLinha);
	int ultimoIndice = getRowCount() - 1;
	fireTableRowsInserted(ultimoIndice, ultimoIndice);
}

/** Remove a linha especificada. */
public void removeSocio(int indiceLinha) {
	// Remove o funcionário da linha especificada.    	
	listaHorarios.remove(indiceLinha);

	// Reporta a mudança. O JTable recebe a notificação
	// e se redesenha permitindo que visualizemos a atualização.
	fireTableRowsDeleted(indiceLinha, indiceLinha);
}

/** Adiciona uma lista de horários ao final dos registros. */
public void addListaDeFuncionarios(List<String> funcionarios) {
	// Pega o tamanho antigo da tabela.
	int tamanhoAntigo = getRowCount();

	// Adiciona os registros.
	listaHorarios.addAll(funcionarios);

	// Reporta a mudança. O JTable recebe a notificação
	// e se redesenha permitindo que visualizemos a atualização.
	fireTableRowsInserted(tamanhoAntigo, getRowCount() - 1);
}

/** Remove todos os registros. */
public void limpar() {
	// Remove todos os elementos da lista de sócios.
	listaHorarios.clear();

	// Reporta a mudança. O JTable recebe a notificação
	// e se redesenha permitindo que visualizemos a atualização.
	fireTableDataChanged();
}

/** Verifica se este table model está vazio. */
public boolean isEmpty() {
	return listaHorarios.isEmpty();
}

}[/code]

Cara, cria uma view no teu bd, se possível usa o inner join, depois daí é só um select normal

Espero ter ajudado, falowwww

Olá VagnerChines, obrigado pela resposta. Como recuperar os dados no banco eu já tenho, mas conforme descrevi, o problema está em preencher a JTable.
A primeira coluna deve ser preenchida com os horários da tabela horários, a segunda coluna com o primeiro registro da tabela agenda, a segunda coluna com o segundo registro e assim por diante.
Eu até tentei montar um select com esses dados pra passar para a JTable, mas não rolou devido à forma como tenho que preencher a tabela.