Problemas ao instanciar um nov formulario (JFrame2) a partir de um evento no outro (JFrame1)

Pessoal, já até postei essa dúvida aqui mas não tive ajuda. Bem, tenho dois formularios JFrame1 e JFrame2. No primeiro tenho os campos Codigo e Descrição. No segundo, tenho uma tabela com todos os produtos cadastrados. Minha ideia é preencher os campos do primeiro formulario apenas com um clique na tabela do segundo. Fiz o seguinte: para abrir o segundo form eu fiz isso ao pressionar a tecla Tab, usando o evento FocusLost. Ao abrir o form2 e carregar a tabela, clicando nela estou conseguindo levar os dados para o form1 tranquilamente. E qual o problema?
Bem, para abrir o form2 a partir do form1 eu to usando

frmProdutos Prod = new frmProdutos()

; E para voltar para o form1 com os dados capturados da tabela faço o seguinte:

frm1 tela = new frm1();
          
          
    //    txtCodigo.setText(tabelaProdutos.getValueAt(tabelaClientes.getSelectedRow(),0).toString());
          tela.txtNome.setText(tabelaProdutos.getValueAt(tabelaClientes.getSelectedRow(),1).toString());
       

          tela.setVisible(true);
          setVisible(false);

E qual o problema que estou enfrentando agora ? Bem… percebi que toda vez que vou fazer uma busca no form2 e volto com os dados recuperados, já tem um form1 aberto e abre um outro form1, ficando varios abertos ao mesmo tempo.
Gostaria de saber como corrigir isso

1 curtida

Você não deveria estar criando uma nova instância do form1 para preencher os campos, mas sim usar a instância que já existe (a mesma que chamou o form2 previamente).

É possível realizar isso de diferentes formas. Uma delas é passar a referência do form1 ou dos textfields para o form2 quando criá-lo, e usar essa referência para preencher os textfields. Algo como:


class frmProdutos extends JFrame {
  private JTextField textFieldASerPreenchido;

  public frmProdutos(JTextField txtField) {
    textFieldASerPreenchido = txtField;
  }

  // outro evento que fecha a tela e preenche o textField
  void buttonPressedOuOQueQuerQueSeja {

    // frm1 tela = new frm1(); // remova essa linha, você NÃO quer criar o form1 novamente

    textFieldASerPreenchido .setText(tabelaProdutos.getValueAt(tabelaClientes.getSelectedRow(),1).toString());

    tela.setVisible(true);
    setVisible(false);
  }
}

Ao criar o form de produtos:

frmProdutos Prod = new frmProdutos(this.txtNome);

Abraço.

1 curtida

Amigo boa noite!!

Veja bem, fiz exatamente como voce disse e ai me deparei com outro ou outros problemas, vejamos:
1 - antes para abrir o form2(clientesBuscaGeral) e o form3(produtosBuscaGeral) bastava eu apertar a tecla TAB, usei o FocusLost. Estando no form2 ou no form3 uma tabela contendo todos os registros de clientes ou produtos, bastava eu clicar no registro desejado e os dados daquele registro em específico ja preencheriam os campos no form1 (vendas).
2 - Aparentemente o problema estava no FocusLost, que cria uma funçao anonima dentro do Listener, e isso impedia que uma classe pudesse acessar a outra. Em razão disso resolvi fazer a chamada dos forms atraves KeyCode da tecla pressionada. O resultado foi que mesmo não havendo mais erro no projeto, não consigo mais abrir as telas de busca geral. Estando no campo txtNome ou no txtDescricao do form1 e apertandoa o enter, a barra de espaço ou qualquer outra conforme o KeyCode, nada acontece, o formulário não abre. O outro problema é que, deixando a chamada no OnKeyPress até abre, porem, ao clicar na tabela, nada acontece, os dados não são transferidos para os campos do formulario de vendas.

para entender melhor as modificações que fiz conforme a sua orientação, logo abaixo tem o meu código:

No form Vendas:
Evento KeyPressed do campo CodProduto

digite ou cole o código aqui
 if (evt.getKeyCode() == KeyEvent.VK_0) {
                frmProdutosBuscaGeral telaPr = new frmProdutosBuscaGeral();
               telaPr.setVisible(true);
            
            }

Evento KeyPressed do campo txtNome

if (evt.getKeyCode() == KeyEvent.VK_SPACE) {
                
                frmClientesBuscaGeral telaC = new frmClientesBuscaGeral(this.txtNome);
                telaC.setVisible(true);
                
                
            
            }

No formulario ClientesBuscaGeral:
 private JTextField txtNome;
    private JFormattedTextField formatTxtCPF;
    private JFormattedTextField FomattedtxtField;
    
     public frmClientesBuscaGeral(JTextField txtField) {
        txtNome = txtField;
        
        formatTxtCPF = FomattedtxtField;
     }
    
    public void listar(){
    
      ClientesDAO dao = new ClientesDAO();
      List<Clientes> lista = dao.listarClientes();
      DefaultTableModel dados = (DefaultTableModel)tabelaClientes.getModel();
      dados.setNumRows(0);
    for(Clientes c : lista){
    
       dados.addRow(new Object[]{
                c.getId(),
                c.getNome(),
                c.getEmail(),
                c.getCelular(),
                c.getTelefone(),
                c.getCep(),
                c.getEndereco(),
                c.getNumero(),
                c.getBairro(),
                c.getCidade(),
                c.getComplemento(),
                c.getEstado(),
                c.getRg(),
                c.getCpf(),
   }); 

No clique do mouse sobre um dos campos da tabela. 
txtNome.setText(tabelaClientes.getValueAt(tabelaClientes.getSelectedRow(),1).toString());
       
          formatTxtCPF.setText(tabelaClientes.getValueAt(tabelaClientes.getSelectedRow(),13).toString());
         // tela.setVisible(true);
          setVisible(false);

No formulario ProdutosBuscaGeral, 

private JTextField txtCodProduto, txtDescricao, txtPreco_Unitario;
    
     public frmProdutosBuscaGeral(JTextField txtField) {
        txtDescricao = txtField;
        txtCodProduto = txtField;
        txtPreco_Unitario = txtField;
     }

public void listar() {

        ProdutosDAO dao = new ProdutosDAO();
        List<Produtos> lista = dao.listarProdutos();
        DefaultTableModel dados = (DefaultTableModel) tabelaProdutos.getModel();
        dados.setNumRows(0);
        for (Produtos c : lista) {

            dados.addRow(new Object[]{
                c.getId(),
                c.getDescricao(),
                c.getPreco(),
                c.getQtd_estoque(),
                c.getFornecedor().getNome()

            });

        }
    }

e Agora no clique do mouse sobre um dos campos da tabela.

//Passo 2 Pegando os dados do cliente clicado e preenchendo os campos da aba Dados Pessoais ( jTabbedPane1)
        txtCodProduto.setText(tabelaProdutos.getValueAt(tabelaProdutos.getSelectedRow(), 0).toString());
        txtDescricao.setText(tabelaProdutos.getValueAt(tabelaProdutos.getSelectedRow(), 1).toString());
        txtPreco_Unitario.setText(tabelaProdutos.getValueAt(tabelaProdutos.getSelectedRow(), 2).toString());

        //frmVendas.setVisible(true);
        dispose();

Eu fiz conforme voce orientou, nenhum dos eventos que antes estava acontecendo agora funciona

O que tem de errado ai ?

Obrigado

1 curtida

O que te mostrei só se refere à parte de passar os dados do table para os edits, não envolve nada de focusLost, keypressed ou outros eventos.

Essa parte não faz sentido, você está preenchendo todas as variáveis no form de busca com o mesmo JTextField. Imagino que tenha sido apenas erro de digitação, certo?

Você precisa debugar e verificar se os eventos (seja focusLost, seja keypress) estão sendo chamados corretamente antes de se preocupar em abrir as outras janelas ou preencher campos. Não adianta ficar batendo cabeça com a segunda janela se você nem está conseguindo exibi-la corretamente.

Fiz um pequeno exemplo de como o focusLost poderia ser usado para chamar uma segunda janela, e de como o keyevent poderia preencher um jtextfield na primeira janela e fechar essa segunda janela:

import javax.swing.*;
import java.awt.GridLayout;
import java.awt.Dimension;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

public class JanelaPrincipal extends JFrame {
	private JTextField campoComFocusLost;
	private JButton botaoQualquer;

	public JanelaPrincipal() {
		super("Janela");
		
		setPreferredSize(new Dimension(300, 300));
		setLayout(new GridLayout(0, 2));
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		campoComFocusLost = new JTextField();
		botaoQualquer = new JButton("OK");
		
		campoComFocusLost.addFocusListener(new FocusListener(){
			@Override
			public void focusGained(FocusEvent e) {}

			@Override
			public void focusLost(FocusEvent e) {
				exibirBuscaEPreencherCampo();
			}
		});

		getContentPane().add(new JLabel("Campo"));
		getContentPane().add(campoComFocusLost);
		getContentPane().add(botaoQualquer);

		pack();
	}
	
	private void exibirBuscaEPreencherCampo() {
		SegundaJanela sj = new SegundaJanela(campoComFocusLost);
		sj.setVisible(true);
	}

	public static void main(String[] args) {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
			  new JanelaPrincipal().setVisible(true);
			}
		});
	}
}
import javax.swing.*;
import java.awt.GridLayout;
import java.awt.Dimension;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;

public class SegundaJanela extends JFrame {
	private JTextField campoParaDigitacao;
	private JTextField campoAPreencherNaOutraJanela;

	public SegundaJanela(JTextField campoDaOutraJanela) {
		super("Segunda Janela");
		campoAPreencherNaOutraJanela = campoDaOutraJanela;

		setPreferredSize(new Dimension(300, 300));
		setLayout(new GridLayout(0, 2));
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

		campoParaDigitacao = new JTextField();
		
		campoParaDigitacao.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
				if (evt.getKeyCode() == KeyEvent.VK_ENTER){
					preencherEFechar();
				}
            }
        });

		getContentPane().add(new JLabel("Valor"));
		getContentPane().add(campoParaDigitacao);

		pack();
	}
	
	private void preencherEFechar() {
		campoAPreencherNaOutraJanela.setText(campoParaDigitacao.getText());
		dispose();
	}
}

Reiterando que estou exemplificando o focusLost e como preencher um jtextfield em outra tela. Você precisa usar apenas as partes que te servem. Simplesmente copiar e colar esse código sem entendê-lo não vai te ajudar.

Abraço.

1 curtida

Você realmente precisa voltar ao form antigo enquanto o novo está em processo de preenchimento? Se não for o caso, o ideal é usar um JDialog modal:

public class DialogQueTemOValorQueQueroRetornar extends JDialog
{
     private int valorSelecionado = 0;
     //Aqui vai a parte que você monta a interface gráfica.

    public int getValorSelecionado() {
        return valorSelecionado;
    }
}

Aí na hora que o JFrame for abrir a outra janela é só fazer:

var dlg = new DialogQueTemOValorQueQueroRetornar();
dlg.setModal(true);
dlg.setVisible(true);
int selecionadoNoDialog = dlg.getValorSelecionado();

Diferente de um JFrame, uma JDialog modal vai bloquear o código no setVisible, deixando o JFrame esperando até que a janela seja fechada e os dados possam ser lidos.

1 curtida

Blza, segui aqui o seu exemplo e deu certo. Só que de tanto fuçar, consegui fazer da outra forma, enviando os campos de texto do form1 como parametro no construtor ao chamar o form2.
Obrigado pela dica

Só que estou acionando o form2 atraves do evento no botao pesquisar. Não conseguir fazer isso com acionamento de teclas, como pore xemplo TAB ou Espaço ou F1.