De qualquer forma, mesmo para sua query atual, você precisaria passar o novo nome do tipo e o antigo.
O seu método alterar só está recebendo um deles.
É. Bem, parece meio besta, mas não daria certo se eu criasse um novo getter getNovoTipo e um setter setNovoTipo na minha classe Tipo, no model?
Ai eu poderia pegar o que já estava com o getNome e passar pelo setNovoTipo.
Edit:
Eu fiz o método para excluir e ele está excluindo, o problema é que está excluindo uma linha antes do que o usuário pede, por exemplo, se eu selecionar a linha 3 e mandar excluir-la, a linha excluída vai ser a linha 2.
E qual é o problema de simplesmente duplicar os dados no JDialog?
Ou de carregar seu tipo novamente do banco?
Bem, não há problema, eu acho, mas na honestidade, nem tenho ideia de como fazer.
Eu estou forçadamente aprendendo a lidar com Swing. Ando lendo e fuçando na API e nos fóruns mesmo, porque meu conhecimento é beeeem básico, então eu vou me baseando no que eu vejo pra ir montando a minha aplicação, mas pode deixar que vou dar mais uma olhada sobre carregar os dados.
Se esse é o seu caso, está indo muito bem. Os códigos que você mostrou até agora estão no caminho certo.
Pois é, vou indo assim. Vou tentar fazer agora, passei o dia todo mexendo com RMI pra ter um tempinho pra mexer com esse aqui agora.
Mas em relação a exclusão, alguma ideia do por que será que está excluindo errado?
Bem, tenho que carregar pelo construtor, certo?
Então fica ago como:
public CadastroTipoDialog(Tipo get) throws ParseException, SQLException {
TipoController tc = new TipoController();
tc.alterar(get.getCodigo(), get.getNome());
}
E dai eu tenho que fazer isso de novo no getTipo?
protected Tipo getTipo() throws ParseException {
TipoController tc = new TipoController();
try {
tc.alterar(Integer.parseInt(jTextFieldCodigoTipo.getText()), jTextFieldNomeTipo.getText());
JOptionPane.showMessageDialog(this, "Tipo alterado com sucesso!");
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "Nao foi possivel alterar tipo!\n" + e.getLocalizedMessage());
} return getTipo();
Bem, é meio obvio que não, porque não está funcionando, mas foi onde eu consegui chegar.
Na verdade, no construtor vc só faz a cópia do objeto para atributos do JDialog:
private boolean confirmado = false;
public CadastroTipoDialog(Tipo tipo) throws ParseException, SQLException {
nome = tipo.getNome();
//Continue aqui para todos os atributos que o JDialog for mexer.
}
Crie também um método para saber se o usuário pressionou ok ou não:
//Na ação de ok do seu JDialog, defina ok para true.
public boolean isConfirmado() {
return confirmado;
}
E crie métodos para a leitura do que foi modificado no seu JDialog:
public String getNome() {
return nome;
}
Na outra janela, vc poderá usar o seu Dialog assim:
[code]public void btnAlterarClick() {
TipoTableModel model = (TipoTableModel)suaTable.getModel();
int index = suaTable.getSelectedIndex();
if (index == -1) //Não selecionou nada?
return;
Tipo tipo = model.get(index);
CadastroTipoDialog ctd = new CadastroTipoDialog(tipo);
ctd.setVisible(true);
if (!ctd.isConfirmado()) //Usuário não pressionou ok?
return;
//Caso seja ok, chama o controller para alterar o tipo
TipoController tc = new TipoController();
tc.alterar(tipo.getCodigo(), ctd.getNome());
}[/code]
Eu sempre considero uma boa prática de programação fazer com que o JDialog não altere nada. Ele simplesmente permite que vc configure alguma coisa, e retorna o que foi configurado, mas nunca chama controllers ou métodos que efetivamente salvam objetos no banco. Isso garante que o JDialog possa ser reaproveitado em outros contextos do sistema, sem falar, que garante também que um problema de banco jamais estará num JDialog.
Claro, as vezes uma ou outra dialog mais complexa irá ferir essa regra, mas é sempre bom ter um guia de boas práticas entre os membros de sua equipe. 
Ok… Só uma coisa ficou meio confusa pra mim…
No exemplo do inicio, você me falou para incluir a linha:
model.set(index, ctd.getTipo()); //getTipo deve retornar o tipo alterado
Isso atualiza minha tabela, correto?
Já estou me sentindo meio idiota, mas acho que confundiu um pouco as coisas na minha cabeça.
Vamos ver:
No controller faço o seguinte:
[code]
public void alterar(int codigotipo,
String nometipo) throws ParseException, SQLException {
Tipo tipo = new Tipo();
tipo.setCodigo(codigotipo);
tipo.setNome(nometipo);
new TipoDao().alterar(tipo);
}[/code]
No DAO Tenho o seguinte:
public void alterar(Tipo tipo) throws SQLException {
String update = "UPDATE tipomedicamento " +
"SET nometipo = ?" +
"WHERE codigotipo = ?";
update(update, tipo.getCodigo(), tipo.getNome());
}
Vou ter mesmo que alterar o código do tipo aqui nessa query ou posso deixa-la assim?
No CadastroTipoDialog tenho:
[code]
private String nome;
private int codigo;
public CadastroTipoDialog() {
initComponents();
jButtonSalvar = null;
}
private boolean confirmado = false;
public CadastroTipoDialog(Tipo tipo) throws ParseException, SQLException {
nome = tipo.getNome();
codigo = tipo.getCodigo();
}
public boolean isOK() {
if (jButtonSalvar == null) {
jButtonSalvar = new JButton();
jButtonSalvar.setText("Salvar");
jButtonSalvar.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
confirmado = true; //Dizemos que o ok foi selecionado.
setVisible(false);
}
});
}
return confirmado;
}
public boolean isConfirmado() {
return confirmado;
}
public String getNome() {
return nome;
}
public int getCodigo() {
return codigo;
}[/code]
No ControleTipo Tenho:
[code]
public void btnAlterarClick() throws ParseException, SQLException {
TipoTableModel model = (TipoTableModel) tableTipo.getModel();
int index = tableTipo.getSelectedRow();
if (index == -1) //Não selecionou nada?
{
return;
}
Tipo tipo = model.get(index);
CadastroTipoDialog ctd = new CadastroTipoDialog(tipo);
ctd.setVisible(true);
if (!ctd.isConfirmado()) //Usuário não pressionou ok?
{
return;
}
//Caso seja ok, chama o controller para alterar o tipo
TipoController tc = new TipoController();
tc.alterar(tipo.getCodigo(), ctd.getNome());
}[/code]
Nessa linha aqui, eu coloquei:
Mas no exemplo você havia posto:
Esse getSelectedIndex() é uma método que eu tenho que criar?
O frustrante é que parece que estou tão perto de conseguir fazer o que preciso, mas não consigo fazer algo que está na minha cara!
Não, o getSelectedIndex() tava errado mesmo. O nome correto do método é getSelectedRow().
Desculpe, esses probleminhas acontecem com frequencia. Você deve lembrar que eu estou dando as dicas, mas não estou na frente do seu compilador, nem com o código montado. Aí não tenho aqui o code completion. =/
Os parâmetros da sua query de alterar estão invertidos (ou parecem, não sei exatamente o comportamento do método update):
public void alterar(Tipo tipo) throws SQLException {
String update = "UPDATE tipomedicamento " +
"SET nometipo = ?" +
"WHERE codigotipo = ?";
update(update, tipo.getNome(), tipo.getCodigo());
}
Note que aqui vc não está alterando o código. Ele é só um parametro do WHERE que indica qual dos tipos deve ser alterado.
O resto parece certo. Exceto pelo fato de eu ter esquecido um detalhe. Adicione na última linha do btnAlterarClick:
Isso avisa o Table que seu dado mudou, para que ela faça o redesenho.
E sim, você está muito perto de ver tudo funcionando. Não se frustre, são mesmo muitas peças nesse quebra-cabeças. Mas se vc apresentasse um código assim para mim numa entrevista de emprego, eu te contrataria.
Rapaz, nem tenho como te agradecer por toda paciência teve comigo e toda ajuda que você já meu deu aqui!
Acabei de tentar de duas maneiras: deixando o mesmo código e colocando um novo código, como fiz nos meus métodos para salvar.
Setando o código diretamente:
public void alterar(Tipo tipo) throws SQLException {
String update = "UPDATE tipomedicamento "
+ "SET codigotipo = NEXTVAL('seq_tipomedicamento'), nometipo=? "
+ "WHERE codigotipo = ?;";
update(update, tipo.getCodigo(), tipo.getNome());
}
[code]public void alterar(/**int codigotipo,*/
String nometipo) throws ParseException, SQLException {
Tipo tipo = new Tipo();
//tipo.setCodigo(codigotipo);
tipo.setNome(nometipo);
new TipoDao().alterar(tipo);
}[/code]
TipoController tc = new TipoController();
tc.alterar(/**tipo.getCodigo(),*/ ctd.getNome());
model.fireTableRowsUpdated(index, index);
E deixando o código:
public void alterar(Tipo tipo) throws SQLException {
String update = "UPDATE tipomedicamento "
+ "SET codigotipo = ?, nometipo=? "
+ "WHERE codigotipo = ?;";
update(update, tipo.getCodigo(), tipo.getNome());
}
public void alterar(int codigotipo,
String nometipo) throws ParseException, SQLException {
Tipo tipo = new Tipo();
tipo.setCodigo(codigotipo);
tipo.setNome(nometipo);
new TipoDao().alterar(tipo);
}
TipoController tc = new TipoController();
tc.alterar(tipo.getCodigo(), ctd.getNome());
model.fireTableRowsUpdated(index, index);
Mas nem assim aparece alguma coisa no JDialog, nem os campos sem nada… Ai fico sem ideia!
Mas, peraí. Seu JDialog está aparecendo vazio? Qual problema exatamente vc está tendo?
No construtor do seu JDialog vc está fazendo o setText para preencher o seu dialog?
O seu método alterar estava certo antes, como postei ali.
O erro certamente não é lá.
Tinha esquecido de chamar o initCompoments();… Falta de atenção ao quadrado!
Na realidade, já estava certo ontem, mas por uma falta ainda maior de atenção minha eu estava chamando o JDialog pra salvar e não alterar! Nunca ia editar mesmo!
Agora, pra excluir, eu vou ter que fazer quase a mesma coisa né? Só que não vou abrir um JDialog. Eu havia feito assim:
[code]
private void onClickExcluir() {
TipoController tc = new TipoController();
int index = tableTipo.getSelectedRow();
if (index == -1) {
return;
}
TipoTableModel model = (TipoTableModel) tableTipo.getModel();
Tipo tipo = model.get(index);
model.fireTableRowsDeleted(index, index);
try {
tc.excluir(index);
JOptionPane.showMessageDialog(this, "Tipo excluido com sucesso!");
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "Nao foi possivel excluir o tipo!\n" + e.getLocalizedMessage());
}
}[/code]
public void excluir(int codigoTipo) throws SQLException {
String delete = "DELETE FROM tipomedicamento WHERE codigotipo = ?";
delete(delete, codigoTipo);
}
public void excluir(int codigoTipo) throws SQLException {
new TipoDao().excluir(codigoTipo);
}
Mas seria melhor se eu fizesse assim, não?
[code]
public ControleTipo(Tipo tipo) {
initComponents();
tableTipo.setModel(new TipoTableModel(new TipoController().listaTipos()));
btnEditar = null;
codigo = tipo.getCodigo();
}
public int getCodigo() {
return codigo;
}
private void onClickExcluir() {
TipoController tc = new TipoController();
int index = tableTipo.getSelectedRow();
if (index == -1) {
return;
}
TipoTableModel model = (TipoTableModel) tableTipo.getModel();
model.fireTableRowsDeleted(index, index);
try {
tc.excluir(codigo);
JOptionPane.showMessageDialog(this, "Tipo excluido com sucesso!");
} catch (SQLException e) {
JOptionPane.showMessageDialog(this, "Nao foi possivel excluir o tipo!\n" + e.getLocalizedMessage());
}
}[/code]
Achei mais coerente, mas não funciona!
Eu tenho uma filosofia que já me salvou muitas vezes. Quando o código está “certo demais” e não está funcionando, tente procurar o erro em outro lugar. Claro, quando vc é iniciante o código tende a parecer certo demais muito rápido, mas com o tempo, isso vira um truque valioso.
No caso, você deve efetivamente excluir o dado do seu tablemodel. Os métodos “fire” só servem para avisar a tabela que você já fez isso, mas não para realizar a ação em si.
Você precisará incluir um método no seu model para fazer a exclusão do tipo da lista que tem lá dentro:
public Tipo remove(int row) {
return valores.remove(row);
fireTableRowsDeleted(row, row);
}
O resto parece certo. Verifique se o dado já não era excluído do banco, mas só a tela ainda estava mostrando ele lá.
Vini, muito obrigado! Consegui fazer tudo certinho, tive que mudar umas coisinhas, mas tá tudo funcionando certo!
Ainda tenho mais 5 cadastros bem mais difíceis que esse pra implementar, mas agora já tenho ideia de como fazer…
Sério mesmo, se não fosse você, já tinha mandando essa bagaça se explodir! Obrigado pelo tempo dedicado e pelas dicas que você me deu!
Opa… de nada. É como eu sempre digo. Se for para não usar o (eca) DefaultTableModel, minha paciência é de jó…