Instâncias e classe estática

10 respostas
T

Bom dia.

Estou com uma dúvida, li bastante sobre o assunto e não consegui compreender.

Eu tenho uma classe Formulario() que contém os Get e Set´s.
Tenho uma classe conexao() que contém a conexão com o banco.
Uma outra classe Registro() que eu executo o seguinte comando:

frm.setAssunto(TextField1.getText());

Ele armazena o valor que selecionei…
Na classe Login() tenho o seguinte comando:

frm.getNome(TextField2.getText());

E mais algumas classes que insiro os valores no get e set!!
Meu problema é:
Cada vez que vou chamar, por exemplo na classe Registro:

Formulario frm = new Formulario();

Eu crio uma classe nova e não utilizo mais o valor que foi armazenado na classe anterior como o nome, por exemplo.
Eu li sobre classes estáticas, mas não soube como usá-las neste caso!!

Como faço para instanciar uma classe em várias outras sem que tenha que criar uma instância nova a cada vez que eu chamo?

10 Respostas

arthurgon

Olá.
Deu pra notar que você está trabalhando com Desktop não é?
Sugiro que estude um pouco sobre o uso do Spring ao invés de utilizar classes estáticas.

rmendes08

Spring ? Acho completamente desnecessário. Se o Thiago está com dificuldade com OO básica usar um framework de DI talvez só piore a situação.

1 - Quando você chama new você não cria uma classe nova, você cria um objeto novo. Esse é o conceito mais básico da orientação a objetos.

2 - E sim, o comportamento da instanciação de objetos é esse mesmo. Quando você cria um objeto novo ele não tem conhecimento algum sobre outros objetos, de forma que seus campos serão inicializados com seus respectivos valores padrão ou de acordo com a inicialização do construtor. É desse jeitinho que funciona.

Mas então, como você resolve o seu problema ?

Você tem que modelar o ciclo de vida do seu objeto: quem tem que criá-lo, quem vai usá-lo e quando ele vai deixar de existir. Com isso em mente , você tem que decidir :

1 - Qual classe vai chamar o operador new sobre a classe;

2 - Como passar uma referência desse objeto para as demais classes que o usarão: isso pode ser feito no construtor da classe ou então como parâmetros de métodos.

3 - Quais classes devem manter referências para esse objeto.

T

1 - Qual classe vai chamar o operador new sobre a classe;

2 - Como passar uma referência desse objeto para as demais classes que o usarão: isso pode ser feito no construtor da classe ou então como parâmetros de métodos.

3 - Quais classes devem manter referências para esse objeto.

[color=red]1 - A classe que vai chamar o operador NEW será minha primeira classe, Login. O primeiro valor armazenado: form.setNome(TextField1.getText())[/color].
[color=red]2 - COMO PASSAR UMA REFERÊNCIAS DESSE OBJETO SEM QUE EU CRIE UM NOVO…???[/color]
[color=red]3 - Todas as outras classes devem manter a referência deste objeto sem que crie um objeto novo, pois os valores são passados por parâmetro nos setAssunto, setNome, setProblema, em classes diferentes.[/color]

Só não sei como eu faço isso =
Passar estou passando, mas não sei como chamar o objeto sem criá-lo novamente…

rmendes08

Por exemplo:

class Login{
    public void executaLogin(){
        Formulario frm = new Formulario();

        Registro reg = new Registro();

        reg.fazAlgumaCoisaNoFormulario(frm);

        System.out.println(frm.getText()); //vai exibir  "Quem setou foi o registro"
    }
}

class Registro{
    public void fazAlgumaCoisaNoFormulario(Formulario frm){ //declara que o método deve receber de alguém um formulário, esse alguém tem 
       frm.setText("Quem setou foi o registro");                      //que se virar para criar o objeto Formulário
    }
}
T

Cara, valeu…Eu entendi tudo o que você colocou aí, UNICO problema!!Não consegui encaixar isso no código lá…

Código do Registro:

package Suporte;

import javax.swing.JOptionPane;

/**
 *
 * @author THenrique
 */
public class Registro extends javax.swing.JFrame {

    /** Creates new form Registro */
    public Registro() {
        initComponents();
        setLocationRelativeTo(null);
        setTitle("Registro");
    }
    Banco bco = new Banco();
    Formulario form = new Formulario();

           private void btEnviarActionPerformed(java.awt.event.ActionEvent evt) {                                         
        form.setProblema(problemArea.getText().toString());
        JOptionPane.showMessageDialog(null,form.getProblema());
        JOptionPane.showMessageDialog(null,form.getNome());
        JOptionPane.showMessageDialog(null,form.getAssunto());
        bco.inserir();
    }                                        

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

            public void run() {
                new Registro().setVisible(true);
            }
        });
    }

Código do Login:

package Suporte;

import javax.swing.JOptionPane;

public class Login extends javax.swing.JFrame {

    /** Creates new form Login */
    public Login() {
        initComponents();
        setLocationRelativeTo(null);
        setTitle("Login");
    }
    conexao con = new conexao();
    Banco bco = new Banco();
    Formulario form = new Formulario();
    Registro reg = new Registro();
    private void btConectarActionPerformed(java.awt.event.ActionEvent evt) {                                           

        if (con.fazConexao() != null) {
            if ((userTxt.getText().equals("Administrador"))) {
                if (passTxt.getText().equals("SupAdmin")) {
                    new Admin().setVisible(true);
                    dispose();
                }
            } else {
                if (bco.Verificar(userTxt.getText(), passTxt.getText()) == true) {
                    form.setNome(this.userTxt.getText());
                    new combo().setVisible(true);
                    dispose();
                } else {
                    JOptionPane.showMessageDialog(null, "Usuário/Senha inválidos.");
                    userTxt.setText("");
                    passTxt.setText("");
                }
            }
        }
    }                                          

    private void passTxtActionPerformed(java.awt.event.ActionEvent evt) {                                        
        // TODO add your handling code here:
    }                                       

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        dispose();
    }                                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new Login().setVisible(true);
            }
        });
    }

Código do Assunto:

package Suporte;

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class combo extends javax.swing.JFrame {

    JComboBox combo = null;
    MyComboModel model = null;
    JButton btOK = null;
    Formulario form = new Formulario();

    public combo() {

        setTitle("Assunto");
        setLayout(new GridLayout(1, 3));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final ArrayList<String> ast = new ArrayList<String>();
        ast.add("Monitor");
        ast.add("Teclado");
        ast.add("Mouse");
        ast.add("Rede");
        ast.add("Internet");
        ast.add("Telefonia fixa");
        ast.add("Telefonia Movel");
        ast.add("Office");
        ast.add("Impressora");
        ast.add("Suporte Brassuco");
        ast.add("DataSul");
        ast.add("Est. Comercial");
        ast.add("Exactus");
        ast.add("IntraSystem");
        ast.add("InfoFisc");

        model = new MyComboModel(ast);

        combo = new JComboBox(model); //Aqui ele cria o combo...
        btOK = new JButton("OK"); //Aqui ele cria o botão...
        initListeners(); //Inicia a ação do botão.




        getContentPane().add(combo); //Aqui ele adiciona o combo...
        add(btOK); //Aqui ele adiciona o botão...
        setLocationRelativeTo(null); //Posiciona no centro da tela.

        pack();




    }
    /*-- Inicio do método de ação do botão OK --*/

    public void initListeners() {
        btOK.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                form.setAssunto(combo.getSelectedItem().toString());
                JOptionPane.showMessageDialog(null,form.getAssunto());
                new Registro().setVisible(true);
                dispose();
            }
        });

    }

Como eu iria encaixar isso neste caso?? Precisaria do meu Formulario sem criar novo no Registro e no combo, no Login eu crio novo…
Não tenho métodos que eu criei no Registro, acho que por isso me confundi um pouco…

**REMOVI UMA SUJEIRA DO CÓDIGO QUE TINHA MANDADO JUNTO!

discorpio

Bom dia a todos.

Eu particularmente também não vejo problema nenhum em utilizar classes estáticas. Contudo você não precisa declarar todos os métodos de sua classe como estáticos. No seu caso por exemplo, basta ter um ou dois métodos estáticos dentro da sua classe principal que eu costumo chamar de FramePrincipal.

Em uma classe composta de métodos estáticos e dinâmicos, somente os métodos dinâmicos serão acessados na instanciação do objeto, enquanto que os métodos estáticos podem ser acessados apenas com o nome da classe (Referência da classe).

Como já disse o nosso amigo Rmendes08, a cada instanciação de um objeto dessa classe, os atributos são reciclados com um valor novo padrão definido ou não por você no construtor da classe através desses métodos dinâmicos, os valores dos métodos de cada objeto se diferenciam um do outro até mesmo em caso de herança (extends), já os métodos estáticos permaneceram com o mesmo valor para todos os objetos, por mais que voce crie várias instanciações (Objetos) dessa classe, e ainda assim cada objeto pode ter acesso ao método estático se for declarado como público, facilitando muito a vida do desenvolvedor.

A minha sugestão é essa:

1º) Crie apenas dois métodos estáticos dentro da sua classe FramePrincipal assim:

public class FramePrincipal extends JFrame {

      private static String user_log;

      public static String getUser_log(){
          return user_log;
      }

      public static void setUser_log(String user_log){
          FramePrincipal.user_log = user_log;
      }

      ......
      ......
      ......
 }

Dentro do construtor da classe FramePrincipal ficando toda ela da seguinte forma:

public class FramePrincipal extends JFrame {

      private static String user_log;

      public static String getUser_log(){
          return user_log;
      }

      public static void setUser_log(String user_log){
          FramePrincipal.user_log = user_log;
      }

      public FramePrincipal(){
        super("Cadastro de Visitantes");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        FrameLogin frmlogin = new FrameLogin(this);
        if (frmlogin.getResponse()){
            setVisible(true);
            // Dá acesso ao usuário
        } else {
            // Fecha a aplicação em caso de não autenticação
            dispose();
            System.exit(0);
        }

        .....
        .....
        .....
  
}

Agora eis minha a classe login

public class FrameLogin extends JDialog implements ActionListener, KeyListener {

    private JTextField txtlogin;
    private JPasswordField txtpassword;
    private JButton btnok, btncancel;
    private String mens;
    private Boolean response = false;
    private int accessdenied = 3;

    public FrameLogin(JFrame parent){
        super(parent, "Acesso ao programa Tal", true);
        setContentPane(getContainer());
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        pack();
        setLocationRelativeTo(this);
        setVisible(true);
    }

    public JPanel getContainer(){
       JPanel container = new JPanel(new GridLayout(4,1));
       // Definição da fonte
       Font font = new Font("Tahoma", 0, 14);
       // Login
       JLabel lblogin = new JLabel("Digite o seu login......");
       lblogin.setFont(font);
       container.add(lblogin);
       txtlogin = new JTextField(10);
       txtlogin.setFont(font);
       txtlogin.addKeyListener(this);
       container.add(txtlogin);
       // Password
       JLabel lblpassword = new JLabel("Digite a sua senha.....");
       lblpassword.setFont(font);
       container.add(lblpassword);
       txtpassword = new JPasswordField(10);
       txtpassword.setFont(font);
       txtpassword.addKeyListener(this);
       container.add(txtpassword);
       // Botões
       // OK
       btnok = new JButton("OK");
       btnok.addActionListener(this);
       container.add(btnok);
       // Cancel
       btncancel = new JButton("Cancelar");
       btncancel.addActionListener(this);
       JPanel panelbutton = new JPanel(new GridLayout(1,2);
       panelbutton.add(btnok);
       panelbutton.add(btncancel);

       container.add(panelbutton);
       
       return container;
    }

    // Verifica se os campos estão vazios
    private Boolean checkTextField(){
        if ("".equals(txtlogin.getText())){
            mens = "Campo login em branco.\n";
            mens += "Digite o login";
        } else if ("".equals(txtpassword.getText())){
            mens = "Campo senha em branco.\n";
            mens += "Digite a senha";
        } else {
            return true;
        }
        ContentLayout.mensagemErro(mens);
        return false;
    }
    
    // Disparo dos eventos dos botões
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource()==btncancel){
            setResponse(false);
        } else if (e.getSource()==btnok){
            if (checkTextField()){
               setResponse(logon());
               if (!getResponse() && accessdenied >= 0) return;
            } else {
               return;
            }
        }
        setVisible(false);
        dispose();
    }

    private Boolean logon(){
        UsuarioBean bean = new UsuarioBean();
        bean.setLogin_usu(txtlogin.getText());
        bean.setSenha_usu(Formatter.getMD5(txtpassword.getText()));
        UsuarioDao dao = new UsuarioDao();
        try {
            dao.selectLogin(bean);
            if ("".equals(bean.getNome_usu())){
               verifyChances();
               return false;
            } else {
               FramePrincipal.setUser_log(bean.getLogin_usu());
               return true;
            }
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage());
            accessdenied = -1;
            return false;
        }
    }

    private void verifyChances(){
        String ch;
        if (accessdenied==0){
            mens = "Voce não tem mais chances.\n";
            mens += "O programa será fechado.";
        } else {
            if (accessdenied==1){
                ch = " chance\n";
            } else {
                ch = " chances\n";
            }
            mens = "Voce só tem agora "+accessdenied+ch;
            mens += "de digitar o login e senha corretamente.";
            txtlogin.setText("");
            txtpassword.setText("");
        }
        accessdenied--;
        ContentLayout.mensagem(mens,"Acesso negado.");
    }


    @Override
    public void keyTyped(KeyEvent e){
        // Método não utilizado
    }

    @Override
    public void keyPressed(KeyEvent e){
        if (e.getKeyCode()==KeyEvent.VK_ENTER){
            if (e.getSource()==txtlogin){
                txtpassword.requestFocusInWindow();
            } else if (e.getSource()==txtpassword){
                btnok.doClick();
            }
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        txtlogin.setText(txtlogin.getText().toUpperCase());
    }

    public Boolean getResponse() {
        return response;
    }

    public void setResponse(Boolean response) {
        this.response = response;
    }

}
rmendes08

Ora, é só criar um método setFormulario na sua classe registro. Quando você criar o registro você chama esse método passando o formulário que você criou. Dentro do métod setFormulario basta atribuir a referência que você recebeu à referência declarada na classe.

T
rmendes, seria algo do tipo:
Formulario form;
public Formulario getForm(){
return form;}

public void setForm(Formulario form){
this.form = form;}

Isso na classe registro?
E o que mudaria isso no caso de eu utilizar o formulario em mais de uma classe?
De qualquer forma eu teria que criar um novo Registro para cada classe que eu chamar.!!

rmendes08

Sim, aí você implementa o get/set conforme sua necessidade. Se você somente precisar receber o formulário de alguma outra classa basta implementar o set.

T

Até aí tudo bem...
Mas por exemplo, na classe Login:

Registro reg = new Registro();

//Eu quero dar um:
 setNome(TextField1.getText());
Aí depois na classe combo:
//Outra vez 
Registro reg = new Registro();
//Eu quero dar um:
setAssunto(combo.getSelectedItem().toString());

Eu não vou estar criando 2 vezes Registro novo? Da mesma forma que eu criaria Formulario?

Criado 18 de janeiro de 2011
Ultima resposta 18 de jan. de 2011
Respostas 10
Participantes 4