Estudo de Caso
Objetivo
Esperamos que, ao final desta aula, você seja capaz de:
utilizar todos os conceitos aprendidos durante toda a disciplina. •
Pré-requisitos
Para esta aula é necessário que os conceitos apresentados no decorrer desta disciplina tenham sido assimilados, e que estejam muito claro o con- ceito e orientação a objetos que foi visto na disciplina de Programação anterior: eles serão utilizados na construção do estudo de caso, visando a demonstrar que são de fundamental importância, para construção de aplicações por um programador Java.
introdução
Iremos, agora, criar um estudo de caso, no qual utilizaremos todos os con- ceitos apresentados em nossas aulas, relacionados ao processo de construção de aplicações visuais com a linguagem Java, utilizando um banco de dados, criando, assim, uma pequena aplicação.
7.1 Definição do problema
Como estamos no final de nossa disciplina, iremos agora utilizar todos os conceitos apresentados, bem como relembrar outros que nos foram colocados na aula passada. Para tanto, vamos criar uma aplicação que interage com um banco de dados. Então vamos ao que interessa.
Nosso estudo de caso consiste na criação de uma pequena aplicação para cadastro de cursos de uma universidade. Assim, utilizaremos a estrutura de banco de dados criada na aula 6, na construção de relatórios. Para isso, devemos definir uma tela inicial com um menu, no qual deverá ser oferecida a possibilidade de abrir a tela de cadastro ou mesmo sair. A tela de cadastro deve possibilitar que diversos cursos sejam acrescentados, com nome e descri- ção. Além disso, iremos acionar um relatório através de nossa aplicação.
7.2 implementação do estudo de caso
Iniciaremos nosso estudo de caso criando uma classe que deriva da classe Frame, no caso, será criada uma janela na qual iremos definir através de seu mé- todo construtor o tamanho e a localização da tela. Além disso, também definire- mos o método executável, então, transcreva o código a seguir, salve-o e execute.
Note que, em nosso método executável instanciamos um objeto da classe que estamos construindo. Dessa forma, conseguimos visualizar os resultados de nossa aplicação. Prosseguindo com nosso exemplo, defina, no mesmo ar- quivo, uma nova classe que será responsável por definir as funcionalidades da janela, que serão acionados com os eventos sobre esta, no caso o listener.
//AppCadastro.java import java.awt.Frame;
public class AppCadastro extends Frame{
//método construtor public AppCadastro(){ super(“Aplicação de cadastro”); setSize(600, 600); setLocation(200, 100); } //método executável
public static void main(String[] args) {
AppCadastro exec = new AppCadastro(); exec.setVisible(true);
} }
Verifique que apenas foram adicionados um import e a nova classe, ao final da apresentada no exemplo anterior. Note que, ao invés de implemen- tarmos a interface WindowListener, fazendo com que obrigatoriamente tivés- semos de declarar sete métodos, derivamos da classe WindowAdapter, sendo que é declarado apenas o método que utilizaremos. Porém, é necessário que este evento seja associado à janela, para tanto, acrescente o próximo código ao método construtor. Neste, instanciamos, um listener, no caso um escutador que é o responsável por reagir à interação dos usuários com a janela.
Vamos agora definir nosso menu, sendo que neste definiremos dois itens, para que sejam executadas as funcionalidades de acionar a tela de cadastro e sair. Assim, como nos exemplos anteriores, transcreva as linhas de código a seguir no método construtor.
//AppCadastro.java import java.awt.*; import java.awt.event.*;
public class AppCadastro extends Frame{
... }
class EvtJanela extends WindowAdapter{
public void windowClosing(WindowEvent e){
System.exit(0); }
}
...
public class AppCadastro extends Frame{
//método construtor
public AppCadastro(){ ...
EvtJanela evt = new EvtJanela(); addWindowListener(evt); } ... } ... ...
public class AppCadastro extends Frame{
//método construtor
public AppCadastro(){
...
MenuBar barraMenu = new MenuBar(); Menu menuArquivo = new Menu(“Arquivo”);
MenuItem itemCadastro = new MenuItem(“Cadastro de Curso”); MenuItem itemSair = new MenuItem(“Sair”);
menuArquivo.add(itemCadastro); menuArquivo.add(itemSair); barraMenu.add(menuArquivo); setMenuBar(barraMenu); } ... }
Agora, precisamos definir o listener de nosso menu. Para tanto, devemos mencionar que nossa classe AppCadastro implementa a interface ActionListe- ner e, com isso nos obriga a também implementar o método ActionPerformed. Então vamos a eles.
Continuamos nosso estudo de caso definindo os containers de componen- tes de nossa aplicação. Então vamos criar três painéis que serão nossas telas, sendo que utilizaremos o gerenciador de layout CardLayout, para assim, ter- mos o efeito de novas janelas que serão trabalhadas.
...
public class AppCadastro extends Frame implements ActionListener{
//método construtor public AppCadastro(){ ... itemCadastro.addActionListener(this); itemSair.addActionListener(this); } ...
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof MenuItem) {
MenuItem item = (MenuItem) e.getSource(); if(item.getLabel().equals(“Sair”)){ System.exit(0); } if(item.getLabel().equals(“Novo de Curso”)){ } } } } ... ...
public class AppCadastro extends Frame implements ActionListener{
Panel geral;
//método construtor
public AppCadastro(){ ...
Panel painelApp = new Panel(); Panel painelCadastro = new Panel();
painelApp.setBackground(SystemColor.control); painelCadastro.setBackground(SystemColor.control); geral = new Panel();
geral.add(painelApp,”J1”); geral.add(painelCadastro,”J2”); geral.setLayout(new CardLayout()); add(“Center”,geral); } ...
public void actionPerformed(ActionEvent e) {
...
if(item.getLabel().equals(“Novo de Curso”)){
CardLayout pilha = (CardLayout) geral.getLayout(); pilha.next(geral); } … } } ...
Criamos três painéis sendo que um consiste no mestre, denominado geral, por meio do qual conseguimos acessar os demais, criando como menciona- do o aspecto de janelas. O componente painelCadastro consiste em nosso container que possuirá todos os demais campos, no caso outros componentes para nosso cadastro. Então, ao final o método construtor adicione as linhas de código a seguir descritas.
Pensando sobre o assunto
O efeito de janelas criado pela utilização de painéis é muito útil para a construção de aplicações visuais. Porém, podem ser instanciadas diversas classes que derivam da classe Frame, e realizando assim a chamada, através do método setVisible(). Deve-se, antes de invocar novas janelas, informar que a janela que está realizando a chamada não é mais a janela ativa, isso com a utilização do método setEnable().
...
import javax.swing.*;
...
public class AppCadastro extends Frame{
...
TextField nome = new TextField(71); TextField descricao = new TextField(68); Button salvar = new Button(“Salvar”); Button limpar = new Button(“Limpar”); Button report = new Button(“Relatório”); Button sair = new Button(“Sair”); Label result = new Label();
//método construtor public AppCadastro(){ ... painelCadastro.setLayout(new FlowLayout()); painelCadastro.add(new Label(“Nome:”)); painelCadastro.add(nome); painelCadastro.add(new Label(“Descrição:”)); painelCadastro.add(descricao);
String[] colunas = {“NOME”, “DESCRIÇÃO”}; Object[][] conteudo = {{“”, “”}};
JTable tabela = new JTable(10,2);
tabela.setPreferredScrollableViewportSize(new Dimension(560, 120)); painelCadastro.add(new JScrollPane(tabela));
Panel painelButton = new Panel(); painelButton.add(salvar); painelButton.add(limpar); painelButton.add(sair); painelButton.add(result); painelCadastro.add(“South”, painelButton); } ... } ...
Com isso, temos nosso layout de nossa aplicação concluído, porém, ainda temos de adicionar as funcionalidades aos eventos que nossos botões reagi- rão. Dessa forma, inicialmente iremos criar nosso método que irá realizar a conexão com o banco de dados, abrindo espaço para que possamos criar outros métodos para inserção de novos elementos.
Note que, em nosso método de conexão, utilizamos o driver jdbc para o banco de dados MySql, porém, adapte a string de conexão para que seu banco de dados, de forma que este seja acessado, possibilitando a inserção e consulta a seu seus dados.
Pensando sobre o assunto
Geralmente é necessário que realizemos o import dos drivers de conexão para um determinado banco de dados. Os SGBDs fornecem estas APIs junto com sua distribuição. Desta forma, consulte o manual de seu banco de dados e verifique o driver para conexão Java. Por exemplo, realizamos o import da classe “com.mysql.jdbc.Connection”.
...
import java.sql.*;
import com.mysql.jdbc.Connection;
...
public class AppCadastro extends Frame implements ActionListener{
...
public void actionPerformed(ActionEvent e) {
... }
public Connection connection() {
Connection connection = null; String con = “jdbc:mysql://localhost:3306/aula07?user=root&password=root”; try { Class.forName(“com.mysql.jdbc.Driver”).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } try {
connection = (Connection) DriverManager.getConnection(con); } catch (SQLException e) { e.printStackTrace(); } return connection; } } ...
Levando a tona todo o conceito de orientação a objetos, criaremos nosso “modelo” de um curso, no caso a classe Curso, com seus atributos e métodos. Note que são disponibilizados os métodos get e set garantindo que os atributos não são acessados diretamente. Então, transcreva a classe Curso para dentro do arquivo.
Nosso próximo passo consiste na criação dos métodos que serão res- ponsáveis por incluir e consultar dados em nosso banco de dados. Com isso, nos restara apenas fazer com que estes métodos sejam acionados por eventos em nossos botões. Assim, transcreva o código abaixo para sua classe e execute-a.
//AppCadastro.java
...
public class AppCadastro extends Frame{
... }
class EvtJanela extends WindowAdapter{
... }
class Curso {
private Integer id = new Integer(0); private String nome = new String(); private String descricao = new String(); private public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) { this.descricao = descricao;
}
public Integer getId() { return id;
}
public void setId(Integer id) { this.id = id;
}
public String getNome() { return nome;
}
public void setNome(String nome) { this.nome = nome;
} }
Nos resta, ainda, gerar nosso relatório, conforme exemplificado na aula 6. Utilizaremos o arquivo jasper desenvolvido nesta aula, e assim temos somente que criar um método que execute a invocação de nosso relatório. Vamos ao que inte- ressa: copie o código a seguir, conforme exemplificado, na classe AppCadastro.
Pensando sobre o assunto
Conforme exemplificado na aula 6, é interessante que seja utilizada uma ferramenta para criação dos relatórios, pois, além de acelerar todo o processo de desenvolvimento, evita um processo trabalhoso manual e, com isso, surpresas na construção dos relatórios.
//AppCadastro.java ... import java.sql.*; import com.mysql.jdbc.Connection; import com.mysql.jdbc.ResultSet; import com.mysql.jdbc.Statement;
public class AppCadastro extends Frame{
...
Curso c = new Curso(); ...
public void incluir(){ try {
Statement statement = connection().createStatement(); String sql = “Insert into Curso VALUES
(null, \’”+c.getNome()+
“\’, \’”+c.getDescricao()+”\’)”; statement.executeUpdate(sql);
result.setText(“CURSO INSERIDO COM SUCESSO!”); } catch (SQLException e) {
e.printStackTrace();
result.setText(“OCORRERAM ERROS NA INSEÇÃO!”); }
}
public ResultSet consultar(){
ResultSet resultadoBanco = null;
String consulta = “Select * from Curso”;
try {
PreparedStatement comandoBanco =
connection().prepareStatement(consulta); resultadoBanco = comandoBanco.executeQuery(); connection().close();
} catch (Exception Erro) {
result.setText(“OCORRERAM ERROS NA CONSULTA!”); }
return resultadoBanco;
}
public void limpar(){
nome.setText(“”); descricao.setText(“”); }
...
import java.io.*;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.export.*; import net.sf.jasperreports.view.*;
public class AppCadastro extends Frame implements ActionListener{
Panel geral; //método construtor public AppCadastro(){ ... } ...
public void actionPerformed(ActionEvent e) {
... }
public void gerarReport() {
try {
Connection con = connection();
Statement stm = (Statement) con.createStatement(); String query = “Select * from Curso”;
ResultSet rs = (ResultSet) stm.executeQuery(query); JRResultSetDataSource jrRS = new JRResultSetDataSource(rs); JRExporter jrpdf = new JRPdfExporter();
JasperPrint print; OutputStream fos = null;
print = JasperFillManager.fillReport(“.\\reports\\Curso.jasper”, null, jrRS);
fos = new FileOutputStream(“.\\reports\\Curso.pdf”); jrpdf.setParameter(JRExporterParameter.OUTPUT_STREAM, fos); jrpdf.setParameter(JRExporterParameter.JASPER_PRINT, print); jrpdf.exportReport(); fos.close(); JasperViewer.viewReport(print); } catch (IOException e) { e.printStackTrace(); } catch (JRException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } ...
Para que nosso código funcione, certifique-se que o arquivo Curso. jasper está no “report” dentro do diretório em que nossa classe AppCa- dastro está. Como mencionado, iremos fazer com que nossos botões, as- sim que acionados, executem nossos métodos, e apresentem os resultados na tabela. Então, assim como nos exemplos, copie o código e verifique o resultado.
Chegamos ao fim de nosso estudo de caso. No quadro a seguir, é apre- sentado todo o código de nossa classe, auxiliando numa visão mais macro do exemplo apresentado. AppCadastro.java //AppCadastro.java import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; import java.sql.*; import net.sf.jasperreports.engine.*; import net.sf.jasperreports.engine.export.*; import net.sf.jasperreports.view.*; import com.mysql.jdbc.Connection; import com.mysql.jdbc.ResultSet; import com.mysql.jdbc.Statement; ...
public class AppCadastro extends Frame implements ActionListener{
Panel geral; //método construtor public AppCadastro(){ ... salvar.addActionListener(this); limpar.addActionListener(this); report.addActionListener(this); sair.addActionListener(this); } ...
public void actionPerformed(ActionEvent e) {
... if(e.getSource()==salvar){ c.setNome(nome.getText()); c.setDescricao(descricao.getText()); incluir(); limpar(); } if(e.getSource()==limpar){ limpar(); } if(e.getSource()==report){ gerarReport(); } if(e.getSource()==sair){ System.exit(0); } } } ...
public class AppCadastro extends Frame implements ActionListener{ TextField nome = new TextField(71);
TextField descricao = new TextField(68); Button salvar = new Button(“Salvar”); Button limpar = new Button(“Limpar”); Button report = new Button(“Relatório”); Button sair = new Button(“Sair”);
Panel geral;
Curso c = new Curso(); Label result = new Label(); public AppCadastro(){
super(“Aplicação de cadastro”); setSize(600, 285);
setLocation(200, 100);
EvtJanela evt = new EvtJanela(); addWindowListener(evt);
MenuBar barraMenu = new MenuBar(); Menu menuArquivo = new Menu(“Arquivo”);
MenuItem itemCadastro = new MenuItem(“Novo de Curso”); MenuItem itemSair =
new MenuItem(“Sair”, new MenuShortcut(KeyEvent.VK_R)); menuArquivo.add(itemCadastro); menuArquivo.add(itemSair); barraMenu.add(menuArquivo); setMenuBar(barraMenu); itemCadastro.addActionListener(this); itemSair.addActionListener(this); Panel painelApp = new Panel(); Panel painelCadastro = new Panel();
painelApp.setBackground(SystemColor.control); painelCadastro.setBackground(SystemColor.control); geral = new Panel();
geral.add(painelApp,”J1”); geral.add(painelCadastro,”J2”); geral.setLayout(new CardLayout()); add(“Center”,geral); painelCadastro.setLayout(new FlowLayout()); painelCadastro.add(new Label(“Nome:”)); painelCadastro.add(nome); painelCadastro.add(new Label(“Descrição:”)); painelCadastro.add(descricao);
String[] colunas = {“NOME”, “DESCRIÇÃO”}; Object[][] conteudo = {{“”, “”}};
JTable tabela = new JTable(conteudo, colunas);
tabela.setPreferredScrollableViewportSize(new Dimension(560,120)); painelCadastro.add(new JScrollPane(tabela));
Panel painelButton = new Panel(); painelButton.add(salvar); painelButton.add(limpar); painelButton.add(report); painelButton.add(sair); painelButton.add(result); painelCadastro.add(“South”, painelButton); salvar.addActionListener(this); limpar.addActionListener(this); report.addActionListener(this); sair.addActionListener(this);
public static void main(String[] args) { AppCadastro exec = new AppCadastro(); exec.setVisible(true);
}
public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof MenuItem) {
MenuItem item = (MenuItem) e.getSource(); if(item.getLabel().equals(“Sair”)){
System.exit(0); }
if(item.getLabel().equals(“Novo de Curso”)){ CardLayout pilha = CardLayout) geral.getLayout(); pilha.next(geral); } } if(e.getSource()==salvar){ c.setNome(nome.getText()); c.setDescricao(descricao.getText()); incluir(); limpar(); } if(e.getSource()==limpar){ limpar(); } if(e.getSource()==report){ gerarReport(); } if(e.getSource()==sair){ System.exit(0); } }
public void gerarReport() { try {
Connection con = connection();
Statement stm = (Statement) con.createStatement(); String query = “Select * from Curso”;
ResultSet rs = (ResultSet) stm.executeQuery(query); JRResultSetDataSource jrRS =
new JRResultSetDataSource(rs); JRExporter jrpdf = new JRPdfExporter(); JasperPrint print;
OutputStream fos = null;
print = JasperFillManager.fillReport
(“.\\reports\\Curso.jasper”, null, jrRS); fos = new FileOutputStream(“.\\reports\\Curso.pdf”); jrpdf.setParameter(JRExporterParameter.OUTPUT_STREAM,fos); jrpdf.setParameter(JRExporterParameter.JASPER_PRINT,print); jrpdf.exportReport(); fos.close(); JasperViewer.viewReport(print); } catch (IOException e) { e.printStackTrace(); } catch (JRException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } }
public void incluir(){ try {
Statement statement =
Statement) connection().createStatement(); String sql = “Insert into Curso VALUES (null,
\’”+ c.getNome()+”\’, \’”+ c.getDescricao()+”\’)”;
statement.executeUpdate(sql);
result.setText(“CURSO INSERIDO COM SUCESSO!”); } catch (SQLException e) {
e.printStackTrace();
result.setText(“OCORRERAM ERROS NA INSEÇÃO!”); }
}
public void consultar(){
ResultSet resultadoBanco = null;
String consulta = “Select * from Curso”; try {
PreparedStatement comandoBanco = connection().prepareStatement(consulta);
resultadoBanco = (ResultSet)comandoBanco.executeQuery(); connection().close();
} catch (Exception Erro) {
result.setText(“OCORRERAM ERROS NA CONSULTA!”); }
}
public void limpar(){ nome.setText(“”); descricao.setText(“”); }
public Connection connection() { Connection connection = null; try { Class.forName(“com.mysql.jdbc.Driver”).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } try {
connection = (Connection) DriverManager.getConnection (“jdbc:mysql://localhost:3306/universidade?user=root&password= root”); } catch (SQLException e) { e.printStackTrace(); } return connection; } }
class EvtJanela extends WindowAdapter{
public void windowClosing(WindowEvent e){ System.exit(0);
} }
Se tudo ocorreu como o esperado, teremos, como resultado final, nossa aplicação, na qual poderemos realizar um novo cadastro, bem como gerar o relatório destes cadastros.
Assim finalizamos nossa 7ª aula e logo nossa disciplina. Esperamos que todos tenham tirado o máximo de proveito e que agora todos sejam capazes de criar programas visuais, utilizando a biblioteca AWT, bem como gerar re- latórios. Boa sorte a todos!
Síntese da aula
Nesta aula, aplicamos todos os conceitos e componentes apresentados du- rante esta aula, além de utilizar o paradigma de orientação a objetos, criando um estudo de caso, no qual pode ser realizado o cadastro em um banco de dados, geração de relatório e trabalhar com diversas janelas e componentes, fixando todo o conhecimento adquirido e alicerçando a idéia geral, para que novas aplicações possam ser construídas.
class Curso {
Integer id = new Integer(0); String nome = new String(); String descricao = new String(); public String getDescricao() {
return descricao; }
public void setDescricao(String descricao) { this.descricao = descricao;
}
public Integer getId() { return id;
}
public void setId(Integer id) { this.id = id;
}
public String getNome() { return nome; }
public void setNome(String nome) { this.nome = nome;
} }
Atividades
1. Conforme utilizado em nosso estudo de caso, como pode ser realizado o
processo de navegação entre painéis em uma aplicação visual Java?
2. Assinale a alternativa incorreta, referente aos componentes gráficos apre-
sentados em nosso estudo de caso.
a) A classe Panel consiste em uma classe do tipo container.
b) Por meio da classe Frame, é possível criar diversas janelas para aplicações visuais.
c) O componente Button é o responsável por executar as funcionalidades do sistema.
d) As classes TextField e TextArea permitem o trabalho com textos.
Comentário das atividades
Na atividade 1, é possível se realizar todo o processo de navegação entre painéis, utilizando o gerenciador de layout CardLayout, e com o auxilio de um listener reagir a eventos e efetuar a mudança entre os painéis com a invo- cação do método next() ou after(). É válido relembrar que pode se trabalhar com outras janelas, por meio da instanciação de diversas classes derivadas da classe Frame. Na atividade 2, se você respondeu o item (c), parabéns, você acertou. No caso o botão, é apenas utilizado para passar ao sistema operacional uma mensagem de que um evento foi realizado, não executar ou mesmo fazer a chamada a uma funcionalidade do sistema, sendo que todo o comportamento deve ser implementado nos métodos oriundo dos listeners que são implementados. O item (a) está correto, uma vez que a classe Panel deriva da classe Container. O (b) também está correto, uma vez que por meio da classe Frame podemos criar diversas janelas. E, finalmente, o item (d) está correto, já que ambos os componentes trabalham com textos.
referências
DEITEL, Harvey M. Java: como programar. 6 ed. São Paulo: Pearson Prentice Hall, 2005.
FILHO, Renato Rodrigues. Desenvolva aplicativos com Java 2. São Paulo: Érica, 2005.
Anotações
FLANAGAN, David. Java: o guia essencial. 5. ed. Porto Alegre. Bookman, 2006. MANZANO, José Augusto Navarro Garcia; COSTA JR., Roberto Affonso da.
Java 2: programação de computadores. São Paulo: Érica, 2006.
THOMPSON, Marco Aurélio. Java 2 & banco de dados. São Paulo: Érica, 2002.