[RESOLVIDO]Usar a mesma instância em lugares diferentes

Bom dia pessoal, venho aqui outra vez solicitar a ajuda de vocês, vou tentar me expressar para ser o mais direto possível.
Estou desenvolvendo um projeto para faculdade onde o mesmo tem leitura de biometria para identificação do usuário, isso já esta ok, esta funcionando, porém quando o usuário é identificado preciso acionar algumas ações, como a Classe principal onde esta o código para reconhecimento do usuário estava bem extensa, resolvi desmembrar alguns métodos de controle para outra Classe (CalculoEControle), ai me vem a grande dúvida que estou tendo agora e já tive outras vezes, e que gostaria de sanar.
Na Classe TelaPrincipal, após a identificação do usuário preciso acionar alguns métodos da Classe CalculoEControle, então crio a instância e passo como parâmetro o id do usuário que foi autenticado e um valor, que seria para desenvolver alguns cálculos, pois bem, porém na Classe CalculoEControle, um método chama o outro para pode fazer os cálculos desejados, mas da o erro NullPointerException, ou seja, preciso instanciar ela novamente para poder executar os métodos, então se fazer isso terei problema, como tive outras vezes. Bem não sei se fui claro, vou postar um pedaço do código para ver se ajuda!

Essa é um método da classe TelaPrincipal

protected void init() {
    capturer.addDataListener(new DPFPDataAdapter() {
        @Override
        public void dataAcquired(final DPFPDataEvent e) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {   
                    PegaUsuarios pegaUsuario = new PegaUsuarios();                            //Cria uma instancia de da classe PegaUsuarios 
                    List <Usuario> lista = pegaUsuario.buscarUsuario();                       //Cria List (Lista) de Usuario que vai receber os objetos retornados pelo método buscarUsuario()
                    DPFPSample amostra = e.getSample();                                       //Captura a amostra para verificar se existe no banco de dados
                    for (Usuario usuario : lista) {                                           //Cria variável do tipo Usuario que recebe dados da lista                             
                        DPFPTemplate temp = DPFPGlobal.getTemplateFactory().createTemplate(); //Criando variável temporária para receber a informação da digital que esta no banco e verificar                 
                        temp.deserialize(usuario.getDigital());
                        int id  = usuario.getID();
                        Double consumo = usuario.getConsumo();
                        
                        if (verify(amostra, temp)){ //Verifica se o usuário tem o cadastro no banco de dados 
          
              CalculoEContole cec = new CalculoEContole(id, consumo);//                                

                            break;                               
                        }
                    }                                              
                }
            });
        }
    });
}

Esse é um método da classe CalculoEComando

public class CalculoEContole extends TelaPrincipal{
    private static CalculoEContole instancia;
    private Connection conexao    = null;
    private PreparedStatement pst = null;
    private ResultSet rs          = null;    

Toolkit toolkit;
Timer timer;

public CalculoEContole(int idUsuario, Double consumo){    
    timer = new Timer();
    timer.schedule(new CalculoEContole.RemindTask(), 0, 5 * 1000);  //0 = Delay | 5*1000 = 5 segundos
    conexao = ModuloConexao.conector();
}
    
class RemindTask extends TimerTask {
    public void run() {
        if (verificaUsuario()) { //Fazer o método de autenticação aqui!!
            System.out.println("Entrooooooou!");
            pegaDados(id);
        } else { 
            System.out.println("Tempo terminou!");
            //timer.cancel(); // Não é preciso porque
                              // existe o System.exite(0);
            System.exit(0);   // Stop processo AWT  
                              // (and everything else)
        }
    }
}


private boolean verificaUsuario(){
    Double consumoPermitido = getConsumo();
    Double consumoPraticado = null;
    String sql = "SELECT COALESCE (SUM(CORRENTE), 0) AS CONSUMO "
            + "FROM CONSUMO C WHERE C.DATA BETWEEN ?  AND ? AND C.USUARIO = ?";
    //Padrão de Data/Hora = 2016.10.03 00:00:00
    try {
        pst = conexao.prepareStatement(sql); //pst recebe endereço da base de dados junto com a SQL
        pst.setString(1, getData() + " 00:00:00");
        pst.setString(2, getData() + " 23:59:59");
        pst.setInt   (3, getID());      
        
        rs = pst.executeQuery();             //rs recebe o retorno da consulta SQL
        if(rs.next())                        //Se houver retorno do select entra na condição
        {   
            consumoPraticado = rs.getDouble(1); //Variável consumoPraticado recebe o valor da consulta SQL
            System.out.println(consumoPraticado);
        }
    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, e);
    }
    
    consumoPraticado = (consumoPraticado * 5) / 3600; //(Consumo praticado * tempo de espera para salvar dados no banco) / 3600 segundos (1h)
    
    if(consumoPraticado < consumoPermitido){
        return true;
    }
    return false;
}

Quando vou rodar o app, da o erro pq para usar o VerificaUsuario(), preciso instanciar a classe.

Pensei em usar o padrão Singleton, porém depois de ler sobre, dizem que não é muito bom!

Espero que tenha sido claro e objetivo, abraço.

Se você criar um construtor para a classe RemindTask que recebe um objeto do tipo CalculoEControle não dá certo?

Algo tipo isso:

Construtor da classe RemindTask

public RemindTask(CalculoEControle cec) {
    this.cec = cec; //partindo do principio que você tem uma variável de instância do tipo CalculoEControle na classe RemindTask
}

Construtor da classe CalculoEControle

public CalculoEContole(int idUsuario, Double consumo){    
    timer = new Timer();
    timer.schedule(new CalculoEContole.RemindTask(this), 0, 5 * 1000);  //0 = Delay | 5*1000 = 5 segundos
    conexao = ModuloConexao.conector();
}

To chutando… não sei se funciona.

Aí você trabalha sempre referenciando esse objeto dentro da classe RemindTask

1 curtida

Amigo obrigado pelo retorno, mas acabei usando o Singleton mesmo, me atendeu, o código ficou da seguinte forma:

Classe com Singleton

    /*
     * To change this license header, choose License Headers in Project Properties.
     * To change this template file, choose Tools | Templates
     * and open the template in the editor.
     */
    package br.com.energymanagement.telas;

    import br.com.energymanagement.dal.ModuloConexao;
    import java.awt.Toolkit;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import static java.lang.System.in;
    import java.net.Socket;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.text.SimpleDateFormat;
    import java.util.Timer;
    import java.util.TimerTask;
    import javax.swing.JOptionPane;

    /**
     *
     * @author david
     */
    public class Singleton {    
        private Connection conexao    = null;
        private PreparedStatement pst = null;
        private ResultSet rs          = null;
        
        private int id;
        private Double consumo;
        
        Toolkit toolkit;
        Timer timer;

        private static Singleton uniqueInstance = new Singleton();

        private Singleton() {
                
                timer = new Timer();
                timer.schedule(new Singleton.RemindTask(), 0, 5 * 1000);  //0 = Delay | 5*1000 = 5 segundos
                conexao = ModuloConexao.conector();
        }

        public static Singleton getInstance() {
            return uniqueInstance;
        }
            
        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public Double getConsumo() {
            return consumo;
        }

        public void setConsumo(Double consumo) {
            this.consumo = consumo;
        }
            
            class RemindTask extends TimerTask {
            public void run() {
                if (verificaUsuario()) {
                    System.out.println("Entrooooooou!");
                    pegaDados(getId());
                } else { 
                    System.out.println("Tempo terminou!");
                    comandoRele("a");
                    timer.cancel(); // Não é preciso porque
                                      // existe o System.exite(0);
                    //System.exit(0);   // Stop processo AWT  
                                      // (and everything else)
                }
            }
        }
            
            //MÉTODO VERIFICA SE O USUÁRIO AINDA TEM COTA PARA SER USADO E RETORNA TRUE OU FALSE
        private boolean verificaUsuario(){
            Double consumoPermitido = getConsumo();
            Double consumoPraticado = null;
            String sql = "SELECT COALESCE (SUM(CORRENTE), 0) AS CONSUMO "
                    + "FROM CONSUMO C WHERE C.DATA BETWEEN ?  AND ? AND C.USUARIO = ?";
            //Padrão de Data/Hora = 2016.10.03 00:00:00
            try {
                pst = conexao.prepareStatement(sql); //pst recebe endereço da base de dados junto com a SQL
                pst.setString(1, getData() + " 00:00:00");
                pst.setString(2, getData() + " 23:59:59");
                pst.setInt   (3, getId());      
                
                rs = pst.executeQuery();             //rs recebe o retorno da consulta SQL
                if(rs.next())                        //Se houver retorno do select entra na condição
                {   
                    consumoPraticado = rs.getDouble(1); //Variável consumoPraticado recebe o valor da consulta SQL
                    System.out.println("Praticado: " + consumoPraticado);
                    System.out.println("Permitido: " + consumoPermitido);
                }
            } catch (Exception e) {
                JOptionPane.showMessageDialog(null, e);
            }
            
            consumoPraticado = (consumoPraticado * 5) / 3600; //(Consumo praticado * tempo de espera para salvar dados no banco) / 3600 segundos (1h)
            
            if(consumoPraticado < consumoPermitido){
                return true;
            }
            return false;
        }
        
        public String getData(){  
               SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd");  
               String data = formatter.format(new java.sql.Date(System.currentTimeMillis()));
               return data;
            }
        
        public void pegaDados(int id){
            
            String enderecoServ = "192.168.1.201"; //Criar campo para definição de host/porta em algum lugar
            int porta = 23;
            
            try {
                Socket client = new Socket(enderecoServ, porta);
                System.out.println("Conectado no servidor " + enderecoServ + ":" + porta);
                
                //Cria um canal para receber dados.
                DataInputStream in = new DataInputStream(client.getInputStream());
                //Cria um canal para enviar dados.
                DataOutputStream out=new DataOutputStream(client.getOutputStream());

                out.writeBytes("f");

                String s = in.readLine(); //Aguarda o recebimento de uma string.
                System.out.println(s);
                armazenaDados(getId(), s);

                //Fecha os canais de entrada e saída.
                in.close();
                out.close();
                
                //Fecha o socket.
                client.close();
                
            } catch (Exception e) {
                JOptionPane.showMessageDialog(null, e);
            }   
        }
        
        //MÉTODO RESPONSÁVEL EM ENVIAR INFORMAÇÕES DE ABERTURA/FECHAMENTO DO RELE PARA ARDUINO
        public void comandoRele(String comando) {
            String enderecoServ = "192.168.1.201"; //Criar campo para definição de host/porta em algum lugar
            int porta = 23;

            try {
                Socket client = new Socket(enderecoServ, porta);
                //System.out.println("Conectado no servidor " + enderecoServ + ":" + porta);

                //Cria um canal para enviar dados.
                DataOutputStream out = new DataOutputStream(client.getOutputStream());

                out.writeBytes(comando);

                //Fecha os canais de entrada e saída.
                in.close();
                out.close();

                //Fecha o socket.
                client.close();

            } catch (Exception e) {
                JOptionPane.showMessageDialog(null, "Erro ao enviar comando para o módulo, verifique a conexão! " + e);
            }
        }
        
        //MÉTODO RESPONSÁVEL POR ADICIONAR INFORMAÇÕES NO BANCO DE DADOS
        public void armazenaDados(int id, String dados) {
            String sql = "INSERT INTO CONSUMO(CARGA, USUARIO, TENSAO, CORRENTE) VALUES (?,?,?,?)";
            String array[];
            array = dados.split(";");

            //Quebrando a String recebida e pegando os valores convertendo em double
            double corrente = Double.parseDouble(array[0]);
            double tensao   = Double.parseDouble(array[1]);
            double potencia = Double.parseDouble(array[2]);

            try {
                pst = conexao.prepareStatement(sql);
                pst.setDouble(1, potencia);
                pst.setInt   (2, id)       ;
                pst.setDouble(3, tensao)  ;
                pst.setDouble(4, corrente);

                pst.executeUpdate();
            } catch (Exception e) {
                JOptionPane.showMessageDialog(null, e);
            }
        }
    }

E as chamadas dos métodos estou fazendo assim:

if (verify(amostra, temp)){ //Verifica se o usuário tem o cadastro no banco de dados 
                                Singleton.getInstance().setId(id);
                                Singleton.getInstance().setConsumo(consumo);
                                break;