Problemas com comunicação entre janelas

6 respostas
Radaelli

Boa noite pessoal...

Sou novo em java e no GUJ, curso atualmente o 7º semestre de Ciência da Computação e estou desenvolvendo um pequeno projeto na universidade, este projeto envolve a criação de um sistema de gerenciamento de fluxo de caixa com banco de dados em postgre, aqueles controles de contas bem simples, bem, o sistema esta na segunda formatação pois a primeira não ficou satisfatória, estou aprendendo java com este projeto, meio que na base do empurrão, necessito e agradeço toda e qualquer ajuda possível.

Bem sem mais enrolação vamos aos meus problemas...

A parte de inclusão, exclusão, alteração no banco de dados Postgre está funcionando perfeitamente, meu sistema está bem dividido em pacotes, Ex: Parte de telas(JFrame's, Codigos SQL, Atributos...), os meus problemas estão relacionados ao tratamento de comandos em janelas diferentes, tentarei mostrar e explicar estes exemplos mais adiante...

Imagem explicativa das telas
[url]http://a.imageshack.us/img52/9444/extelasprimsec.png[/url]

1º Meu sistema possue varias tabelas, em todas eu uso Default Table Model, List Selection Model e List's para preenche-las.
Para ficar mais bonita a visualização do sistema, o cadastro de bancos, compras, vendas, clientes e funcionários são feitas em JFrame's separadas das tabelas onde eles são listados... visualização no link abaixo

[url]http://img689.imageshack.us/img689/3273/telascadastro.png[/url]

Eu necessito fazer com que o sistema atualize a tabela para quando eu cadastrar/alterar os dados que retirei do banco, cliente, fornecedor, compras ou vendas ou o que for... O que eu tentei fazer inicialmente (que utilizei na 1ª versao do sistema onde a tabela e os JTextField estavam no mesmo JFrame e funcionava) foi rechamar o método utilizado para povoar as tabelas inicialmente... Codigo abaixo é o de povoamento da tabela Compras, existente no JFrame JFInicial, funciona perfeitamente quando abro o frame... Ex: figura da janela Bancos vista acima....

[i]Por favor, tratem este trecho de código como se funcionasse perfeitamente, pois realmente funciona perfeitamente, esta aqui apenas para mostrar como é feito o povoamento da tabela[/i]

    DefaultTableModel tmCompras = new DefaultTableModel(null, new String[]{"Data", "Vencimento", "Pagamento", "Modo", "Documento", "Descrição da Despesa", "Conta", "Fornecedor", "Valor", "Situação", "Obs"});
    List<Compras> comprass;

    public void InsereCompras(){
        try {
            ListarCompras();
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, "Problemas para inserir dados na tabela despesas "+ ex);
        }
    }

    public void ListarCompras() throws SQLException {
        ComprasSQL sql = new ComprasSQL();
        comprass = sql.getList("%" + "" + "%");     //Chama do arquivo ComprasSQL a lista de comprass, envia por parametro o Modo de compra(Dinheiro, cheque, cartao...), ou seja, qualquer modo.
        mostraPesquisaCompras(comprass);
        }

    private void mostraPesquisaCompras(List<Compras> comprass) {
        while (tmCompras.getRowCount() > 0) {
            tmCompras.removeRow(0);
        }
        if (comprass.size() == 0) {
            JOptionPane.showMessageDialog(null, "Nenhuma conta para pagar hoje!");
        } else {
            String[] linha = new String[]{null, null, null, null, null, null, null, null, null, null, null};
            for (int i = 0; i < comprass.size(); i++) {
                tmCompras.addRow(linha);
                tmCompras.setValueAt(comprass.get(i).getDataCompra(), i, 0);
                tmCompras.setValueAt(comprass.get(i).getVencimento(), i, 1);
                tmCompras.setValueAt(comprass.get(i).getDataPagamento(), i, 2);
                tmCompras.setValueAt(comprass.get(i).getModo(), i, 3);
                tmCompras.setValueAt(comprass.get(i).getDocumento(), i, 4);
                tmCompras.setValueAt(comprass.get(i).getDescricao(), i, 5);
                tmCompras.setValueAt(comprass.get(i).getIdBanco(), i, 6);
                tmCompras.setValueAt(comprass.get(i).getIdFornecedor(), i, 7);
                tmCompras.setValueAt(comprass.get(i).getValor(), i, 8);
                tmCompras.setValueAt(comprass.get(i).getSituacao(), i, 9);
                tmCompras.setValueAt(comprass.get(i).getObs(), i, 10);
            }
        }
    }
Código usado na janela de cadastro para chamar o método
public void atualizaTabela(){
        JFInicial atualiza = new JFInicial();

        atualiza.InsereCompras();
    }
Só que isto não funcionou, por testes tentei usar o comando dispose() para fechar a janela JFInicial, mas também não tive sucesso, não consigo fazer nada com as janelas anteriores, apenas consigo atualizar uma tabela, ou fechar ela se eu estiver fazendo alguma ação exatamente naquela janela, nem chamando um método que contenha o comando dispose() dentro não tive sucesso...

Bom pessoal, este é o meu problema, se for necessário mais explicações por favor me informe que posto tudo que for necessário, preciso muito resolver estes problemas...

Agradeço muito qualquer ajuda que vocês puderem me dar
Radaelli

6 Respostas

Nicolas_Fernandes

Olá, Radaelli!
Beleza, cara??

Isso é mais simples do que você pensa!
Só que, para se tornar simples, há um componente o qual você precisa esquecer completamente: nosso velho conhecido DefaultTableModel! Com ele, você não tem a opção de definir especificamente cada campo, tipo de valores aceitos, formatações e afins. Além do mais, você não tem a oportunidade de trabalhar diretamente com objetos. Aconselho fortemente o aprendizado do AbstractTableModel. Sua curva de aprendizagem não é tão alta e, se você se dedicar a estudá-lo, em muito pouco tempo você terá entendido e poderá usá-lo nas suas aplicações, tornando sua vida muito mais simples.

Na minha assinatura, segue um link o qual se refere a um tutorial sobre AbstractTableModel, criado pelo ViniGodoy!

Legal… Passada essa parte, vamos à comunicação das telas:

Tenho uma tela com minha tabela, que chamaremos de Manager…

public class ComprasManager extends JFrame {

   private JTable tableCompras;
}

E minha tela para cadastro, que chamaremos de Form.

public class ComprasForm extends JDialog {
   
   private JButton buttonConfirmar, buttonCancelar;
   private JTextBox textValor, textData;
   private JComboBox comboClientes;
   private JLabel label;
}

Beleza… Na nossa tela Form, onde executaremos o cadastro, devemos ter um campo do tipo Boolean para controle e um campo do tipo Map para guardar os dados do formulário. Você entenderá o porquê.

public class ComprasForm extends JDialog {
   
   private JButton buttonConfirmar, buttonCancelar;
   private JTextBox textValor, textData;
   private JComboBox comboClientes;
   private JLabel label;

   private Map<String, Object> dados;
   private Boolean confirmou;
}

Nosso campo confirmou deve representar quando clicarmos no botão “Confirmar” ou “Cancelar”. Caso clique no primeiro, o campo vira true; caso contrário, false.
Devemos ter um método também que retornará os dados do nosso formulário para a tela Parent (pai) e um que avise a situação da nossa variável de controle (confirmou).

public class ComprasForm extends JDialog {
   
   private JButton buttonConfirmar, buttonCancelar;
   private JTextBox textValor, textData;
   private JComboBox comboClientes;
   private JLabel label;

   private Map<String, Object> dados;
   private Boolean confirmou;

   public Map<String, Object> getDados() { return dados; }
   public Boolean isConfirmou() { return confirmou; }
}

Quando instanciarmos os botões, criaremos eventos de ação para eles, certo? São estes eventos que tratarão da nossa variável de controle confirmou.

public class ComprasForm extends JDialog {
   
   // O resto fica omitido pra não ocupar muito espaço!
   public ComprasForm() {
   
      buttonConfirmar = new JButton("Confirmar");
      buttonConfirmar.addActionListener(new Confirmar());
      buttonCancelar = new JButton("Cancelar");
      buttonCancelar.addActionListener(new Cancelar());
   }


   private class Confirmar implements ActionListener {

      public void actionPerformed(ActionEvent e) {
         
         dados.clear();
         dados.put("valor", textValor.getText());
         dados.put("data", textData.getText());
         dados.put("cliente", comboClientes.getSelectedItem());
         
         confirmou = true;
         dispose();
      }
   }

   private class Cancelar implements ActionListener {

      public void actionPerformed(ActionEvent e) {

         confirmou = false;
         dispose();
      }
   }
}

O que aconteceu ali? Caso a pessoa clique em confirmar, eu quero que meus dados sejam inseridos na JTable da tela-pai, certo? Então, eu preencho a minha variável com os dados a serem transmitidos para ela, e aviso que ele clicou em confirmar. Caso o usuário clique em cancelar, ele não “confirmou” a operação, não executando ação de inserção na JTable na outra tela.

Agora, como fazer a mágica acontecer?
No nosso método de ação do botão de “Adicionar Nova Compra”, por exemplo:

ComprasForm cf = new ComprasForm().setVisible(true);
   if ( !cf.isConfirmou() ) return;

   Map<String, Object> dadosRecebidosDoFormulario = cf.getDados();

O que aconteceu? Instanciei um objeto da minha tela de cadastro. Mandei ele ficar visível ao usuário. Enquanto o usuário estiver trabalhando na tela, não acontece nada abaixo, pois o fluxo do método só continua quando a tela de cadastro se fechar. Fechou a tela, beleza. Ele verifica: A variável confirmou é false? Se sim, ele sai do método, pois o usuário clicou em cancelar e não fez nada. E se for true? Daí ele vai pegar os dados que estavam guardados daquele formulário e… Voilà! Pode trabalhar com os dados que estavam no outro formulário à vontade!!

Ficou grande, eu sei, mas quis especificar o máximo possível para aumentar o entendimento!
Espero ter ajudado.
Qualquer dúvida ou melhor esclarecimento, só procurar ou perguntar no fórum que tentaremos ajudar!

Fique com Deus, um abraço!

Radaelli

Boa tarde Nicolas

Bem, vou estudar o AbstractTableMode com calma, testei no meu sistema as suas dicas(do evento do botao) no Default mesmo, mas não tive sucesso, se eu fizer um evento de botão na tela onde está a tabela ele funciona, mas se eu fizer na tela de cadastro ele não funciona, ou melhor, funciona até o ponto onde modifica a tela onde ele está, mas na tela da tabela (ou qualquer outra tela) não tem efeito, os comandos não funcionam

Ricardo Radaelli Meira

Nicolas_Fernandes

O que você diz com “não funcionam”? Não acontece nada na tabela, é isso?

Se sim, não vai acontecer mesmo. Falta você adicionar o seu código para atualizar os dados, ou inserí-los!

Radaelli

Nicolas Fernandes:
O que você diz com “não funcionam”? Não acontece nada na tabela, é isso?

Se sim, não vai acontecer mesmo. Falta você adicionar o seu código para atualizar os dados, ou inserí-los!

Nicolas,

Quando digo que não funcionam, quero me referir que não funciona nada, nenhum comando, não apenas sobre a tabela, mas qualquer coisa sobre aquele JFrame, nem um simples dispose não funciona.

Ricardo Radaelli Meira

Nicolas_Fernandes

Radaelli:

Nicolas,

Quando digo que não funcionam, quero me referir que não funciona nada, nenhum comando, não apenas sobre a tabela, mas qualquer coisa sobre aquele JFrame, nem um simples dispose não funciona.

Ricardo Radaelli Meira

Claro que não funcionará. O que fiz ali foi colocar trechos de códigos soltos, explicando cada pedaçinho, mas sem nenhum ter ligação com o outro, entendeu? Mais tarde eu faço um exemplo completo, e você entenderá certinho.

Radaelli

Nicolas,

Ok aguardo o seu exemplo, mas o detalhe é o seguinte, não falando em tabelas, falando em janelas mesmo, gostaria de fechar a janela secundária (do exemplo do 1º post)
tento o dispose() mas ele nao funciona, a minha duvida é como fazer executar comandos em outros JFrames, ex: na janela 1 quero executar um comando na janela 2

Ex:

JFrame frame2 = new JFrame();
frame2.dispose();

mas ele não funciona, esse é o meu maior problema…

Ricardo Radaelli Meira

Criado 31 de agosto de 2010
Ultima resposta 2 de set. de 2010
Respostas 6
Participantes 2