[RESOLVIDO]atualizar jtable em um jframe a parir de outro jframe

Tenho um jTable que fica em jTabbedPane que por sua vez está dentro de jLayeredPane e por fim em um jFrame “principal”, só a organização da tela principal do meu programa, a partir desse jFrame “principal” eu chamo um outro jFrame “cadastro de contatos” que contém uns campos onde realizo cadastros, o banco funciona bem, escreve e apaga normal. Para carregar os dados do banco no jTable uso uma função chamada fillTableContact(), quando chamo essa função no jFrame “principal” funciona bem, mas quando chamo do jFrame “cadastro de contatos” ela executa normal mas não atualiza o jTable do jFrame “principal”. vejam o código abaixo:

jFrame “principal”:

[code]package agenda;

import classes.bridge2db;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;

/**
*

  • @author Diego
    */
    public class mainWindows extends javax.swing.JFrame {

    private int tabIndex;
    bridge2db conInit2;

    /** Creates new form mainWindows */
    public mainWindows() {
    initComponents();

     conInit2 = new bridge2db();
    
     //FAZ O PROGRAMA ABRIR NO MEIO DA TELA
     setLocationRelativeTo(null);
    
     //ESCONDE O CALEDÁRIO, AGENGA E LEMBRETES NA INICIALIZAÇÃO
     jCalendar1.setVisible(false);//CALENDÁRIO
     jTabbedPane1.setVisible(false);//AGENDA
    
     //DEFINE O TEMA PADRÃO DA INTERFACE (ATUAL NIMBUS)
     try {
         UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
         SwingUtilities.updateComponentTreeUI(this);
     } catch (Exception erronotema) {
         JOptionPane.showMessageDialog(rootPane, erronotema);
     }
    

    }
    private void jLabel3MouseClicked(java.awt.event.MouseEvent evt) {
    jLabel2.setVisible(false);
    jTabbedPane1.setVisible(false);
    jCalendar1.setVisible(true);
    }

    private void jLabel5MouseClicked(java.awt.event.MouseEvent evt) {
    jLabel2.setVisible(false);
    jTabbedPane1.setVisible(true);
    jCalendar1.setVisible(false);
    }

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
    jPopupMenu2.show(jButton3, 0, -62);
    }

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
    jPopupMenu1.show(jButton2, 0, -62);
    }

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {
    adContato frameContato = new adContato();
    frameContato.setVisible(true);
    }

    private void jTabbedPane1MouseClicked(java.awt.event.MouseEvent evt) {
    tabIndex = jTabbedPane1.getSelectedIndex();
    if (tabIndex == 1) {
    fillTableContact();
    }
    }

    private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {
    conInit2.conecta();
    try {
    conInit2.statement.executeUpdate(“DELETE FROM contatos WHERE nome=’” + jTable1.getValueAt(jTable1.getSelectedRow(), 0) + “’”);
    JOptionPane.showMessageDialog(rootPane, “Contato excluído!”);
    } catch (SQLException ex) {
    JOptionPane.showMessageDialog(rootPane, “Não foi possível excluir. Tente novamente.”);
    }
    conInit2.desconecta();
    fillTableContact();
    }

    public void fillTableContact() {
    //JOptionPane.showMessageDialog(rootPane, “cliquei na aba contatos”);
    conInit2.conecta();
    conInit2.executeSQL(“SELECT * FROM contatos ORDER BY id”);
    DefaultTableModel modelo = (DefaultTableModel) jTable1.getModel();
    modelo.setNumRows(0);
    try {
    while (conInit2.resultset.next()) {
    modelo.addRow(new Object[]{conInit2.resultset.getString(“nome”), conInit2.resultset.getString(“telresidencial”), conInit2.resultset.getString(“telmovel”), conInit2.resultset.getString(“email”)});
    }
    conInit2.resultset.first();
    } catch (SQLException erroTabela) {
    JOptionPane.showMessageDialog(rootPane, “Erro ao preencher tabela: \n” + erroTabela);
    }
    conInit2.desconecta();
    }[/code]

jFrame “cadastro de contatos”:

[code]package agenda;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import java.sql.SQLException;
import classes.bridge2db;

/**
*

  • @author Diego
    */
    public class adContato extends javax.swing.JFrame {

    bridge2db conInit;
    mainWindows classImport;

    /** Creates new form adContato */
    public adContato() {
    initComponents();

     //ESTABLECE CONEXÃO COM BD
     conInit = new bridge2db();
    
     classImport = new mainWindows();
    
     //FAZ O PROGRAMA ABRIR NO MEIO DA TELA
     setLocationRelativeTo(null);
    
     //DEFINE O TEMA PADRÃO DA INTERFACE (ATUAL NIMBUS)
     try {
         UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
         SwingUtilities.updateComponentTreeUI(this);
     } catch (Exception erronotema) {
         JOptionPane.showMessageDialog(rootPane, erronotema);
     }
    

    }
    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
    jFormattedTextField1.setText("");
    jFormattedTextField2.setText("");
    jFormattedTextField3.setText("");
    jFormattedTextField4.setText("");
    jTextField1.setText("");
    jTextField2.setText("");
    jTextField3.setText("");
    jTextField4.setText("");
    jTextField9.setText("");
    jTextField10.setText("");
    jComboBox1.setSelectedIndex(0);
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    try {
    conInit.conecta();
    conInit.statement.executeUpdate(“INSERT INTO contatos (nome, endereco, bairro, cidade, uf, cep, telresidencial, telcomercial, telmovel, email, site) VALUES (’” + jTextField1.getText() + “’, '” + jTextField2.getText() + “’, '” + jTextField3.getText() + “’, '” + jTextField4.getText() + “’, '” + jComboBox1.getSelectedItem() + “’, '” + jFormattedTextField1.getText() + “’, '” + jFormattedTextField2.getText() + “’, '” + jFormattedTextField3.getText() + “’, '” + jFormattedTextField4.getText() + “’, '” + jTextField9.getText() + “’, '” + jTextField10.getText() + “’)”);
    JOptionPane.showMessageDialog(rootPane, “Contato cadastrado com sucesso!”);
    jFormattedTextField1.setText("");
    jFormattedTextField2.setText("");
    jFormattedTextField3.setText("");
    jFormattedTextField4.setText("");
    jTextField1.setText("");
    jTextField2.setText("");
    jTextField3.setText("");
    jTextField4.setText("");
    jTextField9.setText("");
    jTextField10.setText("");
    jComboBox1.setSelectedIndex(0);
    } catch (SQLException erroInsert) {
    JOptionPane.showMessageDialog(rootPane, "Erro ao gravar dados.\nDetalhes: " + erroInsert);
    }
    conInit.desconecta();
    classImport.fillTableContact();
    } [/code]

essas são as partes que mais nos interessam.

O que tá errado? Por que meu jTable não atualiza a partir de outro jFrame no qual ele não está contido.

da uma olhada em design patterns
em especial no listener
implemente um listener
então você dispara um evento quando atualiza determinado dado
e todos os ouvintes como por exemplo dua jtable são atualizados

cara eu fiz um negócio que quase dava certo, veja o código:

[code]package agenda;

import classes.bridge2db;
import java.awt.event.;
import java.awt.
;
import java.sql.SQLException;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;

/**
*

  • @author Diego
    */
    public class mainWindows extends javax.swing.JFrame {

    //VARIAVEIS
    private int tabIndex;
    bridge2db conInit2;

    /** Creates new form mainWindows */
    public mainWindows() {
    initComponents();

     //TESTE LISTENER
    

    HandlerFocuss.escutar(jPanel3); //ADICIONEI ISSO[/code]

ai adicionei essa classe:

[code]class HandlerFocuss extends FocusAdapter {

mainWindows ImportClass;
   private Container c;

   public HandlerFocuss(Container c) {
      Component[] componente;

      this.c = c;
      componente = c.getComponents();

      for (int i=0;i < componente.length;i++) {
          componente[i].addFocusListener(this);
      }

   }


@Override
   public void focusGained(FocusEvent e){



      if (e.getOppositeComponent() == null) {
         return;
      }

      if (e.getComponent().getParent() != e.getOppositeComponent().getParent()){
        JOptionPane.showMessageDialog(null,"Saiu do JPanel");//ISSO FUNCIONA
         ImportClass.fillTableContact();//ISSO NÃO DA ERRO NA COMPILAÇÃO MAS QUANDO É CHAMADA DÁ ERRO 

      }

   }

   public static void escutar(Container c) {
    new HandlerFocuss(c);
   }
}[/code]

o listener funcionou bem ta mostrando o JOptioPane no momento que eu preciso, só que o ImportClass.fillTableContact() dá pau na execução

nobody?

A sua atualização não ocorre porque você cria uma nova instância da mainWindows e atualiza nela, e não no frame já aberto. No construtor da sua classeadContato, passe a instância da sua mainWindows como parâmetro.

public adContato(JFrame mainWindows) {

    this.classImport = mainWindows; 
}

E assim faça a chamada do seu fillTableContacts().
Faça o teste e nos dê um reply.

OBS.: Algumas dicas:

1 - Pelo visto, você não aprendeu a construir interfaces gráficas “na mão”. Comece a aprender, vale MUITO a pena, ao invés de usar editores gráficos. Eles só são interessantes quando você já sabe como fazer o “caminho das pedras”. Aprenda a construir frames, usar layouts, criar eventos, manipular tabelas, dentre outros;

2 - ABOMINE COM TODAS AS SUAS FORÇAS O DEFAULTTABLEMODEL. Além de dar trabalho e ser complicado para dar manutenção, você não trabalha diretamente com objetos, o que faz você realizar diversas e diversas consultas no Banco de Dados sem necessidade. Crie o seu próprio modelo de tabela para trabalhar com os dados nela [vide link na minha sign].

Primeiramente obrigado pelo seu interesse em ajudar e também pelas dicas. Eu tentei fazer o que você disse mas não deu certo veja na imagem: http://imageshack.us/photo/my-images/834/trechoccodigo.jpg/

Fiz algo errado?

[quote=DiegoAC]Primeiramente obrigado pelo seu interesse em ajudar e também pelas dicas. Eu tentei fazer o que você disse mas não deu certo veja na imagem: http://imageshack.us/photo/my-images/834/trechoccodigo.jpg/

Fiz algo errado?
[/quote]

Ah, sim, foi mal, erro meu. rs
Ou você faz o cast quando receber um JFrame no construtor…

public adContato(JFrame meuFrame) {

    if (meuFrame instanceof mainWindows)
        classImport = (mainWindows) meuFrame;
}

Ou passa uma referência mainWindows diretamente:

public adContato(mainWindows meuFrame) {

    classImport = meuFrame;
}

DICA: Nomes de classes SEMPRE iniciando com letras maiúsculas!

Ainda não deu certo, se altero meu método construtor a aplicação diz que ele não existe mais e pede para mim criar outro, veja na imagem:http://imageshack.us/photo/my-images/823/trechoccodigo.jpg/ Sobre nome das classes em maiúsculo, eu tinha esquecido disso, sem praticar eu to todo enferrujado, e sem nunca me dedicar a uma linguagem só fico viajando as vezes, por isso que agora parei tudo e estou aprendendo java, na faculdade aprendi c#, mas muito superficial os caras dão só o princípio pra você ir melhorando depois, por isso que sofro um em OO. Ah e obrigado, aguado seu reply.

Você chama a adContato ou a mainWindows primeiro?

Se você chama a mainWindows primeiro, como o nome sugere e como pensei, você mantém o construtor da adContato do modo que fizemos.
Se você chama a adContato primeiro, como você tá dizendo que fez, inverta: o construtor da mainWindows recebe uma referência da adContato.

Eu chamo mainWindows primeiro, adContato abre a partir de um menu em mainWindows, então nesse caso se deixo com está a aplicação diz que a classe adContato não tem um construtor, mas eu vou inverter aqui e já te dou uma resposta.

Estamos no mesmo ponto, quando eu pensei em inverter parei por que logicamente não tem sentido fazer se mainWindows abre primeiro, o interessante é que a fillTableContact() executa mas não atualiza a JTable do jeito que eu tinha feito inicialmente, é como se fosse por que mainWindows onde a jTable está não fosse a janela ativa ou estou executando uma função fora do JFrame da minha JTable.

Se este é o cenário, as classes deveriam ser mapeadas assim:

[code]public class mainWindows extends JFrame {

private JButton buttonContatos;

public mainWindows() {

    /* configurações iniciais do formulário */
    buttonContatos = new JButton("Adicionar contatos");
    buttonContatos.addActionListener(new AdicionarContatosListener(this)); //<-- passo este formulário como parâmetro
    getContentPane().add(buttonContatos);
}

public void fillContactsTable() {
    /* seu código aqui */
}

private class AdicionarContatosListener implements ActionListener {

    private mainWindows formularioPrincipal;

    public AdicionarContatosListener(JFrame formularioPrincipal) {
        this.formularioPrincipal = (mainWindows) formularioPrincipal;
    }

    public void actionPerformed(ActionEvent event) {
        new adContato(formularioPrincipal).setVisible(true);
    }
}

}
[/code]
e…

public class adContato extends JFrame {

    private mainWindows formularioPai;

    public adContato(mainWindows formularioPai) {
        this.formularioPai = formularioPai;
    }
    // ou...
    public adContato(JFrame formularioPai) {

        if (formularioPai instanceof mainWindows)
            this.formularioPai = (mainWindows) formularioPai;
    }

     public void metodoQualquer() {
   
         this.formularioPai.fillContactsTable();
     }
}

Tenta assim!

Só uma pergunta: No meu caso eu abro o JFrame adConato através de um jPopupMenu e não de um jButton esse listener funciona também no JPopupMenu?

Parabéns! Funcionou! Consegui antes que você respondesse minha ultima pergunta jogar o addActionListener no jPopupMenu, o netbeans ainda reclama que não consegue achar um método construtor na classe adContato mas eu resolvi executar mesmo assim e deu certo.

Ah olha só essa parte que tive que modificar como sugestão do net beans e pra jogar no meu JPopUpMenu
era assim:buttonContatos.addActionListener(new AdicionarContatosListener(this)); //<-- passo este formulário como parâmetro
ficou asim:jMenuItem1.addActionListener((ActionListener) new AdicionarContatosListener(this));
Aquele (ActionListener) antes do new que o net beans adicionou é um cast?

Agora só algumas perguntas:

por que o netbeans esta reclamando que não acha um método construtor? veja o código:

[code] public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {

        public void run() {
            new adContato().setVisible(true); //aqui ele diz: cannot find symbol
        }                                     //symbol: constructor adConato() 
    });                                       //location: agenda.adConato
}[/code]

nesse ponto mostra uma luzinha amarela com uma plaquinha vermelha, isso pode causar problemas?

tem como distrinchar o último código que você postou pra mim, só explicar o funcionamento, par ver se bate com o que compreendi?

Mais uma vez muito obrigado, isto auxilia e muito pra mim ir desenvolvendo meu conhecimento em java.

Descobri a consequencia daquela luzinha amarela com a plaquinha vermelha, não tô conseguindo cria meu .jar, só rodo a aplicação a partir do netbeans, já suspeitava mas me iludi, não ta dando, roda beleza com aquelas alterações que fizemos, mas ainda tem isso, e agora?

[quote=DiegoAC]Parabéns! Funcionou! Consegui antes que você respondesse minha ultima pergunta jogar o addActionListener no jPopupMenu, o netbeans ainda reclama que não consegue achar um método construtor na classe adContato mas eu resolvi executar mesmo assim e deu certo.

Ah olha só essa parte que tive que modificar como sugestão do net beans e pra jogar no meu JPopUpMenu
era assim:buttonContatos.addActionListener(new AdicionarContatosListener(this)); //<-- passo este formulário como parâmetro
ficou asim:jMenuItem1.addActionListener((ActionListener) new AdicionarContatosListener(this));
Aquele (ActionListener) antes do new que o net beans adicionou é um cast?
[/quote]

Muito bom! ^^
Exatamente, isso que o netbeans adicionou é um cast explícito da minha classe AdicionarContatosListener em um ActionListener, apesar de que não é necessário.

[quote=DiegoAC]Agora só algumas perguntas:

por que o netbeans esta reclamando que não acha um método construtor? veja o código:

[code] public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {

        public void run() {
            new adContato().setVisible(true); //aqui ele diz: cannot find symbol
        }                                     //symbol: constructor adConato() 
    });                                       //location: agenda.adConato
}[/code][/quote]

Você possui um construtor vazio na sua classe adContato? Se não, é por isso que o Netbeans está reclamando!
Eu não aconselho a colocar um construtor vazio, já que você precisa atualizar a outra tela quando chama a adContatos mas, só por convenção, coloque os dois construtores na sua classe pra você entender:

public class adContato extends JFrame {

    public adContato() {  }
    public adContato(JFrame mainWindows) {
 
        this(); //<-- chamada do construtor acima.
        /* suas operações */
    }
}

Esse é o modo do Netbeans indicar que há um erro! Como não há construtor vazio, não há como compilar, entende?

Vamos lá…

    // minha classe
    public class adContato extends JFrame {  
      
        // minha variável que representa a instância do formulário principal.
        private mainWindows formularioPai;  
        
        // meu construtor que recebe o formulário principal por parâmetro.
        public adContato(mainWindows formularioPai) {  
            this.formularioPai = formularioPai;  
        }  
        
        // meu construtor que recebe um JFrame por parâmetro.
        public adContato(JFrame formularioPai) {  
      
            // caso esse JFrame seja uma mainWindows...
            if (formularioPai instanceof mainWindows)  
                // faço o cast e adiciono na minha variável privada de controle do formulário principal.
                this.formularioPai = (mainWindows) formularioPai;  
        }  
      
         public void metodoQualquer() {  
             // chamo o método no formulário principal.
             this.formularioPai.fillContactsTable();  
         }  
    }  

Assim tá bom?

[quote=DiegoAC]
Mais uma vez muito obrigado, isto auxilia e muito pra mim ir desenvolvendo meu conhecimento em java.[/quote]
Mim não conjuga verbos.
http://tudibao.com.br/2010/04/quando-usar-eu-e-mim.html

Caramba aqui é java, português é tudo, eu sei da regra do “mim”, é o costume de escrever errado antes de aprender a regra. Mas voltando ao java vou testar volto já.

Fiz isso:

[code] public adContato() {
initComponents();
}

public adContato(mainWindows formularioPai) {
    this();
   
    this.formularioPai = formularioPai;

    //ESTABLECE CONEXÃO COM BD
    conInit = new bridge2db();

    //FAZ O PROGRAMA ABRIR NO MEIO DA TELA
    setLocationRelativeTo(null);

}

[/code]

Os dois métodos são contrutores? Pode -se considerar agora que não há mais método construtor vazio pelo que eu fiz? Testei com o método vazio também funcionou. Se eu tivesse mantido o método vazio ainda existiria alguma alternativa melhor?

[quote=DiegoAC]Fiz isso:

[code] public adContato() {
initComponents();
}

public adContato(mainWindows formularioPai) {
    this();
   
    this.formularioPai = formularioPai;

    //ESTABLECE CONEXÃO COM BD
    conInit = new bridge2db();

    //FAZ O PROGRAMA ABRIR NO MEIO DA TELA
    setLocationRelativeTo(null);

}

[/code]

Os dois métodos são contrutores? Pode -se considerar agora que não há mais método construtor vazio pelo que eu fiz? Testei com o método vazio também funcionou. Se eu tivesse mantido o método vazio ainda existiria alguma alternativa melhor?[/quote]

O que você fez com os construtores é exatamente o que deve ser feito: coloca-se todos os métodos e instâncias comuns ali e chama ele nos construtores específicos!
Quando se fala de construtores vazios, sim, você não tem construtores vazios, pois todos tem códigos.
Agora, quando se trata de construtores sem parâmetros, que é o nosso caso, ele se aplica por não possuir nenhum parâmetro nele.

Então caso encerrado! Muito obrigado! :thumbup: