Redimensionar largura das colunas de jTable com TableModel próprio

11 respostas
claudneto

Código do TableModel:

package gerenciamentodecampeonatos;

import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;

/**
 *
 * @author C. Neto
 */
public class CadastroTableModel extends AbstractTableModel  {
    /* Lista de Jogadores que representam as linhas. */
	private List<Jogador> linhas;

	/* Array de Strings com o nome das colunas. */
	private String[] colunas = new String[] {
			"*", "Nome", "Email", "NumUSP", "Tel"};


	/* Cria um CadastroTableModel vazio. */
	public CadastroTableModel() {
		linhas = new ArrayList<Jogador>();
	}

	/* Cria um CadastroTableModel carregado com
	 * a lista de jogadores especificada. */
	public CadastroTableModel(List<Jogador> listaDeJogadores) {
		linhas = new ArrayList<Jogador>(listaDeJogadores);
	}


	/* Retorna a quantidade de colunas. */
	@Override
	public int getColumnCount() {
		// Está retornando o tamanho do array "colunas".
		// Mas como o array é fixo, vai sempre retornar 5.
		return colunas.length;
	}

	/* Retorna a quantidade de linhas. */
	@Override
	public int getRowCount() {
		// Retorna o tamanho da lista de jogadores.
		return linhas.size();
	}

	/* Retorna o nome da coluna no índice especificado.
	 * Este método é usado pela JTable para saber o texto do cabeçalho. */
	@Override
	public String getColumnName(int columnIndex) {
		// Retorna o conteúdo do Array que possui o nome das colunas
		// no índice especificado.
		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) {
		// Retorna a classe referente a coluna especificada.
		// Aqui é feito um switch para verificar qual é a coluna
		// e retornar o tipo adequado. As colunas são as mesmas
		// que foram especificadas no array "colunas".
		switch (columnIndex) {
		case 0: // Primeira coluna é o id, que é um int.
			return int.class;
		case 1: // Segunda coluna é o nome, que é uma String..
			return String.class;
		case 2: // Terceira coluna é o email,
			return String.class;
                case 3: // Quarta coluna é o número USP,
                        return int.class;
		case 4: // Quinta coluna é o telefone.
			return String.class;
		default:
			// Se o índice da coluna não for válido, lança um
			// IndexOutOfBoundsException (Exceção de índice fora dos limites).
			// Não foi necessário verificar se o índice da linha é inválido,
			// pois o próprio ArrayList lança a exceção caso seja inválido.
			throw new IndexOutOfBoundsException("columnIndex out of bounds");
		}
	}

	/* Retorna o valor da célula especificada
	 * pelos índices da linha e da coluna. */
	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		// Pega o jogador da linha especificada.
		Jogador jog = linhas.get(rowIndex);

		// Retorna o campo referente a coluna especificada.
		// Aqui é feito um switch para verificar qual é a coluna
		// e retornar o campo adequado. As colunas são as mesmas
		// que foram especificadas no array "colunas".
		switch (columnIndex) {
		case 0: // Primeira coluna é o id.
			return jog.getId();
		case 1: // Segunda coluna é o nome.
			return jog.getNome();
		case 2: // Terceira coluna é email.
			return jog.getEmail();
		case 3: // Quarta coluna é o número USP.
			return jog.getNumUSP();
                case 4: // Quinta coluna é o telefone.
			return jog.getTelefone();
		default:
			// Se o índice da coluna não for válido, lança um
			// IndexOutOfBoundsException (Exceção de índice fora dos limites).
			// Não foi necessário verificar se o índice da linha é inválido,
			// pois o próprio ArrayList lança a exceção caso seja inválido.
			throw new IndexOutOfBoundsException("columnIndex out of bounds");
		}
	}

	/* 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) {
            // Pega o jogador da linha especificada.
		Jogador jog = linhas.get(rowIndex);

		// Retorna o campo referente a coluna especificada.
		// Aqui é feito um switch para verificar qual é a coluna
		// e setar o campo adequado. As colunas são as mesmas
		// que foram especificadas no array "colunas".
		switch (columnIndex) {
		case 0: // Primeira coluna é o id.
                        if (aValue.getClass() == int.class)
			jog.setId (Integer.parseInt(aValue.toString()));
		case 1: // Segunda coluna é o nome.
                        if (aValue.getClass() == String.class)
			jog.setNome(aValue.toString());
		case 2: // Terceira coluna é email.
                        if (aValue.getClass() == String.class)
			jog.setEmail(aValue.toString());
		case 3: // Quarta coluna é o número USP.
                        if (aValue.getClass() == int.class)
			jog.setNumUSP (Integer.parseInt(aValue.toString()));
                case 4: // Quinta coluna é o telefone.
                        if (aValue.getClass() == String.class)
			jog.setTelefone(aValue.toString());
		default:
			// Se o índice da coluna não for válido, lança um
			// IndexOutOfBoundsException (Exceção de índice fora dos limites).
			// Não foi necessário verificar se o índice da linha é inválido,
			// pois o próprio ArrayList lança a exceção caso seja inválido.
			throw new IndexOutOfBoundsException("columnIndex out of bounds");
		}
        }

	/* 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;
	}

	/* Retorna o jogador da linha especificada. */
	public Jogador getJogador(int indiceLinha) {
		return linhas.get(indiceLinha);
	}

	/* Adiciona um registro. */
	public void addJogador(Jogador jog) {
		// Adiciona o registro.
		linhas.add(jog);

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

	/* Remove a linha especificada. */
	public void removeJogador(int indiceLinha) {
		// Remove o jogador da linha especificada.
		linhas.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 jogadores ao final dos registros. */
	public void addListaDeJogador(List<Jogador> jog) {
		// Pega o tamanho antigo da tabela.
		int tamanhoAntigo = getRowCount();

		// Adiciona os registros.
		linhas.addAll(jog);

		// 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 jogadores.
		linhas.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 linhas.isEmpty();
	}
}

Agora vem a dúvida...como setar a largura das colunas dentro do TableModel? Eu precisaria de um método pra isso e chamar no meu programa ou posso fazer isso no construtor?

Outra dúvida, como aplicar esse TableModel na minha jTable da minha aplicação?

11 Respostas

ViniGodoy

Não seta. O TableModel é um modelo dos dados, enquanto a largura da coluna é um atributo de view.
E aspectos de view, você deve definir no seu frame.

Poderia ser assim:

suaTable.setModel(new CadastroTableModel(new jogadorDao().carregarJogadores()));

Geralmente é bom criar um atributo só para o seu model:

CadastroTableModel model = new CadastroTableModel();

Assim vc pode usa-lo depois:

suaTable.setModel(this.model); this.model.addListaDeJogador(new jogadorDao().carregarJogadores());

claudneto

Foi da maneira que eu imaginei mesmo.

Porém, a largura tá complicado de resolver!

CadastroTableModel model =  new CadastroTableModel();
        tabela_cadastro.setModel(model);

        tabela_cadastro.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        tabela_cadastro.getColumnModel().getColumn(0).setWidth(55);
        tabela_cadastro.getColumnModel().getColumn(1).setWidth(300);
        tabela_cadastro.getColumnModel().getColumn(2).setWidth(80);
        tabela_cadastro.getColumnModel().getColumn(3).setWidth(80);
        tabela_cadastro.getColumnModel().getColumn(4).setWidth(80);

        model.fireTableDataChanged();

Isso não resolve! Eu to jogando isso no construtor do FrameView pra ele setar essas informações, logo que for criado o componente.

ViniGodoy

Use o comando setPreferredWidth(), e não o setWidth().

RenanRosa
claudneto:
Foi da maneira que eu imaginei mesmo.

Porém, a largura tá complicado de resolver!

CadastroTableModel model =  new CadastroTableModel();
        tabela_cadastro.setModel(model);

        tabela_cadastro.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        tabela_cadastro.getColumnModel().getColumn(0).setWidth(55);
        tabela_cadastro.getColumnModel().getColumn(1).setWidth(300);
        tabela_cadastro.getColumnModel().getColumn(2).setWidth(80);
        tabela_cadastro.getColumnModel().getColumn(3).setWidth(80);
        tabela_cadastro.getColumnModel().getColumn(4).setWidth(80);

        model.fireTableDataChanged();

Isso não resolve! Eu to jogando isso no construtor do FrameView pra ele setar essas informações, logo que for criado o componente.

na TableColumnModel tem um metodo chamado setPreferredWidth(int), utilize ele.

claudneto

Aeeee…vlw!

[RESOLVIDO]

RenanRosa

claudneto:
Aeeee…vlw!

[RESOLVIDO]

foi minha ajuda que resolveu ? :stuck_out_tongue:
nossa, acabei de postar e no mesmo minuto já postou :lol:

ViniGodoy

RenanRosa:
foi minha ajuda que resolveu ? :stuck_out_tongue:
nossa, acabei de postar e no mesmo minuto já postou :lol:

Eu havia dito a mesma coisa 13 minutos antes.

claudneto

Foi a ajuda dos dois!

Hahaha…

Mas pra que existe o setWidth() se ele não funciona?!

ViniGodoy

Isso é uma longa história: http://www.developer.com/java/ent/article.php/630651/Swing-from-A-to-Z-Minimum-Maximum-and-Preferred-Sizes.htm

Mas basicamente o redimensionamento funciona baseado no seu tamanho preferido, ou seja, no tamanho que o componente idealmente teria que ter.
O tamanho final é ajustado pelo container do do componente.

RenanRosa

ViniGodoy:
RenanRosa:
foi minha ajuda que resolveu ? :stuck_out_tongue:
nossa, acabei de postar e no mesmo minuto já postou :lol:

Eu havia dito a mesma coisa 13 minutos antes.

pois é, a página tava aberta, pois quando eu entro no GUJ eu vou abrindo em nova página varios tópicos, ai você adicionou a resposta e eu não vi

fwsales

Opa, fui ajudado também!
Rsrs…

package table;

import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;
import model.Venda;

public class VendaTableModel extends AbstractTableModel{

    public static final int COL_ITEM = 0;
    public static final int COL_QTDE = 1;
    public static final int COL_CODIGOBARRAS = 2;
    public static final int COL_UNITARIO = 3;
    public static final int COL_DESCRICAO = 4;
    public static final int COL_ST = 5;
    public static final int COL_VALORITEM = 6;
    public ArrayList<Venda> listarVenda;

    public VendaTableModel(ArrayList<Venda>l){
        listarVenda = new ArrayList<Venda>(l);
    }

    public int getRowCount() {
        return listarVenda.size();
    }

    public int getColumnCount() {
        return 7;
    }

    public Object getValueAt(int linhas, int colunas) {
        Venda ven = listarVenda.get(linhas);
        if(colunas == COL_ITEM) return ven.getItem();
        if(colunas == COL_QTDE) return ven.getQuantidade_unidade();
        if(colunas == COL_CODIGOBARRAS) return ven.getCodigo_barras();
        if(colunas == COL_UNITARIO) return ven.getValor_unitario();
        if(colunas == COL_ST) return ven.getSt();
        if(colunas == COL_DESCRICAO) return ven.getNome_produto();
        if(colunas == COL_VALORITEM) return ven.getValor_item();
        return null;
    }

    @Override
    public String getColumnName(int colunas){
        if(colunas == COL_ITEM) return "Item";
        if(colunas == COL_QTDE) return "Qtde. Unid.";
        if(colunas == COL_CODIGOBARRAS) return "Cód.Barras";
        if(colunas == COL_UNITARIO) return "Unit.";
        if(colunas == COL_ST) return "ST";
        if(colunas == COL_DESCRICAO) return "Descrição";
        if(colunas == COL_VALORITEM) return "Valor Item";
        return null;
    }



}

JFrame:

public final class cad_transacao extends javax.swing.JFrame {
    public cad_transacao() {
        initComponents();
        setLocationRelativeTo(null);
        preencher_table();
    }

//...

    private void preencher_table() {
        tbDados.setModel(new VendaTableModel(new VendaDAO().listarCoo(tfCoo.getText())));
        ajusta_tamanho_coluna();
    }

//...

    private void ajusta_tamanho_coluna(){
        tbDados.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        tbDados.getColumnModel().getColumn(0).setPreferredWidth(60);
        tbDados.getColumnModel().getColumn(1).setPreferredWidth(80);
        tbDados.getColumnModel().getColumn(2).setPreferredWidth(150);
        tbDados.getColumnModel().getColumn(3).setPreferredWidth(80);
        tbDados.getColumnModel().getColumn(4).setPreferredWidth(300);
        tbDados.getColumnModel().getColumn(5).setPreferredWidth(80);
        tbDados.getColumnModel().getColumn(6).setPreferredWidth(80);
    }
}
Criado 29 de abril de 2011
Ultima resposta 9 de jan. de 2012
Respostas 11
Participantes 4