Aplicação Swing Recebendo NullPointerException

tentando migrar minha aplicação simploria de web para desktop, fiz uma tela pra inserir os dados no banco de dados… mais. recebo um nullPointer sem saber o motivo, segue o codigo…

package com.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

import com.dao.ClienteDAO;
import com.model.Cliente;

public class MontaUI {
	
	private JFrame janela;
	private JPanel principal;
	private JTextField nome;
	private JTextField sexo;
	private JTextField telefone;
	private JTextField rg;
	private JTextField cpf;
	private JTextField dataNascimento;
	
	public static void main(String[] args) {
		new MontaUI().montaTela();
	}
		
	public void montaTela(){
		montaJanela();
		montaPainelPrincipal();
		montaEntrada();
		montaBotaoAdicionar();
		mostraJanela();
	}
	
	public void montaEntrada(){
		nome = new JTextField("Nome");
		sexo = new JTextField("Sexo");
		telefone = new JTextField("Telefone");
		rg = new JTextField("Rg");
		cpf = new JTextField("CPF");
		dataNascimento = new JTextField("Data de Nascimento");
	}
	
	public void montaPainelPrincipal(){
		principal = new JPanel();
		janela.add(principal);
	}
	
	public void montaJanela(){
		janela = new JFrame("Cadastro Geral");
		janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
                // na linha abaixo recebo a exception
		principal.add(nome);
		principal.add(sexo);
		principal.add(telefone);
		principal.add(rg);
		principal.add(cpf);
		principal.add(dataNascimento);
	}
	
	public void mostraJanela(){
		janela.pack();
		janela.setSize(700,700);
		janela.setVisible(true);
	}
	
	private void montaBotaoAdicionar() {
		JButton botaoCarregar = new JButton("Grava");
		botaoCarregar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new ClienteDAO().adiciona(new Cliente(nome.getText(), sexo.getText(), telefone.getText(), rg.getText(), cpf.getText()));
			}
		});
		principal.add(botaoCarregar);
	}
	
	
}

poste o stack…

Exception in thread “main” java.lang.NullPointerException
at com.gui.MontaUI.montaJanela(MontaUI.java:55)
at com.gui.MontaUI.montaTela(MontaUI.java:30)
at com.gui.MontaUI.main(MontaUI.java:26)

o método montaJanela é chamado antes do método montaPainelPrincipal. Isso faz com que a variável principal não tenha valor ainda :wink:

Dica: monte a tela adicionando os componentes conforme a árvore hierárquica.

Ou seja, renderiza o container e depois os items desses e assim vai… Isso evita esses problemas.

hum… realmente nao sei nada de swing ainda. essa é minha primeira aplicação… mas ainda recebo essa stack, mesmo mudando o que você disse.

Exception in thread “main” java.lang.NullPointerException
at com.gui.MontaUI.montaPainelPrincipal(MontaUI.java:47)
at com.gui.MontaUI.montaTela(MontaUI.java:30)
at com.gui.MontaUI.main(MontaUI.java:26)

Olha, eu acho que o problema esta no método public void montaJanela().

Neste método ele adiciona os jTextFields nome, sexo, telefone, rg, cpf e dataNascimento porém eles ainda não foram criados na memória, ou seja, estão nulos.

Acho que você tem que alterar o método montaTela() deixando assim:

public void montaTela(){
montaEntrada();
montaPainelPrincipal();
montaBotaoAdicionar();
montaJanela();
mostraJanela();
}

Ah e também tem que adicionar o jPanel principal ao jFrame no método montaJanela.

… alterei… e ainda continuo recebendo o erro…


package com.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

import com.dao.ClienteDAO;
import com.model.Cliente;

public class MontaUI {
	
	private JFrame janela;
	private JPanel principal;
	private JTextField nome;
	private JTextField sexo;
	private JTextField telefone;
	private JTextField rg;
	private JTextField cpf;
	private JTextField dataNascimento;
	
	public static void main(String[] args) {
		new MontaUI().montaTela();
	}
		
	public void montaTela(){
		montaEntrada();
		montaPainelPrincipal();
		montaBotaoAdicionar();
		montaJanela();
		mostraJanela();
	}
	
	public void montaEntrada(){
		nome = new JTextField("Nome");
		sexo = new JTextField("Sexo");
		telefone = new JTextField("Telefone");
		rg = new JTextField("Rg");
		cpf = new JTextField("CPF");
		dataNascimento = new JTextField("Data de Nascimento");
	}
	
	public void montaPainelPrincipal(){
		principal.add(nome);
		principal.add(sexo);
		principal.add(telefone);
		principal.add(rg);
		principal.add(cpf);
		principal.add(dataNascimento);
		
	}
	public void montaJanela(){
		janela = new JFrame("Cadastro Geral");
		principal = new JPanel();
		janela.add(principal);
		janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	public void mostraJanela(){
		janela.pack();
		janela.setSize(700,700);
		janela.setVisible(true);
	}
	
	private void montaBotaoAdicionar() {
		JButton botaoCarregar = new JButton("Grava");
		botaoCarregar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new ClienteDAO().adiciona(new Cliente(nome.getText(), sexo.getText(), telefone.getText(), rg.getText(), cpf.getText()));
			}
		});
		principal.add(botaoCarregar);
	}
	
	
}

Tentou usar o depurador?

Pode colocar o breakpoint na linha que a exception indica.

Crie conforme sua árvore de componentes. Digamos que você tenha um panel, com um panel dentro dele e um textfield dentro do segundo panel.

Panel
|
Panel
|
TextField

a criação seria algo como:

[code]

public class Tela extends JFrame {
private JPanel panel1;
private JPanel panel2;
private JTextField textfield;

public Tela() {
    //posicionamento, tamanho, etc, etc aqui
    initComponents();
}

private void initComponents() {
     this.add(getPanel1());
}

private JPanel getPanel1() {
     if(panel1 == null) {
         panel1 = new JPanel();
         panel1.add(getPanel2());
         //configurações aqui
     }
     return panel1;
}


private JPanel getPanel2() {
     if(panel2 == null) {
         panel2 = new JPanel();
         panel2.add(getTextField());
         //configurações aqui
     }
     return panel2;
}

private JTextField getTextField() {
if(textfield== null) {
textfield= new JTextField();
//configurações aqui
}
return textfield;
}

}[/code]

Ele vai iniciar lá de cima e vai criando os componentes em ordem. Quando chegar no filho, é de certeza que ele já existe, quando o pai adicionar também se sabe que o filho existe.

EDIT: Não testei nada, pode não compilar :slight_smile:

[code] public void montaPainelPrincipal(){
principal = new JPanel(); // crie o objeto JPanel aqui, se não ocorrerá o NullPointerException
principal.add(nome);
principal.add(sexo);
principal.add(telefone);
principal.add(rg);
principal.add(cpf);
principal.add(dataNascimento);

}
public void montaJanela(){
	janela = new JFrame("Cadastro Geral");
	// retire a linha abaixo, pois ele já foi criado no método montaPainelPrincipal
	// principal = new JPanel();
	janela.add(principal);
	janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}[/code]

Mas acho que fica mais fácil de identificar os erros se fizer como o Daniels sugeriu, criando os getters para os componentes, assim cada método fica responsável pela inicialização de um componente.

obrigado eric. agora funcionou… estou tendo um trabalhao com swing…

Acho que criar tela e adicionar métodos, fica mais facio dessa forma.

[code]package Janelas;

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public final class tela extends JFrame implements ActionListener {

private JLabel nome;
private JTextField txtNome;
private JButton btnSair;

public tela() {
    super("Tela de Cadastro");
    initComponents();

}

//iniciar componentes;
public void initComponents() {

    nome = new JLabel("Informe o Nome:");
    txtNome = new JTextField();

    btnSair=new JButton("Sair");

    setLayout(null);

    nome.setBounds(10, 20, 100, 20);
    txtNome.setBounds(10, 40, 180, 20);
    btnSair.setBounds(90, 90, 80, 20);

    btnSair.addActionListener(this);


    Container c = getContentPane();

    c.add(nome);
    c.add(txtNome);
    c.add(btnSair);

    setBounds(10, 30, 500, 400);
    setVisible(true);


}

private void Métodos() {//Metodo
}


public void actionPerformed(ActionEvent e) {//Métodos Abstratos
   if(e.getSource()== btnSair){
       dispose();
       //System.exit(0); ou esse
   }
}

  public static void main(String args[]) {
    new tela();
}

}
[/code]