1. Padrão MVC

O objetivo do Model View Controller (MVC) é separar os dados ou lógicas de negócios (Model) da interface do usuário (View) e do fluxo da aplicação (Control). Utilizando este padrão seria possível reutilizar boa parte da aplicação para a comunicação com outras interfaces e também torna mais fácil a manutenção na aplicação.

Model: onde ficam as classes de negócio, têm o contato com as informações armazenadas e que são mostradas, estejam elas em um banco de dados, arquivo XML, ou onde quer que estejam. É no Model e somente no Model que as operações de CRUD ( em inglês  Create, Read, Update e Delete) que devem acontecer - inserir, consultar, alterar e deletar. As classes model armazenam dados nos atributos de interface dos objetos e permitem a execução das funções (métodos) extraídos do problema de negócio.

CRUD em inglês: 
C
reate
(kriˈeɪt): criar.
R
ead
(rid): ler.
U
pdate (ʌpˈdeɪt):
atualizar.
D
elete (dɪˈlit):
deletar.

View: é a apresentação, é o que aparece, é o que é visualizado por quem usa o sistema. É no View que as informações, sejam elas quais forem e de de qual lugar tenha vindo, serão exibidas.

Controller: é responsável por controlar todo o fluxo do programa, onde a lógica se desenvolve, como se fosse um processador em uma CPU. Um controlador funciona como um intermediário entre a camada de apresentação e a camada de negócios, sua função é controlar e coordenar o envio de requisições feitas entre a visão e o modelo. O controller define o comportamento da aplicação, o controle é quem interpreta as solicitações (cliques, seleções de menus) feitas por usuários com bases nestes requerimentos o controlador comunica-se com o modelo que seleciona a view e atualiza-a para o usuário, ou seja, o controlador controla e mapeia as ações.

O esquema abaixo mostra um MCV padrão, embora possa haver pequenas alterações para adaptações que são necessárias para cada projeto, como a inclusão de um pacote só para as classes genéricas, possibilitando assim, a impotação desse pacote.

2. DAO - Data Access Object

O padrão de projeto DAO (Data Access Object / Objeto de Acesso a Dados) se tornou um dos padrões de projeto mais utilizados no desenvolvimento de aplicações de softwares e tem como finalidade separar as regras de acesso a banco de dados das regras de negócios e de interface com usuário ou qualquer outro tipo de classe que não tenha relevância alguma com as ações de persistência.

O uso do pattern DAO, além de prover um melhor design para aplicação, agregar princípios de boas práticas, propicia um melhor reaproveitamento de implementação. Um DAO na aplicação propicia um ponto central, para acesso a dados, fazendo uso de um quantitativo de classes relativamente pequenos.

Todas as comunicações com o mecanismo de persistência são mediadas por um objeto o DAO. Esse objeto mapeia informações transportadas em objetos (Transfer Object) para instruções da API de persistência e mapeia resultados obtidos dela de volta para os mesmos objetos de transporte. Toda a lógica de mapeamento e execução das instruções é deixada dentro do objeto DAO desta forma isolando a aplicação da API de persistência por completo.

O objeto DAO é responsável por operar o mecanismo de persistência em nome da aplicação tipicamente executando os quatro tipos de operações - Criar, Recuperar , Alterar, Apagar - conhecidas pela sigla CRUD - do inglês Create, Retrive, Update , Delete. As operações de edição são invocadas diretamente passando o objeto com as informações a serem editadas. As operações de recuperação são normalmente implementadas como métodos específicos.

O DAO é um tipo muito especifico de Serviço (padrão Service) especializado em conversar com o SGBD e em prover as operações CRUD e de pesquisas. Por isto o contrato de um DAO é diferenciado da sua implementação (como é normal no padrão Service) e cada implementação corresponde a uma tecnologia especifica e/ou a um SGBD especifico. Em ultima análise não se trata de uma única implementação, mas de uma familias de implementações. Cada familia especificamente desenhada para um tecnologia de persistência, um SGDB e até um conjunto especifico de objetos de transporte.

A camada, ou layer, de persistência ou de acesso aos dados é a parte da aplicação responsável por se comunicar com o banco de dados, ou com o framework de persistência, sendo mais conhecidos como DAO.

As classes DAO representam uma camada própria, e formam um pacote de acesso de dados, algumas vezes sob o pacote do modelo, algumas vezes um pacote independente e outras vezes parte do pacote de controladores. O mais comum é mesmo que o pacote de DAO fique subordinado ao Modelo, mas sem estendê-lo. Assim temos uma separação e relativa independência da camada de acesso dados e do Domínio.

O principio é que para cada Modelo, temos um DAO correspondente. Toda interação e configuração com o Banco de dados, ou com o framework de persistência, ficam na camada dos DAO. Então o DAO passa a programar métodos como Select, Delete, Insert, Update e outros que venham a ser necessário. Podem programar métodos mais específicos, como selecionarOndeNomeComecaComLetra ou cadastrarLista.

É 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.


O projeto abaixo exemplifica os conceitos abordados neste tutorial:

Projeto: AgendaUm

1. Criar o projeto ProjetoDb1b no netbeans:

Arquivo > Novo projeto ... > aplicativo java > Próximo  > Nome do projeto: AgendaUm > Finalizar

Não marcar Criar classe principal

2. Criação do banco de dados agendadb no phpMyAdmin:


3. Criação da tabela contato.sql  no phpMyAdmin

3.1. Estrutura da tabela contato


Observação:
O campo id é AUTO_INCREMENT, por conta disso, no comando INSERT do SQL não será especificado este campo, caso não seja configurado dessa forma, é necessário inserí-lo no comando INSERT do método adiciona do arquivo ContatoDao, caso contrário será gerado um erro.

3.2. Visualização da tabela contatos


4. Apresentação do projeto já feito

A figura abaixo mostra o projeto em execução, percebe-se a divisão da estrutura em pacotes, o pacote execute possuia classe Main que executa o projeto inserindo dados na tabela contato, porém, o projeto de fato é executado pela classe JTAgendaContatos.

5. criar o pacote conexao e dentro dele a classe CriaConexao:

CriaConexão.java

package conexao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class CriaConexao {

    public static Connection getConexao() throws SQLException {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            System.out.println("Conectando ao banco");
            return DriverManager.getConnection("jdbc:mysql://localhost:3306/agendadb", "root", "");
        } catch (ClassNotFoundException e) {
            throw new SQLException(e.getMessage());
        }
    }
}

Foi criado o método getConexao do tipo Connection, getConexao faz o registro do drive e retorna o método DriverManager.getConnection que por sua vez faz a conexão propriamente dita.


6. Criar o pacote dao e dentro dele a classe ContatoDao:

ContatoDao.java

package dao;

import conexao.CriaConexao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JTable;

import logica.Contato;

public class ContatoDao {

    private Connection conexao;

    public ContatoDao() throws SQLException {
        this.conexao = CriaConexao.getConexao();

    }

    public void adiciona(Contato c1) throws SQLException {
        String sql = "insert into contato(nome,endereco,telefone,email,sexo)"
                + "values(?,?,?,?,?)";
        try (PreparedStatement stmt = conexao.prepareStatement(sql)) {
            //seta os valores
            stmt.setString(1, c1.getNome());
            stmt.setString(2, c1.getEndereco());
            stmt.setString(3, c1.getTel());
            stmt.setString(4, c1.getEmail());
            stmt.setString(5, c1.getSexo());
            //executa o código
            stmt.execute();
            stmt.close();
        }

    }

    public List<Contato> getLista(String nome) throws SQLException {
        String sql = "select * from contato where nome like ?"; //esta variavel, -sql-, é outra, esta em um novo bloco, novo escopo
        PreparedStatement stmt = this.conexao.prepareStatement(sql);
        stmt.setString(1, nome);

        ResultSet rs = stmt.executeQuery();/*
         * rs vai receber todos os meus contados que esta a cima, porém os que
         * foram mandados com os parametro da atual conexão, que é o ?, que significa
          * um nome a ser entrado para pesquisa
         */

        List<Contato> minhaLista = new ArrayList<Contato>();

        while (rs.next()) {
            Contato c1 = new Contato();
            c1.setId(Long.valueOf(rs.getString("Id")));
            c1.setNome(rs.getString("nome"));
            c1.setEndereco(rs.getString("endereco"));
            c1.setTel(rs.getString("telefone"));
            // c1.setEmail(rs.getString("email"));
            //c1.setSexo(rs.getString("sexo"));
            //c1.setId(rs.getLong("id"));
            minhaLista.add(c1);
        }
        rs.close();
        stmt.close();
        return minhaLista;
    }

    public void altera(Contato c1) throws SQLException {
        String sql = "update contato set nome=?," + " endereco=?, telefone=?, email=?" + ",sexo=? where id=?";
        PreparedStatement stmt = conexao.prepareStatement(sql);
        //seta os valores
        stmt.setString(1, c1.getNome());
        stmt.setString(2, c1.getEndereco());
        stmt.setString(3, c1.getTel());
        stmt.setString(4, c1.getEmail());
        stmt.setString(5, c1.getSexo());
        stmt.setLong(6, c1.getId());
        // executa o código sql
        stmt.execute();
        stmt.close();

    }

    public void remove(Contato c1) throws SQLException { // implementação do método -remove-
        String sql = "delete from contato where id=?";
        PreparedStatement stmt = conexao.prepareStatement(sql);
        stmt.setLong(1, c1.getId());
        stmt.execute();
        stmt.close();


    }
}


6.1. o construtor ContatoDao() atribui a this.conexao a chamada do método CriaConexao.getConexao(), a partir desta chamada, a conexão está estabelecida;

6.2. o método adiciona ao ser executado irá executar o comando INSERT que adicionará os respectivos valores aos campos da tabela contato;

6.3. em seguida será feito a preparação do banco de dados através do método prepareStatement(sql) para a inserção de dados;

6.4. os métodos setString irão atribuir aos valores do comado INSERT os atributos da classe contato, correspondento os índices de 1 a 5 aos valores seqüênciais do comando INSERT values(?,?,?,?,?), ou seja, values(1,2,3,4,5).

6.5. o método getLista() é do tipo List, que por sua vez tem elementos do tipo da classe Contato;

6.5.1. repara que "SELECT * from contato where nome like ?", seleciona os campos pertencente a nome que forem iguais a ?, istó é, uma valor a ser entrado ainda;

6.5.2.stmt= this.conexao.prepareStatement(sql) fará a conexão, stmt.setString(1, nome) atribuirá o valor nome.


7. Criar o pacote executa e dentro dele a classe Main:

Main.java


import dao.ContatoDao;
import java.sql.SQLException;
import logica.Contato;

public class Main {

    public static void main(String[] args) throws SQLException {
        Contato c1 = new Contato();
        c1.setNome("Nome de alguém");
        c1.setEndereco("Endereço de Alguem");
        c1.setTel("0000-0000");
        c1.setEmail("Alguém@bol.com.br");
        c1.setSexo("M");

        ContatoDao dao = new ContatoDao();
        dao.adiciona(c1);
        System.out.println("Adicionado no banco");
    }
}

A classe Main foi criada para teste, o objeto c1 do tipo Contato atribui diretamente os valores digitado entre parentesis ao atributos de classe;

O objeto dao do tipo ContatoDao, faz a conexão com o banco de dados e atribui aos campos da tabela contato os atributos do objeto c1.

8. Criar o pacote logica e dentro dele a classe Contato:

Contato.java

package logica;

public class Contato {

    private Long id;
    private String nome;
    private String endereco;
    private String tel;
    private String email;
    private String sexo;

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getEndereco() {
        return endereco;
    }

    public void setEndereco(String endereco) {
        this.endereco = endereco;
    }

    public Long getId() {
        return id;
    }

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

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getSexo() {
        return sexo;
    }

    public void setSexo(String sexo) {
        this.sexo = sexo;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }
}

A classe Contato é um espelho da tabela, com isso, é possível manipular os dados da tabela com essa classe.

9. Criar o pacote form e dentro dele a classe JTAgentaContatos:

JTAgentaContatos.java

1    /*
2     * To change this template, choose Tools | Templates
3     * and open the template in the editor.
4     */
5    package form;
6   
7    import java.sql.SQLException;
8    import java.util.List;
9    import javax.swing.JOptionPane;
10    import javax.swing.JTable;
11    import javax.swing.ListSelectionModel;
12    import javax.swing.event.ListSelectionEvent;
13    import javax.swing.event.ListSelectionListener;
14    import javax.swing.table.DefaultTableModel;
15    import dao.ContatoDao;
16    import logica.Contato;
17       
18    /**
19     *
20     * @author Adm
21     */
22    public class JTAgendaContatos extends javax.swing.JFrame {
23   
24        DefaultTableModel tmContato = new DefaultTableModel(null, new String[]{"Id",   "Nome", "Endereco", "Tel"});
25        List<Contato> contatos; //é uma lista do tipo Contato????
26        ListSelectionModel lsmContato;
27   
28        /**
29         * Creates new form jTAgendaContatos
30         */
31        public JTAgendaContatos() {
32            initComponents();
33            desabilitaDados();
34        }
35   
36        /**
37         * This method is called from within the constructor to initialize the form.
38         * WARNING: Do NOT modify this code. The content of this method is always
39         * regenerated by the Form Editor.
40         */
41        // <editor-fold defaultstate="collapsed" desc="Generated Code">                         
42        private void initComponents() {
43   
44            jPanel1 = new javax.swing.JPanel();
45            jLId = new javax.swing.JLabel();
46            jLNome = new javax.swing.JLabel();
47            jLEndereco = new javax.swing.JLabel();
48            jLTelefone = new javax.swing.JLabel();
49            jLEmail = new javax.swing.JLabel();
50            jLSexo = new javax.swing.JLabel();
51            jTId = new javax.swing.JTextField();
52            jTNome = new javax.swing.JTextField();
53            jTEndereco = new javax.swing.JTextField();
54            matriculaTxt = new javax.swing.JTextField();
55            nota1Txt = new javax.swing.JTextField();
56            nota2Txt = new javax.swing.JTextField();
57            jBPesquisa = new javax.swing.JButton();
58            jTPesquisar = new javax.swing.JTextField();
59            jScrollPane3 = new javax.swing.JScrollPane();
60            jTTabela = new javax.swing.JTable();
61            panel1 = new java.awt.Panel();
62            jBNovo = new javax.swing.JButton();
63            jBAlterar = new javax.swing.JButton();
64            jBExcluir = new javax.swing.JButton();
65            jBSalvar = new javax.swing.JButton();
66            jBSair = new javax.swing.JButton();
67   
68            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
69   
70            jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Dados do contato"));
71            jPanel1.setName("jTSexo");
72   
73            jLId.setText("aluno_id");
74   
75            jLNome.setText("Nome: *");
76   
77            jLEndereco.setText("Endereço *");
78   
79            jLTelefone.setText("Telefone");
80   
81            jLEmail.setText("email");
82   
83            jLSexo.setText("Sexo");
84   
85            jTId.setName("jTId");
86   
87            jTNome.setName("jTNome");
88   
89            jTEndereco.setName("jTEndereco");
90            jTEndereco.addActionListener(new java.awt.event.ActionListener() {
91                public void actionPerformed(java.awt.event.ActionEvent evt) {
92                    jTEnderecoActionPerformed(evt);
93                }
94            });
95   
96            matriculaTxt.setName("matriculaTxt");
97   
98            nota1Txt.setName("nota1Txt");
99   
100            javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
101            jPanel1.setLayout(jPanel1Layout);
102            jPanel1Layout.setHorizontalGroup(
103                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
104                .addGroup(jPanel1Layout.createSequentialGroup()
105                    .addContainerGap()
106                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
107                        .addGroup(jPanel1Layout.createSequentialGroup()
108                          .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
109                                .addComponent(jLNome, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
110                                .addComponent(jLId, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
111                            .addGap(19, 19, 19)
112                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
113                                .addComponent(jTNome, javax.swing.GroupLayout.PREFERRED_SIZE, 212, javax.swing.GroupLayout.PREFERRED_SIZE)
114                                .addComponent(jTId, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE)))
115                        .addGroup(jPanel1Layout.createSequentialGroup()
116                            .addComponent(jLEndereco)
117                            .addGap(5, 5, 5)
118                            .addComponent(jTEndereco, javax.swing.GroupLayout.PREFERRED_SIZE, 212, javax.swing.GroupLayout.PREFERRED_SIZE)))
119                    .addGap(18, 18, 18)
120                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
121                        .addComponent(jLTelefone)
122                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
123                            .addComponent(jLEmail, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
124                            .addComponent(jLSexo, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
125                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
126                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
127                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
128                            .addComponent(nota1Txt, javax.swing.GroupLayout.DEFAULT_SIZE, 212, Short.MAX_VALUE)
129                            .addComponent(matriculaTxt))
130                        .addComponent(nota2Txt, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE))
131                    .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
132            );
133            jPanel1Layout.setVerticalGroup(
134                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
135                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
136                    .addContainerGap(23, Short.MAX_VALUE)
137                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
138                        .addGroup(jPanel1Layout.createSequentialGroup()
139                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
140                                .addComponent(jLTelefone)
141                                .addComponent(matriculaTxt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
142                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
143                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
144                                .addComponent(jLEmail)
145                                .addComponent(nota1Txt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
146                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
147                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
148                                .addComponent(jLSexo)
149                                .addComponent(nota2Txt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
150                        .addGroup(jPanel1Layout.createSequentialGroup()
151                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
152                                .addComponent(jLId)
153                                .addComponent(jTId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
154                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
155                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
156                                .addComponent(jLNome)
157                                .addComponent(jTNome, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
158                            .addGap(11, 11, 11)
159                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
160                                .addComponent(jLEndereco)
161                                .addComponent(jTEndereco, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
162                    .addGap(86, 86, 86))
163            );
164   
165            jBPesquisa.setText("Pesquisar");
166            jBPesquisa.addActionListener(new java.awt.event.ActionListener() {
167                public void actionPerformed(java.awt.event.ActionEvent evt) {
168                    jBPesquisaActionPerformed(evt);
169                }
170            });
171   
172            jScrollPane3.setName("jTTabela");
173   
174            jTTabela.setModel(tmContato);
175            jTTabela.setName("Tabela");
176            jTTabela.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
177            lsmContato=jTTabela.getSelectionModel();
178            lsmContato.addListSelectionListener(new ListSelectionListener(){
179                public void valueChanged(ListSelectionEvent e){
180                    if (! e.getValueIsAdjusting ()) {
181                        jTTabelaLinhaSelecionada(jTTabela);
182                    }
183                }
184            });
185            jScrollPane3.setViewportView(jTTabela);
186   
187            panel1.setBackground(new java.awt.Color(240, 240, 240));
188   
189            jBNovo.setText("Novo");
190            jBNovo.setName("jBNovo");
191            jBNovo.addActionListener(new java.awt.event.ActionListener() {
192                public void actionPerformed(java.awt.event.ActionEvent evt) {
193                    jBNovoActionPerformed(evt);
194                }
195            });
196   
197            jBAlterar.setText("Alterar");
198            jBAlterar.setName("jBAlterar");
199            jBAlterar.addActionListener(new java.awt.event.ActionListener() {
200                public void actionPerformed(java.awt.event.ActionEvent evt) {
201                    jBAlterarActionPerformed(evt);
202                }
203            });
204   
205            jBExcluir.setText("Excluir");
206            jBExcluir.addActionListener(new java.awt.event.ActionListener() {
207                public void actionPerformed(java.awt.event.ActionEvent evt) {
208                    jBExcluirActionPerformed(evt);
209                }
210            });
211   
212            jBSalvar.setText("Salvar");
213            jBSalvar.addActionListener(new java.awt.event.ActionListener() {
214                public void actionPerformed(java.awt.event.ActionEvent evt) {
215                    jBSalvarActionPerformed(evt);
216                }
217            });
218   
219            jBSair.setText("Sair");
220   
221            javax.swing.GroupLayout panel1Layout = new javax.swing.GroupLayout(panel1);
222            panel1.setLayout(panel1Layout);
223            panel1Layout.setHorizontalGroup(
224                panel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
225                .addGroup(panel1Layout.createSequentialGroup()
226                    .addContainerGap()
227                    .addComponent(jBNovo)
228                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
229                    .addComponent(jBAlterar)
230                    .addGap(18, 18, 18)
231                    .addComponent(jBExcluir)
232                    .addGap(43, 43, 43)
233                    .addComponent(jBSalvar)
234                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
235                    .addComponent(jBSair)
236                    .addContainerGap(24, Short.MAX_VALUE))
237            );
238   
239            panel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jBAlterar, jBExcluir, jBNovo, jBSair, jBSalvar});
240   
241            panel1Layout.setVerticalGroup(
242                panel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
243                .addGroup(panel1Layout.createSequentialGroup()
244                    .addContainerGap()
245                    .addGroup(panel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
246                        .addComponent(jBNovo)
247                        .addComponent(jBAlterar)
248                        .addComponent(jBExcluir)
249                        .addComponent(jBSalvar)
250                        .addComponent(jBSair))
251                    .addContainerGap(21, Short.MAX_VALUE))
252            );
253   
254            panel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {jBAlterar, jBExcluir, jBNovo, jBSair, jBSalvar});
255   
256            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
257            getContentPane().setLayout(layout);
258            layout.setHorizontalGroup(
259                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
260                .addGroup(layout.createSequentialGroup()
261                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
262                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
263                            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
264                            .addComponent(jTPesquisar, javax.swing.GroupLayout.PREFERRED_SIZE, 203, javax.swing.GroupLayout.PREFERRED_SIZE)
265                            .addGap(32, 32, 32)
266                            .addComponent(jBPesquisa))
267                        .addGroup(layout.createSequentialGroup()
268                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
269                                .addGroup(layout.createSequentialGroup()
270                                    .addContainerGap()
271                                    .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 574, javax.swing.GroupLayout.PREFERRED_SIZE))
272                                .addGroup(layout.createSequentialGroup()
273                                    .addGap(20, 20, 20)
274                                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
275                            .addGap(0, 4, Short.MAX_VALUE)))
276                    .addContainerGap())
277                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
278                    .addGap(0, 0, Short.MAX_VALUE)
279                    .addComponent(panel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
280                    .addGap(95, 95, 95))
281            );
282            layout.setVerticalGroup(
283                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
284                .addGroup(layout.createSequentialGroup()
285                    .addGap(20, 20, 20)
286                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
287                        .addComponent(jBPesquisa)
288                        .addComponent(jTPesquisar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
289                    .addGap(30, 30, 30)
290                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
291                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
292                    .addComponent(panel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
293                    .addGap(26, 26, 26)
294                    .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 169, javax.swing.GroupLayout.PREFERRED_SIZE)
295                    .addContainerGap(206, Short.MAX_VALUE))
296            );
297   
298            pack();
299        }// </editor-fold>                       
300   
301        private void jTEnderecoActionPerformed(java.awt.event.ActionEvent evt) {                                          
302            // TODO add your handling code here:
303        }                                         
304   
305        private void jBAlterarActionPerformed(java.awt.event.ActionEvent evt) {                                         
306            try {
307                alteraContato();
308                listarContato();
309   
310   
311                // TODO add your handling code here:
312            } catch (SQLException ex) {
313                JOptionPane.showMessageDialog(null, "Problema no jBAlterar");
314            }
315        }                                        
316   
317        private void jBNovoActionPerformed(java.awt.event.ActionEvent evt) {                                      
318            // TODO add your handling code here:
319            habilitaDados();
320            jTNome.setText("");
321            nota1Txt.setText("");
322            jTEndereco.setText("");
323            matriculaTxt.setText("");
324            nota2Txt.setText("");
325   
326   
327        }                                     
328   
329        public void desabilitaDados() {
330            jTId.setEditable(false);
331            jTNome.setEditable(false);
332            jTEndereco.setEditable(false);
333            matriculaTxt.setEditable(false);
334            nota1Txt.setEditable(false);
335            nota2Txt.setEditable(false);
336   
337        }
338   
339        public void habilitaDados() {
340            jTNome.setEditable(true);
341            jTEndereco.setEditable(true);
342            matriculaTxt.setEditable(true);
343            nota1Txt.setEditable(true);
344            nota2Txt.setEditable(true);
345   
346        }
347   
348        public boolean verificaDados() {
349            if (!jTNome.getText().equals("") && !jTEndereco.getText().equals("")) {
350                return true;
351            } else {
352                JOptionPane.showMessageDialog(null, "Campos Nome ou Edereço não preenchidos");
353            }
354            return false;
355        }
356   
357        private void jBSalvarActionPerformed(java.awt.event.ActionEvent evt) {                                        
358            if (verificaDados()) {
359                cadastro();
360                desabilitaDados();
361            }
362   
363   
364        }                                       
365   
366        private void jBPesquisaActionPerformed(java.awt.event.ActionEvent evt) {                                          
367            try {
368                listarContato();
369            } catch (SQLException ex) {
370                JOptionPane.showMessageDialog(null, "Erro na Pesquisa!");
371            }
372        }                                         
373   
374        private void jBExcluirActionPerformed(java.awt.event.ActionEvent evt) {                                         
375            try {
376                excluirContato();
377                mostraPesquisa(contatos);
378            } catch (SQLException ex) {
379                JOptionPane.showMessageDialog(null, "Erro no botão excluir!");
380            }
381   
382        }                                        
383   
384        public void excluirContato() throws SQLException {
385   
386            int resp = JOptionPane.showConfirmDialog(this, "Tem certeza da exclusão!", "confirmação", JOptionPane.YES_NO_OPTION);
387            if (resp == JOptionPane.YES_NO_OPTION) {
388                ContatoDao dao = new ContatoDao();
389                dao.remove(contatos.get(jTTabela.getSelectedRow()));
390                mostraPesquisa(contatos);
391   
392            }
393   
394        }
395   
396        public void listarContato() throws SQLException {
397            ContatoDao dao = new ContatoDao();
398            contatos = dao.getLista("%" + jTPesquisar.getText() + "%");
399            mostraPesquisa(contatos);
400        }
401   
402        private void mostraPesquisa(List<Contato> contatos) {
403            while (tmContato.getRowCount() > 0) {//para zera a pesquisa anterior
404                tmContato.removeRow(0);
405            }
406            if (contatos.size() == 0) {
407                JOptionPane.showMessageDialog(null, "Nenhum contato cadastrado");
408            } else {
409                String[] linha = new String[]{null, null, null, null};
410                for (int i = 0; i < contatos.size(); i++) {
411                    tmContato.addRow(linha);
412                    tmContato.setValueAt(contatos.get(i).getId(), i, 0);
413                    tmContato.setValueAt(contatos.get(i).getNome(), i, 1);
414                    tmContato.setValueAt(contatos.get(i).getEndereco(), i, 2);
415                    tmContato.setValueAt(contatos.get(i).getTel(), i, 3);
416                }
417            }
418        }
419   
420        public static void main(String args[]) {
421   
422            java.awt.EventQueue.invokeLater(new Runnable() {
423   
424                public void run() {
425                    new JTAgendaContatos().setVisible(true);
426                }
427            });
428        }
429        // Variables declaration - do not modify                    
430        private javax.swing.JButton jBAlterar;
431        private javax.swing.JButton jBExcluir;
432        private javax.swing.JButton jBNovo;
433        private javax.swing.JButton jBPesquisa;
434        private javax.swing.JButton jBSair;
435        private javax.swing.JButton jBSalvar;
436        private javax.swing.JLabel jLEmail;
437        private javax.swing.JLabel jLEndereco;
438        private javax.swing.JLabel jLId;
439        private javax.swing.JLabel jLNome;
440        private javax.swing.JLabel jLSexo;
441        private javax.swing.JLabel jLTelefone;
442        private javax.swing.JPanel jPanel1;
443        private javax.swing.JScrollPane jScrollPane3;
444        private javax.swing.JTextField jTEndereco;
445        private javax.swing.JTextField jTId;
446        private javax.swing.JTextField jTNome;
447        private javax.swing.JTextField jTPesquisar;
448        private javax.swing.JTable jTTabela;
449        private javax.swing.JTextField matriculaTxt;
450        private javax.swing.JTextField nota1Txt;
451        private javax.swing.JTextField nota2Txt;
452        private java.awt.Panel panel1;
453        // End of variables declaration                  
454   
455        private void cadastro() {
456            try {
457                // TODO add your handling code here:
458                Contato c1 = new Contato();
459                c1.setNome(jTNome.getText());
460                c1.setTel(matriculaTxt.getText());
461                c1.setEndereco(jTEndereco.getText());
462                c1.setEmail(nota1Txt.getText());
463                c1.setSexo(nota2Txt.getText());
464   
465                ContatoDao dao = new ContatoDao();
466                dao.adiciona(c1);
467            } catch (SQLException ex) {
468                JOptionPane.showMessageDialog(null, "Não adicionou");
469            }
470        }
471   
472        private void jTTabelaLinhaSelecionada(JTable tabela) {
473            if (jTTabela.getSelectedRow() != -1) {
474                habilitaDados();
475                jTId.setText(String.valueOf(contatos.get(tabela.getSelectedRow()).getId()));
476                jTNome.setText(contatos.get(tabela.getSelectedRow()).getNome());
477                jTEndereco.setText(contatos.get(tabela.getSelectedRow()).getEndereco());
478                nota1Txt.setText(contatos.get(tabela.getSelectedRow()).getEmail());
479                matriculaTxt.setText(contatos.get(tabela.getSelectedRow()).getTel());
480            } else {
481                jTId.setText("");
482                jTNome.setText("");
483                matriculaTxt.setText("");
484                nota1Txt.setText("");
485                jTEndereco.setText("");
486                nota2Txt.setText("");
487   
488            }
489        }
490   
491        private void alteraContato() throws SQLException {
492            if (jTTabela.getSelectedRow() != -1) {
493                if (verificaDados()) {
494                    Contato c1 = new Contato();
495                    ContatoDao dao = new ContatoDao();
496                    c1.setId(Long.valueOf(jTId.getText()));
497                    c1.setNome(jTNome.getText());
498                    c1.setEndereco(jTEndereco.getText());
499                    c1.setTel(matriculaTxt.getText());
500                    c1.setEmail(nota1Txt.getText());
501                    c1.setSexo(nota2Txt.getText());
502                    dao.altera(c1);
503                }
504                JOptionPane.showMessageDialog(null, "Contato alterado!");
505            }
506        }
507    }



- linha 22: public class JTAgendaContatos extends javax.swing.JFrame {
Corresponde ao formulário JFrame de nome JTAgendaContatos, é o primeiro componente a ser criado, todo os outro componentes são incluídos nele, um JFrame é uma classe com um método main;

- A figura de apresentação do projeto já mostra a execução do projeto.