[RESOLVIDO] java.lang.NullPointerException ao gerar arquivo TXT

11 respostas
JhowTroMundo

Olá a todos.

Sou principiante em java, e recentemente recebi uma proposta de um primo para desenvolver um softwaer simples para ele e seus colegas de trabalho, pois lhes facilitaria e agilizaria o processo.

Pra isso, precisei criar uma classe que contenha um metodo que receba uma string e salve seu valor em um arquivo .TXT

Ficou dessa forma

import java.awt.*; 
import java.io.*; 
import javax.swing.JFrame;

public class SalvarTXT extends JFrame  {
    
     public static FileDialog Fabrir;    
     public static FileDialog Fsalvar;   
    
    SalvarTXT() {
       Fabrir = new FileDialog(this,"Abrir arquivo",FileDialog.LOAD);
       Fsalvar = new FileDialog(this,"Salvar arquivo",FileDialog.SAVE);        
    }

    public static void salvarTXT (String texto) {
        String nomeDoArquivo;
        //System.out.println(texto);

        try {
                Fsalvar.show();
                if (Fsalvar.getFile()==null) return;
                nomeDoArquivo = Fsalvar.getDirectory()+Fsalvar.getFile() + ".txt";
                FileWriter out = new FileWriter(nomeDoArquivo);
                out.write(texto);
                out.close();
            }
            catch(java.io.IOException exc) {
                System.out.println(exc);
            }
            //catch(java.lang.NullPointerException erro) {
                //System.out.println(erro);
            //}

    }

    public static String letTXT(){

        String nomeDoArquivo;
        try {
                Fabrir.show();
                if (Fabrir.getFile()==null) return null;

                nomeDoArquivo = Fabrir.getDirectory()+Fabrir.getFile();
                FileReader in = new FileReader(nomeDoArquivo);
                String S="";
                int i = in.read();
                while (i!=-1) {
                    S = S +(char)i;
                    i = in.read();
                }

                in.close();
                return S;

            }
            catch(java.io.IOException exc) {
                System.out.println(exc);
                return null;
            }
            //catch(java.lang.NullPointerException erro) {
            //    System.out.println(erro);
            //    return null;
            //}
    }
}

Criei uma classe para fazer o teste:

import javax.swing.JOptionPane;

/**
 *
 * @author Jhonatas
 */
public class SalvarTXTTeste {

    public static void main (String[] args){
        SalvarTXT.salvarTXT(String.valueOf(JOptionPane.showInputDialog(null, "Digite seu texto", "Entrada",JOptionPane.INFORMATION_MESSAGE)));
        System.out.println(SalvarTXT.letTXT());
    }

}

Ao executar a classe de teste, ocorre os seguinte erro nos metodos salvarTXT e abrir TXT:

Exception in thread main java.lang.NullPointerException

at salvartxt.SalvarTXT.salvarTXT(SalvarTXT.java:30)

at salvartxt.SalvarTXTTeste.main(SalvarTXTTeste.java:17)

O mesmo erro se refere às seguintes linhas:

20 - Fsalvar.show();
40 - Fabrir.show();

O que posso fazer?

Alguma sugestão de onde posso encontrar classes prontas para utilizá-las e estudar por elas?

Obrigado.

11 Respostas

ViniGodoy

Como seus métodos são estáticos, o construtor não executará.

O ideal é que você pare de trabalhar com métodos estáticos.

Mas uma solução rápida para o seu problema seria remover aquele construtor e declarar os atributos assim:

public static FileDialog fAbrir = new FileDialog(null,"Abrir arquivo",FileDialog.LOAD); public static FileDialog fSalvar = new FileDialog(null,"Salvar arquivo",FileDialog.SAVE);

Atenção. Fique atento também à convenção de nomes do Java. Nomes de atributo começam por letras minúsculas, e seguem o estilo CamelCase.

Outra coisa. Como você trabalha com Swing o ideal é usar a classe JFileChooser, e não a classe FileDialog.

Victor_Neves

será que resolveria se voce descomentasse o catch na linha 30 ???
ve ai.

renamed

O problema está aqui

SalvarTXT() {
		Fabrir = new FileDialog(this, "Abrir arquivo", FileDialog.LOAD);
		Fsalvar = new FileDialog(this, "Salvar arquivo", FileDialog.SAVE);
	}

Essa parte do código só seria executada se vc criasse uma instância dessa classe, como vc nunca faz isso, esse código nunca é executado.

Logo, qnd vc executa

Fsalvar.show();

Acontece esse erro de ponteiro nulo.
Minha sugestão é fazer o seguinte:

Fsalvar = new FileDialog(new JFrame(), "Salvar arquivo", FileDialog.SAVE); Fsalvar.show();

Coloque essa linha bem acima de onde vc chama o método show.

A propósito, show está “deprecated”… tente usar setVisible(true) :wink:

ok? =D

JhowTroMundo

ViniGodoy

Eu já havia tentado dessa forma, mas ocorre outro erro. Uma variável não-estática não pode ser referenciada em um contexto estático, o que só se resolveu quando instanciei os FileDialog dentro do construtor.

declarei os métodos como estáticos pela mesma razão: o método main da classe de teste é estático, portando só pode fazer referencia a métodos estáticos de outra classe.

Não, não resolveria. coloquei esse catch a nivel de teste, apenas. Com esse catch funcionando, o codigo é executado, mas como um erro é encontrado, ele ontinua a executar normalmente, pelo catch.

Vou tentar criando um método não estático na classe de testes e fazer a chamada dos métodos por ela. Acho que resolve.

JhowTroMundo

renamed:
O problema está aqui

SalvarTXT() {
		Fabrir = new FileDialog(this, "Abrir arquivo", FileDialog.LOAD);
		Fsalvar = new FileDialog(this, "Salvar arquivo", FileDialog.SAVE);
	}

Essa parte do código só seria executada se vc criasse uma instância dessa classe, como vc nunca faz isso, esse código nunca é executado.

Logo, qnd vc executa

Fsalvar.show();

Acontece esse erro de ponteiro nulo.
Minha sugestão é fazer o seguinte:

Fsalvar = new FileDialog(new JFrame(), "Salvar arquivo", FileDialog.SAVE); Fsalvar.show();

Coloque essa linha bem acima de onde vc chama o método show.

A propósito, show está “deprecated”… tente usar setVisible(true) :wink:

ok? =D

Entendo o que quer dizer, mas sim, foram instanciadas globalmente, portanto deveria funcionar em qualquer método.

Obrigado pelas dicas e pela ajuda.

ViniGodoy

Mas na minha solução rápida, eu continuo declarando as variáveis como estáticas!

O que você deve fazer no main, se for parar de trabalhar com método estáticos, é criar uma instância da sua classe, e só então chamar os métodos. Vou ver se elaboro um exemplo aqui.

renamed

JhowTroMundo:
renamed:
O problema está aqui

SalvarTXT() {
		Fabrir = new FileDialog(this, "Abrir arquivo", FileDialog.LOAD);
		Fsalvar = new FileDialog(this, "Salvar arquivo", FileDialog.SAVE);
	}

Essa parte do código só seria executada se vc criasse uma instância dessa classe, como vc nunca faz isso, esse código nunca é executado.

Logo, qnd vc executa

Fsalvar.show();

Acontece esse erro de ponteiro nulo.
Minha sugestão é fazer o seguinte:

Fsalvar = new FileDialog(new JFrame(), "Salvar arquivo", FileDialog.SAVE); Fsalvar.show();

Coloque essa linha bem acima de onde vc chama o método show.

A propósito, show está “deprecated”… tente usar setVisible(true) :wink:

ok? =D

Entendo o que quer dizer, mas sim, foram instanciadas globalmente, portanto deveria funcionar em qualquer método.

Na verdade vc só declarou os atributos globalmente, não os instanciou.
Consegue enxergar a diferença? :smiley:

JhowTroMundo

Graças às sugestoes de todos vcs, agora funcionou direitinho.

Parei de trabalhar com metodos estáticos, e instanciei a classe SalvarTXT na classe de testes, e assim o problema de referencia estática sumiu.

Seguem as classes:

import java.awt.*; 
import java.io.*; 
import javax.swing.JFrame;

public class SalvarTXT extends JFrame  {
    
     FileDialog fAbrir = new FileDialog(this,"Abrir arquivo",FileDialog.LOAD);;
     FileDialog fSalvar= new FileDialog(this,"Salvar arquivo",FileDialog.SAVE);;
    
    SalvarTXT() {
       
    }

    public void salvarTXT (String texto) {
        String nomeDoArquivo;       

        try {
                fSalvar.show();
                if (fSalvar.getFile()==null) return;
                nomeDoArquivo = fSalvar.getDirectory()+fSalvar.getFile() + ".txt";
                FileWriter out = new FileWriter(nomeDoArquivo);
                out.write(texto);
                out.close();
            }
            catch(java.io.IOException exc) {
                System.out.println(exc);
            }
    }

    public String letTXT(){

        String nomeDoArquivo;
        try {
                fAbrir.show();
                if (fAbrir.getFile()==null) return null;

                nomeDoArquivo = fAbrir.getDirectory()+fAbrir.getFile();
                FileReader in = new FileReader(nomeDoArquivo);
                String S="";
                int i = in.read();
                while (i!=-1) {
                    S = S +(char)i;
                    i = in.read();
                }

                in.close();
                return S;

            }
            catch(java.io.IOException exc) {
                System.out.println(exc);
                return null;
            }
            
    }
}
import javax.swing.JOptionPane;

/**
 *
 * @author Jhonatas
 */
public class SalvarTXTTeste {

    public static void main (String[] args){
        SalvarTXT salvarTXT = new SalvarTXT();
        
        salvarTXT.salvarTXT(String.valueOf(JOptionPane.showInputDialog(null, "Digite seu texto", "Entrada",JOptionPane.INFORMATION_MESSAGE)));
        
        System.out.println(salvarTXT.letTXT());

    }

}

Desculpem a minha “noobisse”, ainda estou aprendendo a utilizar os recursos do forum e do java.

Obrigado a todos pela ajuda.

ViniGodoy

Veja um exemplo, usando JFileChooser, e fazendo a leitura do arquivo através da classe Scanner.

import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Scanner;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

public class SalvarTxt {
    //A classe JFileChooser é a versão Swing da FileDialog
    private JFileChooser fileChooser = new JFileChooser();

    public void salvar(String texto) {
        //Mostramos a caixe de save. O método retorna APPROVE_OPTION caso o usuário tenha pressionado o ok
        //Portanto, se não retornar isso, saímos do método (ele pressionou cancel ou fechou a caixa sem selecionar arquivo nenhum).
        if (fileChooser.showSaveDialog(null) != JFileChooser.APPROVE_OPTION) {
            return;
        }

        //Obtemos o arquivo selecionado pelo usuário
        File file = fileChooser.getSelectedFile();

        //Criamos um PrintWriter, para escrever no arquivo.
        PrintWriter pw = null;
        try {
            //Escrevemos no arquivo. 
            pw = new PrintWriter(file);
            pw.println(texto);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //Fechamos o arquivo.
            if (pw != null) {
                pw.close();
            }
        }
    }

    public String ler() {
        //Mesmo esquema do método acima, mas agora usamos a caixa de abrir arquivo.
        if (fileChooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION) {
            return "";
        }

        File file = fileChooser.getSelectedFile();
        //Criamos um StringWriter, para gerar a string lida do arquivo
        //O StringWriter é simplesmente um buffer, do que foi escrito. Isso pq gerar strings através de concatenação direta 
        //é uma tarefa muito lenta. Uma alternativa seria usar também o StringBuilder.
        StringWriter sw = new StringWriter();
        //Criamos um PrintWriter, para escrever a String.
        PrintWriter pw = new PrintWriter(sw);
        
        //Criamos um scanner, para ler do arquivo.
        Scanner scan = null;
        try {
            scan = new Scanner(file);
            //Enquanto o arquivo tiver linhas
            while (scan.hasNextLine()) {
                //Lemos a linha
                pw.println(scan.nextLine());
            }
            //Retornamos o texto lido.
            return sw.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        } finally {
            //Fechamos o arquivo
            if (scan != null) {
                scan.close();
            }
        }
    }

    public static void main(String[] args)
    {
        SalvarTxt salvar = new SalvarTxt();
        salvar.salvar(JOptionPane.showInputDialog(null, "Digite seu texto", "Entrada",JOptionPane.INFORMATION_MESSAGE));
        JOptionPane.showMessageDialog(null, salvar.ler());
    }
}

Tome também o cuidado de sempre fechar o arquivo num finally, como fiz ali em cima.

JhowTroMundo
ViniGodoy:
Veja um exemplo, usando JFileChooser, e fazendo a leitura do arquivo através da classe Scanner.
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Scanner;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

public class SalvarTxt {

    private JFileChooser fileChooser = new JFileChooser();

    public void salvar(String texto) {
        if (fileChooser.showSaveDialog(null) != JFileChooser.APPROVE_OPTION) {
            return;
        }

        File file = fileChooser.getSelectedFile();
        PrintWriter pw = null;
        try {
            pw = new PrintWriter(file);
            pw.println(texto);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (pw != null) {
                pw.close();
            }
        }
    }

    public String ler() {
        if (fileChooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION) {
            return "";
        }

        File file = fileChooser.getSelectedFile();
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        
        Scanner scan = null;
        try {
            scan = new Scanner(file);
            while (scan.hasNextLine()) {
                pw.println(scan.nextLine());
            }
            return sw.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        } finally {
            if (scan != null) {
                scan.close();
            }
        }
    }

    public static void main(String[] args)
    {
        SalvarTxt salvar = new SalvarTxt();
        salvar.salvar(JOptionPane.showInputDialog(null, "Digite seu texto", "Entrada",JOptionPane.INFORMATION_MESSAGE));
        JOptionPane.showMessageDialog(null, salvar.ler());
    }
}

90% do que voce fez aqui eu não entendo, mas vou rodar esse codigo e estudar essas classes novas (pra mim).

obrigado :D

ViniGodoy

Ok, inclui uns comentários ali em cima.

Criado 4 de janeiro de 2010
Ultima resposta 4 de jan. de 2010
Respostas 11
Participantes 4