Alguém tem um exemplo de uma classe que extenda de SwingWorker, onde ela alimente uma JTable adicionando linhas ou alterando algumas ?
Exemplo:
...
this.rotina=newString[]{"Clientes", "Processando", String.valueOf(qtdRegistros), "0"};this.modelo.addRow(this.rotina);intlinhas=this.modelo.getRowCount();for(inti=0; i < qtdRegistros; i++) {this.rotina=newString[]{String.valueOf(i)};this.modelo.setValueAt(this.rotina,linhas,4); //desta forma não gera erro, mas pára aqui e não continua no restante do código.
...
}
...
O exemplo abaixo funciona bem. Só que adiciona linhas para cada registro trabalhado (fato que não quero). Apenas citei para deixar claro que a rotina não está com problema no for{}
Não seria interessante (e mais rápido) vc usar um AbstractTableModel , popular uma List com valores e adicioná-la ao model?
V
vicentedepaula
Olá luiz_renato,
Pois bem, estou utilizando o DefaultTableModel pelo seguinte:
esta JTable servirá apenas para posicionar o usuário de como está andamento de uma fila de processos. Trata-se de uma rotina de importação para diversos cadastros, onde aparecerá nesta tabela aquilo que está sendo processando ou que já finalizou. Algo semelhante ao que temos na rotina de exportação de dados de tabelas do MS Sql Server. Ao todo não passará de 20 importações.
Ex.:
Cadastro | Status | Total de Registros | Registro atual
Produtos | Finalizado | 89 | 89
Clientes | Processando | 1000 | 27 (este 27 é que vai sendo modificado dentro do for{} )
…
Sugestões ?
luiz_renato
Deixa eu entender:
Cadastro | Status | Total de Registros | Registro atual
Produtos | Finalizado | 89 | 89
Clientes | Processando | 1000 | 27
são array´s de valores que vao preencher as jTable´s ?
V
vicentedepaula
É apenas uma jtable, preenchida com um array de string, ver this.rotina.
luiz_renato
Aconselho usar TableModel mas vai uma dica (nao testei tente adaptar):
Seu exemplo se assemelha com aquele que funciona, que mostrei no início. Ou seja, tem apenas adições de linhas. O que desejo é adicionar linhas e alterar o valor da coluna que mostra o número do registro atual.
Ex.:
Cadastro | Status | Total de Registros | Registro atual
Produtos | Finalizado | 89 | 89 // aqui já finalizou o processo de Produtos. Daí, é adiciona nova linha para Clientes, como segue abaixo:
Clientes | Processando | 1000 | 27 (este 27 é que vai sendo modificado dentro do for{} )
…
luiz_renato
Simples,
Adapta a lógica dentroi do loop pra ao inves de adicionar , executar o setValue .
Nicolas_Fernandes
Eu compartilho da opinião do luiz_renato.
Use um TableModel particular onde você vai trabalhar com o objeto em questão, e não com células. Ao invés de "alterar o valor da coluna", você muda o valor do seu objeto. É OO e mais prático, não? Me baseei no exemplo do luiz_renato:
publicclassTableSwingWorkerextendsSwingWorker<void,void>{privateJTabletable;privateSeuTableModelmodelo;privateTableSwingWorker(JTabletable,SeuTableModelmodelo){setTable(table);setModelo(modelo);}@OverrideprotectedvoiddoInBackground()throwsException{// Supondo que você transformou aquele array de string em uma classe POJO.Rotinarotina=newRotina("Clientes","Processando",modelo.getQuantidadeRegistros(),0);modelo.adicionarRegistro(rotina);for(intI=0;I<modelo.getQuantidadeRegistros();++I){Rotinarotina=newRotina("Clientes","Processando",modelo.getQuantidadeRegistros(),I);modelo.adicionarRegistro(rotina);}}}
Assim, você não fica preocupado com cast, com buscar células na tabela nem nada do tipo.
V
vicentedepaula
luiz_renato,
mas é isto que está emperrando! Veja lá no início quando coloquei o :
esta linha acima não funciona! A aplicação pára e não surge erro algum no console, tampouco há alteração no JTable.
Nicolas Fernandes,
Agradeço sua participação, mas reforço a idéia de que não preciso adicionar linhas na JTable para cada passagem loop do for{}. Se eu fizer do jeito que ambos sugeriram, no JTable ocorrerá isto:
Quando na realidade eu quero apenas: Cadastro | Status | Total de Registros | Registro atual
Produtos | Finalizado | 89 | 89 // aqui já passou pelo processo
Clientes | Processando | 1000 | 27 // este 27 é o 27ª passagem loop do for. Ele é resultado do this.modelo.setValueAt(this.rotina, linhas, 4)
Nicolas_Fernandes
Entendi o que você precisa, vicentedepaula. Mas ainda continuo com a ideia do TableModel específico. Porquê? Porque você cria um evento onde você altera um objeto específico e avisa sua tabela que aquela linha foi alterada.
Vamos pensar…
Você pode ver se aquele objeto tem o status processando. Se ele estiver totalmente processado, você seta o status como Finalizado. Que tal?
Algo como:
// onde linha é o procedimento atual.
Rotina rotina = modelo.getItemAt(linha);
if (rotina.getLinhaProcessada() == rotina.getTotalRegistros()) {
rotina.setStatus(Status.PROCESSADO);
modelo.updateItemAt(rotina, linha); // dentro do update, você chama o fireTableRowsUpdated(row, row), para avisar que mudou o registro na tabela.
}
Entendi o que você precisa ou ainda estou voando longe? rs
V
vicentedepaula
Resolvido!
Como era um caso simples, mantive o uso de DefaultTableModel ao invés do AbstractTableModel.
O erro foi bobo!!! Vejamos:
Se na JTable desejo alterar o valor da 4ª coluna, o parâmetro de número da coluna deve ser 3 no .setValueAt. Havia colocado erroneamente 4.
O mesmo ocorreu para a linha.
Portanto, dentro do for{} coloquei:
Portanto, se congelou sem erro (era ao menos para surgir um array Index out of Bounds mas nem surgiu no console), dê uma olhada nas referências de linha e coluna passadas no setValuAt do modelo usado.
De qualquer forma, obrigado Nicolas Fernandes e luiz_renato pela atenção !!!
Nicolas_Fernandes
Que bom que deu certo.
Mas amigão, é o seguinte: eu penso que não existe caso simples e caso complexo para usar um modelo correto e bacana, sabe? Eu ainda acho que você deveria tentar adaptar o seu código para um AbstractTableModel, porque assim você faria o uso de objetos ao invés de linha/coluna. Fica mais “orientado”, saca?
Mas que bom que resolveu, era bobo mesmo. Às vezes a gente procura o complexo e acaba não percebendo o simples rs.
V
vicentedepaula
Nicolas,
O setValueAt do DefaultTableModel tem a mesma parametrização do setValueAt do AbstractTableModel. Ambos no primeiro parâmetro tratam de um objeto a ser enviado para a linha e coluna passados nos parâmetros seguintes.
Uso o AbstractTableModel em outras situações mais complexas. Mas nesta, onde a tabela não possui nenhuma coluna editável, apenas com caráter informativo, não vejo probs