Dados atualizados estão indo para ultima posição da JTable, [RESOLVIDO] VLW

22 respostas
A
Boa tarde galera, sempre quando atualizo os dados, eles vão para a ultima posição da JTable, e estou utilizando TableModel que eu mesmo criei... por que??? Vo postar meus códigos fontes referentes a alteração..Vlw MÉTODO ALTERAR DO DAO - (VAI NO BANCO DE DADOS)
public void altera(Contato contato) throws SQLException{

		Connection conn = Conexao.getConexao();
		String sql = " Update usuario set nome = ? ,idade = ? ,telefone = ? where idusuario = ? ";
		PreparedStatement stmt = conn.prepareStatement(sql);

		// Setar os valores no statemant
		stmt.setString(1, contato.getNome());
		stmt.setString(2, contato.getIdade());
		stmt.setString(3, contato.getTelefone());
		stmt.setInt(4,contato.getIdusuario());

		// Executa o código SQL com os valores setados
		stmt.execute();
		stmt.close();
    }
MÉTODO ALTERAR DAS REGRAS DE NEGÓCIO
public void alterarContato(int idusuario,String nome,String idade,String telefone) throws SQLException{

		Contato cont = new Contato(nome,idade,telefone);
		cont.setIdusuario(idusuario);
		contatoDAO cDAO = new contatoDAO();
		cDAO.altera(cont);
	}
EVENTO DO MOUSE
private void tabelaMouseClicked(java.awt.event.MouseEvent evt) {                                    
       int linha = tabela.getSelectedRow();
       tf_nome.setText(tabela.getValueAt(linha, 0).toString());
       tf_idade.setText(tabela.getValueAt(linha, 1).toString());
       tf_telefone.setText(tabela.getValueAt(linha, 2).toString());
    }
BOTAO ALTERAR
private void bt_alterarActionPerformed(java.awt.event.ActionEvent evt) {

        if(evt.getSource() == bt_alterar){
            ContatoNegocio cont = new ContatoNegocio();
            int row = tabela.getSelectedRow();

                ContatoTableModel modelo = (ContatoTableModel)tabela.getModel();
                Contato contato = modelo.get(row);//Campo está criado dentro do Table model "
                 //private List<Contato> Contato;

            try {
                cont.alterarContato(contato.getIdusuario(), tf_nome.getText(), tf_idade.getText(), tf_telefone.getText());
                JOptionPane.showMessageDialog(null,"Alterado com Sucesso!!");
            } catch (SQLException ex) {
                Logger.getLogger(ContatoFrame.class.getName()).log(Level.SEVERE, null, ex);
            }


             
        }
    }
OBS:(OS DADOS ESTÃO SENDO ALTERADOS PERFEITAMENTE NO BANCO DE DADOS, O PROBLEMA É QUE ESTÃO INDO PRA ULTIMA POSIçÃO DO JTABLE).

22 Respostas

ViniGodoy

Por que você está criando um novo contato, se você só quer altera-lo?

A

Em que lugar estou criando um novo contato???
Obs(Os dados estão sendo alterados perfeitamente alterados no banco de dados, mas eles Aparecem na JTable na ultima posição, e só depois que fecho e abro a aplicação de novo!!
na verdade são 2 probelmas :cry: )

malucocelo

Tua consulta tá ordenada? Imagino que seja isso.

ViniGodoy

Dentro do método alterar contato, olha o new lá.

A

Não Viny, dentro de método alterar contato nao estou criando ele de novo não, eu estanciei a classe contato dentro do método alterar contato para passa-lá como parametro para a classe contatoDAO, repare be dentro da clase contatoDAO que vc ai ver os parametros da classe Contato serem utiliados lá, dentro da classe contatoDAO, estão sendo utilizados os atributos que foram passados como parametros da classe contato, eu ainda seto ambos no statement… infelizmente eu acho que nao é esse o problema nao… :cry:

ViniGodoy

O primeiro passo é alterar o método alterarContato para trabalhar com o contato dentro do JTable:

public void alterarContato(Contato cont,String nome,String idade,String telefone) throws SQLException{  
   cont.setNome(nome);
   cont.setIdade(idade);
   cont.setTelefone(telefone);
   new contatoDAO().altera(cont);  
}

Note que tirei fora a necessidade de passar o parâmetro id, já que ele já está dentro do objeto contato e geralmente ele nunca é alterado.

Ok, agora altere o seu evento de botão para usar esse método, e avisar a tabela que a linha daquele contato mudou:
private void bt_alterarActionPerformed(java.awt.event.ActionEvent evt) {  
   int row = tabela.getSelectedRow();  

   ContatoTableModel modelo = (ContatoTableModel)tabela.getModel();  
   Contato contato = modelo.get(row);//Obtém o contato de dentro do modelo
   
   try {  
      //Altera o contato da linha selecionada.
      new ContatoNegocio().alterarContato(contato, tf_nome.getText(), tf_idade.getText(), tf_telefone.getText());  
      modelo.fireTableRowsUpdated(row, row); //Avisa que os dados da linha mudaram, para serem repintados
      JOptionPane.showMessageDialog(null,"Alterado com Sucesso!!");  
   } catch (SQLException ex) {  
      Logger.getLogger(ContatoFrame.class.getName()).log(Level.SEVERE, null, ex);  
   }  
}
Outra coisa. Seu evento de mouseClick tem um sério problema. Se você alterar a ordem dos campos da tabela, ele para de funcionar. Por isso, é melhor sempre se basear na sua classe de negócio:
private void tabelaMouseClicked(java.awt.event.MouseEvent evt) {                                      
   ContatoTableModel modelo = (ContatoTableModel)tabela.getModel();  
   Contato contato = modelo.get(row);//Obtém o contato da linha selecionada
   tf_nome.setText(contato.getNome());  
   tf_idade.setText(Integer.toString(contato.getIdade()));  
   tf_telefone.setText(contato.getTelefone());  
}
Assim as colunas podem alterar de ordem livremente, sem que você tenha que alterar essa função. Ainda volto a insistir para que você crie uma função:
public ContatoTableModel getModel() {
   return (ContatoTableModel)tabela.getModel();  
}
Isso evita a criação dessa variável:
ContatoTableModel modelo = (ContatoTableModel)tabela.getModel();

Já que você pode simplesmente chamar getModel() no lugar dela. E com a vantagem de que se o nome da classe ou da tabela mudarem, você só precisará alterar isso em 1 único ponto do seu código.

A

[quote=ViniGodoy]O primeiro passo é alterar o método alterarContato para trabalhar com o contato dentro do JTable:

public void alterarContato(Contato cont,String nome,String idade,String telefone) throws SQLException{  
   cont.setNome(nome);
   cont.setIdade(idade);
   cont.setTelefone(telefone);
   new contatoDAO().altera(cont);  
}

Note que tirei fora a necessidade de passar o parâmetro id, já que ele já está dentro do objeto contato e geralmente ele nunca é alterado.

Ok, agora altere o seu evento de botão para usar esse método, e avisar a tabela que a linha daquele contato mudou:
private void bt_alterarActionPerformed(java.awt.event.ActionEvent evt) {  
   int row = tabela.getSelectedRow();  

   ContatoTableModel modelo = (ContatoTableModel)tabela.getModel();  
   Contato contato = modelo.get(row);//Obtém o contato de dentro do modelo
   
   try {  
      //Altera o contato da linha selecionada.
      new ContatoNegocio().alterarContato(contato, tf_nome.getText(), tf_idade.getText(), tf_telefone.getText());  
      modelo.fireTableRowsUpdated(row, row); //Avisa que os dados da linha mudaram, para serem repintados
      JOptionPane.showMessageDialog(null,"Alterado com Sucesso!!");  
   } catch (SQLException ex) {  
      Logger.getLogger(ContatoFrame.class.getName()).log(Level.SEVERE, null, ex);  
   }  
}

Ai Viny, fiz isso ai que vc mandou, e os dados nao estão sendo alterados...por que?????

ViniGodoy

Posta de novo seus métodos pra ver se não faltou nada.

A
ta ai..
public void altera(Contato contato) throws SQLException{

		Connection conn = Conexao.getConexao();
		String sql = " Update usuario set nome = ? ,idade = ? ,telefone = ? where idusuario = ? ";
		PreparedStatement stmt = conn.prepareStatement(sql);

		// Setar os valores no statemant
		stmt.setString(1, contato.getNome());
		stmt.setString(2, contato.getIdade());
		stmt.setString(3, contato.getTelefone());
		stmt.setInt(4,contato.getIdusuario());

		// Executa o código SQL com os valores setados
		stmt.execute();
		stmt.close() }
public void alterarContato(Contato cont,String nome,String idade,String telefone) throws SQLException{

	         cont = new Contato(nome,idade,telefone);
		
		contatoDAO cDAO = new contatoDAO();
		cDAO.altera(cont);
	}
private void bt_alterarActionPerformed(java.awt.event.ActionEvent evt) {                                           

        if(evt.getSource() == bt_alterar){
            ContatoNegocio cont = new ContatoNegocio();
            int row = tabela.getSelectedRow();

                ContatoTableModel modelo = (ContatoTableModel)tabela.getModel();
                Contato contato = modelo.get(row);//Campo está criado dentro do Table model "
                 //private List<Contato> Contato;

            try {
                cont.alterarContato(contato, tf_nome.getText(), tf_idade.getText(), tf_telefone.getText());
                modelo.fireTableRowsUpdated(row, row);
                JOptionPane.showMessageDialog(null,"Alterado com Sucesso@@");
            } catch (SQLException ex) {
                Logger.getLogger(ContatoFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
             
        }
    }
ViniGodoy

Seu método alterarContato continua criando um contato novo, e não tem absolutamente nada a ver com o que eu escrevi. Repetindo, você precisa alterar o contato que está dentro do JTable, não criar uma cópia dele fora do JTable.

Só assim os dados de dentro do model serão atualizados e dizer que as linhas foram alteradas fará algum sentido.

A

Viny, mas aquilo é um simles método contrutor, sempre que o ativo, ele lança os valores para as suas respectivas variáveis…vou tenar aqui, caso nao der certo posto novamente…vlw

ViniGodoy

Ah, só uma explicação.

Quando você faz:

public void metodo(Tipo x) {
   x = new Tipo();
}

Tipo a = new Tipo();
metodo(a);
Você está apenas alterando o valor da referência x. Mas isso não altera o valor da referência fora (o valor de a). O que acontece é que a e x passam a apontar para objetos diferentes. É o mesmo caso seu, ao fazer
contato = new Contato(...);

Você está alterando a referência da variável local contato do método alteraContato, para um novo contato, recém criado. O contato que está dentro do model, continua completamente inalterado.

Por isso, é importante receber a referência e dar set nos campos dela. Como as duas apontarão para o mesmo local, o set será dado no contato recebido como parâmetro.

A

Viny, ele foi alterado perfeitamente, inclusive ele foi alterado em tempo de execução, mas ocorreu um problema, ele continua indo pra ultima posição,mas ele vai pra ultima posição sempre que fecho e abro a aplicação novamente :cry:

ViniGodoy

E que critério você está usando para ordenar os registros no listar() do seu DAO?

A

Não entendi…??? o que tem haver o listar com o alterar, eu nao estouusando o método listar no alterar do DAo nem no da regra de negocio.estranho

A

Vo postar o método que to utilizando para listar os dados dentro da Frame, o meu método de listar() do DAO.

MÉTODO QUE LISTA DENTRO DA FRAME
rivate void preencheTabela() throws SQLException{

        ContatoNegocio cont = new ContatoNegocio();
        List<Contato> lista = cont.listarContato();

        ContatoTableModel modelo = new ContatoTableModel(lista);
        tabela.setModel(modelo);
    }
MÉTODO DE LISTAR DO DAO
public List<Contato> listar() throws SQLException{

        Connection conn = Conexao.getConexao();

		String sql = "Select * from usuario";
		PreparedStatement stmt = conn.prepareStatement(sql);

		// Esse método é utilizado para apontar para os dados do BD
		ResultSet rs = stmt.executeQuery();

		//Cria uma lsita para armazenar os valores que serão buscados
		 List<Contato> minhaLista = new ArrayList<Contato>();

		while(rs.next()){
			// Essa Rotína pega os dados do banco e armazena nesse objeto do tipo contato
			Contato contato = new Contato(rs.getInt("idusuario"));
                        contato.setNome(rs.getString("nome"));
                        contato.setIdade(rs.getString("idade"));
                        contato.setTelefone(rs.getString("telefone"));
			//Essa rotína adiciona os dados de contato no objeto minhaLista
			minhaLista.add(contato);

		 }
		 rs.close();
		 stmt.close();
		 return minhaLista;
      }
ViniGodoy

No seu listar, vc está deixando a ordem que os objetos vem do banco a cargo do banco:

Por isso, cada vez que você carrega a lista, ela virá na ordem que o BD achar mais adequada. O ideal é você usar um order by, tipicamente, por nome:

Isso garante que vc carregue tudo numa ordem consistente, sempre que o programa é iniciado. :slight_smile:

malucocelo

Justamente o que eu havia sugerido lá em cima.

A

Certo… tudo bem…mas ta acontecendo o seguinte, caso eu altere um nome de alguma pessoa, e esse nome após ser alterado for conter como primeira letra a letra “A”, ele vai para a primeira posição,certo??? é normal de Acontecer isso?? ou campo mesmo contendo a letra “A” como inicial apó ser alterado tem que continuar na sua respectiva posição??? Caso eu coloque o comando “select*from usuario order by idusuario”, caso durante alguma alteração, for inserido algum nome com a letra “A” ela irá continuar na mesma posição… o que vcs acham dessa solução??? ou a outra é melhor???
Vlws galerinha :-o

malucocelo

Em um caso com esse, não há implementação melhor, você deve pedir a opnião dos usuários do sistema e se possível deixar a possibilidade de ordenar por mais que um critério, normalmente se ordena pelo nome, mas, pode ser que os usuários prefiram outra coisa.

ViniGodoy

Uma boa seria usar a classe de auto-filtro, da minha assinatura. :slight_smile:

A

Vlw Galerinha muito obrigado de coração…

Criado 12 de março de 2010
Ultima resposta 14 de mar. de 2010
Respostas 22
Participantes 3