JAVA para desktop MVC

29 respostas
java
A

Boa noite a todos, estou fazendo um CRUD usando MVC, e tenho que fazer com que o programa funcione com uma DAO feita com SQL e com uma DAO feita com listas de array em memória (Não simultaneamente, quando alternar de uma DAO para outra o programa tem que funcionar do mesmo jeito ) minhas duvidas são as seguintes. Posso instanciar a DAO na classe principal? Tenho 3 tabelas no banco de dados, tenho que fazer uma DAO e um controlador para cada tabela? Para o programa funcionar com as duas DAOs é só nomear os métodos de ambas igualmente certo? Controlador é a mesma coisa que FACADE? O construtor pode ficar no controlador?
Segue meu código:

TO (Não vou colocar os geters e seters para não ficar gigante…):
package TO;

public class Professor {
   private Integer rg;
   private String nome; 
   private String titulo;

DAO:

public class ConsultasProfessor extends Conexao {
    

    public boolean inserir(Professor pro) {
        PreparedStatement ps = null;
        Connection con = getConexao();

        String sql = "INSERT INTO professor (nome, rg, titulo) VALUES (?,?,?)";

        try {
            ps = con.prepareStatement(sql);
            ps.setString(1, pro.getNome());
            ps.setInt(2, pro.getRg());
            ps.setString(3, pro.getTitulo());
            ps.execute();
            return true;

        } catch (SQLException e) {
            System.err.println(e);
            return false;
        } finally {
            try {
                con.close();
            } catch (SQLException e) {
                System.err.println(e);
            }
        }
    }

Controler:
public class CtrlProfessor implements ActionListener {

private Professor professor;
private ConsultasProfessor consultaprofessor;
private frmProfessor frmprofessor;

public CtrlProfessor(Professor professor, ConsultasProfessor consultaprofessor, frmProfessor frmprofessor) {
    this.professor = professor;
    this.consultaprofessor = consultaprofessor;
    this.frmprofessor = frmprofessor;
    this.frmprofessor.btnBuscar.addActionListener(this);
    this.frmprofessor.btnModificar.addActionListener(this);
    this.frmprofessor.btnDeletar.addActionListener(this);
    this.frmprofessor.btnSalvar.addActionListener(this);
    this.frmprofessor.btnLimpar.addActionListener(this);
}

public void iniciar() {
    frmprofessor.setTitle("Professor");
    frmprofessor.setLocationRelativeTo(null);

}

public void limpar() {
    frmprofessor.txtNome.setText("");
    frmprofessor.txtRG.setText("");
    frmprofessor.txtTitulo.setText("");

}

@Override
public void actionPerformed(ActionEvent e) {

    if (e.getSource() == frmprofessor.btnSalvar) {
        professor.setNome(frmprofessor.txtNome.getText());
        professor.setRg(Integer.parseInt(frmprofessor.txtRG.getText()));
        professor.setTitulo(frmprofessor.txtTitulo.getText());

        if (consultaprofessor.inserir(professor)) {
            JOptionPane.showMessageDialog(null, "Salvo com sucesso!");
            limpar();
        } else {
            JOptionPane.showMessageDialog(null, "Erro ao salvar, consulte o log!");
            limpar();
        }

    }

Classe principal:

public class ProjetoMvc {

/**

* @param args the command line arguments

*/

public static void main(String[] args) {

Professor professor = new Professor();

frmProfessor frmprofessor = new frmProfessor();

ConsultasProfessor consultaprofessor = new ConsultasProfessor();
CtrlProfessor ctrlprofessor = new CtrlProfessor(professor, consultaprofessor, frmprofessor);
    ctrlprofessor.iniciar();
    frmprofessor.setVisible(true);
    
}

}
e a view só tem o frame.

29 Respostas

A

Alguem?

javaflex

Exemplo: http://www.mballem.com/post/utilizando-swing-com-banco-de-dados/?i=1

A

Primeiramente obrigado por responder.
No exemplo esta escrito: “É possível na View o acesso ao Model, como instanciar uma classe de entidade para ter acesso aos seus métodos, mas nunca as classes que possuem relacionamentos com o banco de dados. No exemplo deste tutorial foram passados para o Controller par metros tipo String, mas poderiam ser os objetos do tipo Contato (Entidade Contato).”

No meu caso eu instanciei a DAO que tem relacionamento do banco na minha classe principal assim:

public static void main(String[] args) {
        Professor professor = new Professor(); //TO
        frmProfessor frmprofessor = new frmProfessor(); //VIEW
        ConsultasProfessor consultaprofessor = new ConsultasProfessor(); //DAO
        
        CtrlProfessor ctrlprofessor = new CtrlProfessor(professor, consultaprofessor, frmprofessor);//Controler
        ctrlprofessor.iniciar();
        frmprofessor.setVisible(true);

Será que pode? Ou esta errado?

A

Obrigado @javaflex

javaflex

Segue o exemplo que te passei ou algum outro material. Se tentar aprender sem material de estudo vai ficar se complicando a toa. Seguindo algo terá menos dúvidas genéricas e sim mais pontuais. Lá no exemplo, o main só trata sobre frame, não tem nada de DAO.

A

Então @javaflex o problema é que o programa esta feito e funcionando, por isso queria saber se esta certo, ai não teria necessidade de fazer outro ou corrigir, já que estou fazendo mais três trabalhos paralelo a esse seria bom saber que esse esta pronto, mas obrigado caso precisar fazer outro vou usar o exemplo.
Se alguém souber se pode instanciar a DAO na main da um alô aqui please.

javaflex

Poder pode, é uma classe como qualquer outra. Mas fica uma zona. Mas fica a seu critério. Só te passei um bom material pra seguir.

A

Então essa é minha preocupação pq meu professor é ultra exigente, e se tiver alguma coisa que fere o design pattern ele já arrebenta a nota

javaflex

Então segue esse exemplo ou outro material se não quiser fazer feio.

MVC não é design pattern, é padrão de arquitetura.

A

É acho q vai ser o jeito :weary:… Vlw men

D

Na minha opinião, o MVC é somente a separação do Model-View-Controller, se vc conseguir identificar isso no seu projeto, então está certo. Mas para mim, o código tem alguns problemas.

O link do exemplo do @javaflex é muito bom, mas tem algumas coisas lá que não são explicadas.

Então significa que terá que usar interfaces:

public interface ProfessorDAO {
  public boolean inserir(Professor p);
  public List<Professor> buscarPorNome(String nome);
  public List<Professor> buscarTodos();
  public void remover(int id);
}

public class ProfessorDAOBaseImpl implements ProfessorDAO {}
public class ProfessorDAOListImpl implements ProfessorDAO {}

Outro problema é que o Controller está sendo instanciado na view e não acho isso muito certo:

public class CtrlProfessor /*implements ActionListener*/ {
// private Professor professor;
private ProfessorDAO professorDAO;
private frmProfessor frmprofessor;

public CtrlProfessor(ProfessorDAO professorDAO) {
    this.professor = professor;
    this.professorDAO = professorDAO;
    /* coisas da view
    this.frmprofessor.btnBuscar.addActionListener(this);
    this.frmprofessor.btnModificar.addActionListener(this);
    this.frmprofessor.btnDeletar.addActionListener(this);
    this.frmprofessor.btnSalvar.addActionListener(this);
    this.frmprofessor.btnLimpar.addActionListener(this);
    */
}

public void iniciar() {
    frmprofessor = new frmprofessor(this);
    frmprofessor.setVisible(true);
// frmprofessor.setTitle("Professor"); // transfira para view
// frmprofessor.setLocationRelativeTo(null); // transfira para view
}

public boolean inserirProfessor(Professor p) { return professorDAO.inserir(p); }
/* transfira para view
public void limpar() {
    frmprofessor.txtNome.setText("");
    frmprofessor.txtRG.setText("");
    frmprofessor.txtTitulo.setText("");
}
@Override
public void actionPerformed(ActionEvent e) {

    if (e.getSource() == frmprofessor.btnSalvar) {
        professor.setNome(frmprofessor.txtNome.getText());
        professor.setRg(Integer.parseInt(frmprofessor.txtRG.getText()));
        professor.setTitulo(frmprofessor.txtTitulo.getText());

        if (consultaprofessor.inserir(professor)) {
            JOptionPane.showMessageDialog(null, "Salvo com sucesso!");
            limpar();
        } else {
            JOptionPane.showMessageDialog(null, "Erro ao salvar, consulte o log!");
            limpar();
        }

    }
}    
*/
}

Quase tudo que coloquei em comentário é da view.

public static void main(String[] args) {
  // configuração e startup
  // ProfessorDAO pDAO = new ProfessorDAOBaseImpl();
  ProfessorDAO pDAO = new ProfessorDAOListImpl();

  // app
  CtrlProfessor controller = new CtrlProfessor(pDAO);
  controller.iniciar();
}

No main geralmente inicia primeiro as configurações e os startups e depois o controle da aplicação, o próprio controle inicia o restante no método iniciar.

É minha opinião sobre MVC. Nos livros, cada um vai mostrar o MVC de diferentes formas.

A

Obrigado @diego12, não consegui arrumar o código pq estou aprendendo, deu uma boa pesquisada e estou refazendo com interfaces e tudo bem separado, mas não estou sabendo chamar o update:

DAO:

public Aluno alterar(Aluno aluno) {

PreparedStatement ps = null;

Connection con = new Conexao().getConnection();
String sql = "UPDATE aluno SET nome=? WHERE rg=?";

        try {
            ps = con.prepareStatement(sql);
            ps.setString(1, aluno.getNome());
            ps.setInt(2, aluno.getRg());
            ps.execute();
            return aluno;

        } catch (SQLException e) {
            System.err.println(e);
            return null;
        } 
    }

Controler:

@Override
    public Aluno alterar(Aluno aluno) {
       return mad.alterar(aluno);
    }
view:

private void alterarActionPerformed(java.awt.event.ActionEvent evt) {

ManterAlunoFacade manteralunofacade = new ManterAlunoFacade();

Aluno aluno = new Aluno();
try {
            aluno.setNome(nomeAluno.getName());
            aluno.setRg(Integer.parseInt(rgAluno.getText()));
            
            aluno = manteralunofacade.alterar(aluno);
            
            JOptionPane.showMessageDialog(null, "Alterado com sucesso!");
            limparCampos();

        } catch (HeadlessException | NumberFormatException ex) {
            Logger.getLogger(NovoAluno.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

interfaces DAO e CONTROLlER:

public Aluno alterar(Aluno al);

Acho q não estou sabendo chamar na view

D

Como está a view? Acho que o problema é que o botão não está chamando o método.

A

Esta assim:

private void alterarActionPerformed(java.awt.event.ActionEvent evt) {                                        
            ManterAlunoFacade manteralunofacade = new ManterAlunoFacade();
            Aluno aluno = new Aluno();

            try {
                aluno.setNome(nomeAluno.getName());
                aluno.setRg(Integer.parseInt(rgAluno.getText()));
                
                aluno = manteralunofacade.alterar(aluno);
                
                JOptionPane.showMessageDialog(null, "Alterado com sucesso!");
                limparCampos();

            } catch (HeadlessException | NumberFormatException ex) {
                Logger.getLogger(NovoAluno.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
A

@diego12 chega a aparecer a mensagem do JOptionPane mas não faz o update no banco de dados, acho que eu fiz alguma coisa errada na hora de chamar na view, não sei bem como fazer, estou aprendendo java, estou pesquisando modelos e fazendo

D
aluno = manteralunofacade.alterar(aluno);
        if (aluno != null) {
            JOptionPane.showMessageDialog(null, "Alterado com sucesso!");
            limparCampos();
        } else {
            JOptionPane.showMessageDialog(null, "Erro na atualização!");
        }

e no DAO

// ps.execute();
 ps.executeUpdate();
A
deu esse erro:

Exception in thread “AWT-EventQueue-0” java.lang.NullPointerException

at Models.ManterAlunoDAO.alterar(ManterAlunoDAO.java:103)

at Controller.ManterAlunoFacade.alterar(ManterAlunoFacade.java:52)

at view.NovoAluno.alterarActionPerformed(NovoAluno.java:221)

at view.NovoAluno.access$100(NovoAluno.java:19)

at view.NovoAluno$2.actionPerformed(NovoAluno.java:91)
A

Um amigo meu acho o erro:

try {
                aluno.setNome(nomeAluno.getName());

era getText no lugar de getName :weary:

Mas eu queria saber como que eu faço pra tratar o erro do jeito que vc postou com o if else com o meu codigo é  ver se os campos estão vazio?

Tentei assim:

try {

if(nomeAluno.getText() != “” && rgAluno.getText() != “”){

aluno.setNome(nomeAluno.getText());

aluno.setRg(Integer.parseInt(rgAluno.getText()));
aluno = manteralunofacade.alterar(aluno);
        
        JOptionPane.showMessageDialog(null, "Alterado com sucesso!");
        limparCampos();
        }
        else{
            JOptionPane.showMessageDialog(null, "Erro na atualização!");
        }
    } catch (HeadlessException | NumberFormatException ex) {
        Logger.getLogger(NovoAluno.class.getName()).log(Level.SEVERE, null, ex);
    }

N sei pq mas o try e o if não querem aparecer na citação do código

A

fiz o if assim: if(nomeAluno.getText() != “” && rgAluno.getText() != “”){

D

Use métodos para pegar os valores dos componentes:

na view:

public String getNome() {
    String nome = nomeAluno.getText();
    if (nome == null) return "";
    return nome.trim();
}

public int getRG() {
    try {
        return Integer.parseInt(rgAluno.getText());
    } catch(Exception e) {
      return -1;
    }
}

no action:

try {
        aluno.setNome(getName());
        aluno.setRg(getRG());
        
        aluno = manteralunofacade.alterar(aluno);
        JOptionPane.showMessageDialog(null, "Alterado com sucesso!");
        limparCampos();
    } catch (Exception ex) {
        JOptionPane.showMessageDialog(null, ex.getMessage());
    }

no controle:

public Aluno alterar(Aluno aluno) throws Exception{
   validarAluno(aluno);
   return mad.alterar(aluno);
}

public void validarAluno(aluno) {
  if (aluno.getNome == null || aluno.getNome.isEmpty()) throw new Exception("Nome inválido!");
  if (aluno.getRG <= 0) throw new Exception("RG inválido!");
}

[EDIT]
melhor criar uma classe para validar:

public class ValidadorDeAluno {
  public void validar(Aluno aluno) throws Exception {}
}

ValidadorDeAluno validadorDeAluno = new ValidadorDeAluno ();
public Aluno alterar(Aluno aluno) throws Exception{
   validadorDeAluno.validar(aluno);
   return mad.alterar(aluno);
}
A

Boa noite @diego12 obrigado pela ajuda.
Agora estou fazendo as DAOs de arrays, mas eu fiz o inserir eu creio que esta certo mas não esta adicionando na array, não aprece erro nenhum

public boolean inserir(String nome, Integer rg) throws Exception {
        int cont = 0;
        Aluno al = new Aluno();
        al.setNome(nome);
        al.setRg(rg);
        ArrayList<Aluno> alunos = new ArrayList<>();
        alunos.add(al);
        return cont > 0;
       
    }
D

Onde está sendo armazenada a lista?

ArrayList<Aluno> alunos = new ArrayList<>();
 public boolean inserir(String nome, Integer rg) throws Exception {
        // int cont = 0;
        Aluno al = new Aluno();
        al.setNome(nome);
        al.setRg(rg);
        alunos.add(al);
        // return cont > 0;
       return true;
    }
A

Na ArrayList alunos
criei o objeto aluno
Aluno al = new Aluno();
pego as propriedades e coloco no objeto
al.setNome(nome);
al.setRg(rg);
Ai coloco o objeto na arraylist
alunos.add(al);
né?

D

Sim, mas “onde está sendo armazenada a lista” ? Como vc acessaria a lista se vc a perdesse? A solução seria colocando a lista como atributo da classe.

A

Assim né:
public class ManterAlunoDAO extends Conexao implements InterfaceManterAlunoDAO{

private ArrayList<Aluno> aluno = new ArrayList<>();


@Override
public boolean inserir(String nome, Integer rg) throws Exception {
    int cont = 0;
    Aluno al = new Aluno();
    al.setNome(nome);
    al.setRg(rg);
    ArrayList<Aluno> alunos = new ArrayList<>();
    alunos.add(al);
    return cont > 0;
   
}

Se for assim, já estava assim, mas não esta gravando

D

Falta remover aquela linha:

al.setRg(rg);
// ArrayList<Aluno> alunos = new ArrayList<>(); // remover
alunos.add(al);
A

Consegui, acabei mudando o parâmetro do método para objeto

@Override
    public boolean inserir(Aluno aluno) throws Exception {
        this.aluno.add(aluno);
        return true;
       
    }

Estou fazendo o de busca agora, mas não esta dando certo:

public Aluno consulta(Aluno aluno) {
                int tamanho = this.aluno.size();
                int aux=0;
                for(int i = 0; i<tamanho; i++){
                    if(this.aluno.get(i).getRg().equals(aluno.getRg())){
                        aluno = this.aluno.get(i);
                        aux++;
                    }
                    if(aux == 0)
                        throw new UnsupportedOperationException("Nenhum aluno encontrado.");
                    return aluno;
                }
                return aluno;
                
            }
D

Não faz sentido buscar algo que já tem, faça as buscas pelos atributos:

public Aluno buscarAlunoPorRg(Integer rg) {
            int tamanho = this.aluno.size();
            for(int i = 0; i<tamanho; i++){
                if(this.aluno.get(i).getRg().equals(rg)){
                    return this.aluno.get(i);
                }
            }
            throw new UnsupportedOperationException("Nenhum aluno encontrado.");
        }
A

Não sei pq mas ele entra na exception toda vez, e eu mandei imprimir a arraylist no botão de inserir e ela esta gravando tudo

Criado 1 de junho de 2018
Ultima resposta 13 de jun. de 2018
Respostas 29
Participantes 3