JTable com JComboBox não ficam editaveis

11 respostas
furacao123

Aew galera estou tendo uma dificuldade ao tentar implementar JComBox em um Model exteds AbstractTableModel, segue o modelo...

public class FuncionarioAtributoModel extends AbstractTableModel {

    private Object[][] tabela;
    private String[] colunas = {"", "Código", "Descrição", "Valor"};
    private Class[] types = new Class[]{
        java.lang.Boolean.class, java.lang.String.class,
        java.lang.String.class, java.lang.String.class
    };
    private boolean[] canEdit = new boolean[]{
        true, false, false, true
    };
    private List<FuncionarioAtributo> listaAtributo;
    private List<FuncAtributoValor> listaValor;
    private FuncionarioAtributo funcAtributo;
    private FuncAtributoValor funcValor;

    public FuncionarioAtributoModel(List<FuncionarioAtributo> listaAtributo,
            List<FuncAtributoValor> listaValor) {
        this.listaAtributo = listaAtributo;
        this.listaValor = listaValor;
        filtrar();
    }

    private void filtrar() {
        tabela = new Object[listaAtributo.size()][colunas.length];
        int i = 0;
        while (i < listaAtributo.size()) {

            if (!listaAtributo.contains(listaValor.get(i).getFuncAtributo())) {
                funcAtributo = listaAtributo.get(i);
                tabela[i][0] = false;
                tabela[i][1] = funcAtributo.getId();
                tabela[i][2] = funcAtributo.getDescricao();
                tabela[i][3] = "";
            } else {
                funcValor = listaValor.get(i);
                tabela[i][0] = true;
                tabela[i][1] = funcValor.getId();
                tabela[i][2] = funcValor.getFuncAtributo().getDescricao();
                tabela[i][3] = funcValor.getValor();
            }
            i++;
        }
    }

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

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

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        return tabela[rowIndex][columnIndex];
    }

    @Override
    public String getColumnName(int col) {
        return colunas[col];
    }

    @Override
    public Class getColumnClass(int c) {
        return types[c];
    }

    @Override
    public boolean isCellEditable(int row, int col) {
        return canEdit[col];
    }
}

a Coluna 0 é formada por checkBox mas não consigo fazer com que eles fiquem editaveis ao clicar nao faz nada como resolvo esse problema?

Obrigado.

11 Respostas

ViniGodoy

Seu modelo, apesar de ser filho de AbstractTableModel, é praticamente uma cópia do DefaultTableModel.

O array de Object[] é completamente desnecessário, basta trabalhar diretamente com sua List<FuncionarioAtributo>.

Para que a alteração do valor funcione, você também precisa sobrescrever o método setValueAt.

Marky.Vasconcelos

E o que aparece é um JCheckBox se for a coluna 0, pois ele retorna Boolean.class (A não ser que voce alterou o CellRenderer).

E voce precisa sobreescrever o método setValueAt pois se não seu dado não será atualizado.

De resto, siga a dica do ViniGodoy.

furacao123

Imaginei mesmo que teria de sobscrever esse metodo, ta feito e funcinou belezinha, agora quanto ao model estar parecido com o DefaultTableModel é porque esse modelo tem campos que não tenho no objeto FuncionarioAtributo, entao nao tenho como setar o valor verdadeiro ou falço para o checkbox da coluna 0.

ViniGodoy

Existem duas alternativas melhores para fazer o que você fez.

A primeira, é definir uma classe com os campos extras, e associar ao objeto da linha por um map.

A segunda é criar um decorator, com as propriedades a mais.
Como o decorator é uma classe super simples que só existe dentro do model, você pode até deixar os atributos publicos.

public static class FuncionarioAtributoView { public bool checked; public FuncionarioAtributo fa; }

Aí dentro do model vc faz um List<FuncionarioAtributoView> ao invés de um List<FuncionarioAtributo>. E faz seu model trabalhar com FuncionarioAtributo para quem o vê de fora.

furacao123

vou fazer isso, mas vou ter de continuar usando o List<FuncionarioAtributo> por causa do JPA, aproveitando o post, por exemplo eu trabalhando diretamente com a List ao invez de array de Object o que melhoria na parte de pegar os dados da tabela?

Existe uma maneira mais facil do que ter de percorrer celula a celula da tabela para seta um um objeto e gravar?

Pensei em fazer o Table Model me retornar a lista atuaizada seria o mais correto?

Obrigado.

ViniGodoy

Sim, é isso que eu geralmente faço. No caso, se você usar o decorator que comentei acima, você faz o model retornar a lista sem o decorator. E aí salva ela no JPA.

furacao123

Mas por exemplo como faria para criar um decorator de uma classe mapeada no JPA segue o mapeamento do FuncionarioAtributo

public class FuncionarioTipo implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id", nullable = false)
    private Integer id;
    @Column(name = "descricao")
    private String descricao;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "funcionarioTipo", fetch = FetchType.LAZY)
    private List<Funcionario> funcionarioList;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "funcionarioTipo", fetch = FetchType.EAGER)
    private List<FuncionarioAtributo> funcAtributoList;

Como eu posso substituir esse metodo?
colocando a anotação de Transient e deixando esse metodo + o View?

Estou criando um atributo Transient em minha classe FuncionarioAtributo, o checked e trabalho diretamente com ele

ViniGodoy

O decorator jamais vai ser persistido. Ele é só uma classezinha para complementar informações do model. Ele nem sequer precisa saber que o JPA existe.

furacao123

mas o decorator fica na camada de Modelo ou de View?

ViniGodoy

Só existe no interior do TableModel. O TableModel é um intermediário entre o modelo (sua classe JPA) e a view (a tabela).

furacao123

Ah é que confundi quando voce me falou Model por isso nao entendi onde ficava o decorator, o problema é a forma como esta feito os relacionamentos, tenho Funcionario relacionado com um FuncionarioTipo esse FuncionarioTipo é ligado com vários FuncionarioAtributo que por sua vez é ligado com varios FuncAtributoValor onde cada FuncAtributoValor é ligado a um Funcionario

no meu TableModel estou montando uma tabelinha onde o usuario escolhe o Tipo do Funcionario e de acordo com o tipo traz na tabela os FuncionarioAtributo se for um novo registro, no caso de edição traz na tabela o valor do FuncAtributoValor do Funcionario, estou pensando e montando o TableModel com esses relacionamento

Criado 13 de setembro de 2010
Ultima resposta 13 de set. de 2010
Respostas 11
Participantes 3