aluno: Italo Fernandes Aguiar
ano/sem: 2008/2o.
data do laboratório (6) : 02/09/2008 (2)
Introdução
Um sistema com interface gráfica que simula uma interação entre professores e alunos em esquema de correção de relatórios e divulgação de notas foi implementado em Java. A ferramenta usada para desenvolver o projeto foi o NetBeans, porém, na hora de converter para o BlueJ, estava acontecendo problemas de compilacao. Portanto, extraiu-se apenas as imagens do esquema de classes e pacotes do BlueJ mas todo o Projeto está em um arquivo JAR gerado no NetBeans.
Desenvolvimento
Foram realizadas as seguintes alterações no projeto desenvolvido no lab1:
- Adicionaram-se classes que representam alunos de 3 instituições e estas extendem a classe Aluno;
- Adicionaram-se classes que representam comportamentos dos objetos da classe Aluno e estas extendem uma classe abstrata mais geral, a classe Comportamento;
- Uma Queue genérica foi implementada e a classe RelaQueue passou a extender aquela; e
- Uma interface gráfica foi desenvolvida para facilitar a interacao usuário-aplicativo.
Os codigos usados no lab2 encontram-se listados abaixo:
PACOTE ALUNOS:
package alunos; import base.Aluno; import base.RelaQueue; import base.Comportamento; import comportamentos.Burro; public class AlunoITA extends Aluno { // CONSTRUCTOR public AlunoITA(String nome, RelaQueue queue) { super(nome, queue); } // ALUNO DO ITA NAO PODE TER O COMPORTAMENTO DE BURRO public void setComportamento(Comportamento comportamento) throws Exception { if (comportamento instanceof Burro) { throw new Exception("Aluno ITA nao pode ser Burro."); //iteanos não são burros! } super.setComportamento(comportamento); //faz o que a superclasse Aluno faz. } }
package alunos; import base.Aluno; import base.RelaQueue; import base.Comportamento; import comportamentos.Summa; import comportamentos.SafoPreguicoso; public class AlunoUNICAMP extends Aluno { // CONSTRUCTOR public AlunoUNICAMP(String nome, RelaQueue queue) { super(nome, queue); } // ALUNO UNICAMP NAO PODE TER O COMPORTAMENTO DE SUMMA OU SAFO PREGUICOSO public void setComportamento(Comportamento comportamento) throws Exception { if (comportamento instanceof Summa || comportamento instanceof SafoPreguicoso) { throw new Exception("Aluno UNICAMP nao pode ser Summa nem Safo Preguicoso."); } super.setComportamento(comportamento); //faz o que a superclasse Aluno faz. } }
package alunos; import base.Aluno; import base.RelaQueue; import base.Comportamento; import comportamentos.Summa; import comportamentos.SafoPreguicoso; public class AlunoUSP extends Aluno { public AlunoUSP(String nome, RelaQueue queue) { super(nome, queue); } // ALUNO USP NAO PODE TER O COMPORTAMENTO DE SUMMA OU SAFO PREGUICOSO public void setComportamento(Comportamento comportamento) throws Exception { if (comportamento instanceof Summa || comportamento instanceof SafoPreguicoso) { throw new Exception("Aluno USP nao pode ser Summa nem Safo Preguicoso."); //iteanos não são burros! } super.setComportamento(comportamento); //faz o que a superclasse Aluno faz. } }
PACOTE BASE:
package base; import base.RelaQueue; import base.Relatorio; import base.Comportamento; import comportamentos.Esforcado; // classe abstrata: nao pode haver objeto dessa classe instanciado public class Aluno { // ATRIBUTOS private int conhecimento = 0; private String nome; private RelaQueue queue; private Comportamento comportamento; // CONSTRUCTOR public Aluno(String nome, RelaQueue queue) { this.nome = nome; this.queue = queue; // SETANDO UM COMPORTAMENTO INCIAL: this.comportamento = new Esforcado(this); comportamento.setAluno(this); } // GETTERS E SETTERS public int getConhecimento() { return conhecimento; } public String getNome() { return nome; } public Comportamento getComportamento() { return comportamento; } public void setComportamento(Comportamento comportamento) throws Exception { this.comportamento = comportamento; } // METODOS DELEGADOS AO ATRIBUTO comportamento public float getInteligencia() { return comportamento.getInteligencia(); } public float getDedicacao() { return comportamento.getDedicacao(); } // METODO PARA FAZER E ENTREGAR UM RELATORIO public void fazEEntregaRelatorio() { double qualidade = (2 * this.getDedicacao() + 1 * this.getInteligencia() ) / 3 ; double originalidade = (1 * this.getDedicacao() + 2 * this.getInteligencia() ) / 3 ; Relatorio rela = new Relatorio( (float) qualidade ,(float) originalidade, this); queue.queue(rela); this.conhecimento++; // ver em que parte do metodo fica isso... } // METODO PARA CONVERTER O OBJETO Aluno PARA String public String toString() { return nome; } }
package base; import base.Aluno; // CLASSE ABSTRATA QUE CARACTERIZA QUAL O TIPO // DE ALUNO NOS QUESITOS DEDICACAO E INTELIGENCIA public abstract class Comportamento { // IMPLEMENTA UMA RELACAO 1:1 COM O Aluno aluno Aluno aluno; // CONSTRUCTOR public Comportamento(Aluno aluno) { this.aluno = aluno; } // GETTERS E SETTERS public Aluno getAluno() { return aluno; } public void setAluno(Aluno aluno) { this.aluno = aluno; } // METODOS A SEREM IMPLEMENTADOS public abstract float getInteligencia(); public abstract float getDedicacao(); @Override public abstract String toString(); }
package base; import java.lang.Math; public class Professor { RelaQueue queue; // constructor public Professor(RelaQueue queue) { this.queue = queue; } // metodo que dah a nota de um relatorio fornecido private float corrigirRelatorio(Relatorio rela) { double nota = (rela.getQualidade() + rela.getOriginalidade() + Math.random()) / 3 * 10; return (float) nota; } // metodo que acessa a fila de relatorios e retira todos dando suas notas public void corrigirRelatorios() { Relatorio rela; while ((rela = queue.dequeue()) != null) { System.out.println(rela.getAluno().getNome() + ": " + this.corrigirRelatorio(rela)); } } // METODO corrigirRelatorios ADAPTADO PARA A INTERFACE GRAFICA, // POIS NESTA TEM DE SER RETORNADO UM STRING public String corrigirRelatoriosToFrame() { Relatorio rela; String resultado = null; int loop = 0; // CADA RESULTADO EH COLOCADO EM UMA LINHA DA STRING while ((rela = queue.dequeue()) != null) { loop++; if(loop == 1) { resultado = rela.getAluno().getNome() + ": " + this.corrigirRelatorio(rela); } else { resultado += "\n" + rela.getAluno().getNome() + ": " + this.corrigirRelatorio(rela); } } return resultado; } }
package base; import java.util.ArrayList; // CLASSE Queue COM USO DE GENERICOS public class Queue<T> { private ArrayList<T> array = new ArrayList<T>(); // METODO PARA INSERIR UM GENERICO NA FILA public void queue(T obj) { array.add(obj); } // METODO PARA RETIRAR UM GENERICO DA FILA public T dequeue() { if( array.isEmpty() ) { return null; } else { T obj = array.get( 0 ); array.remove(obj); return obj; } } }
package base; // classe que implementa a fila de relatorios public class RelaQueue extends Queue<Relatorio> { // SUAM IMPLEMENTACAO ESTAH VAZIA PORQUE ESTA EXTENDE A CALSSE Queue // COM EXATAMENTE OS MESMOS METODOS E ATRIBUTOS }
package base; // classe que representa o relatorio import base.Aluno; public class Relatorio { float qualidade; float originalidade; Aluno aluno; // constructor public Relatorio(float qualidade, float originalidade, Aluno aluno) { this.qualidade = qualidade; this.originalidade = originalidade; this.aluno = aluno; } // getters public Aluno getAluno() { return aluno; } public float getOriginalidade() { return originalidade; } public float getQualidade() { return qualidade; } // metodo que representa a forma que um objeto desta classe deve // ser apresentado quando chamado em formato String public String toString() { return "Relatorio de " + aluno.getNome() + ", de qualidade " + this.qualidade + " e originalidade = " + this.originalidade + "."; } }
PACOTE COMPORTAMENTOS:
package comportamentos; import base.Aluno; import base.Comportamento; // CLASSE DERIVADA DA CLASSE Comportamento, HAVENDO AQUI O CONCEITO DE HERANCA public class Burro extends Comportamento { // CONSTRUCTOR public Burro(Aluno aluno) { super(aluno); } // METODOS ABSTRATOS DA SUPERCLASSE IMPLEMENTADOS @Override public float getDedicacao() { return 0; } @Override public float getInteligencia() { return 0; } // METODO PARA CONVERTER UM Comportamento Burro PARA STRING public String toString() { return "Burro"; } }
package comportamentos; // CLASSE DERIVADA DA CLASSE Comportamento, HAVENDO AQUI O CONCEITO DE HERANCA import base.Aluno; import base.Comportamento; // CLASSE DERIVADA DA CLASSE Comportamento, HAVENDO AQUI O CONCEITO DE HERANCA public class Esforcado extends Comportamento { // CONSTRUCTOR public Esforcado(Aluno aluno) { super(aluno); } // metodos abstratos da super classe implementados: @Override public float getDedicacao() { return 1; } @Override public float getInteligencia() { return (float) 0.5; } // METODO PARA CONVERTER UM Comportamento Esforcado PARA STRING public String toString() { return "Esforcado"; } }
package comportamentos; import base.Aluno; import base.Comportamento; import java.lang.Math; // CLASSE DERIVADA DA CLASSE Comportamento, HAVENDO AQUI O CONCEITO DE HERANCA public class Imprevisivel extends Comportamento { // CONSTRUCTOR public Imprevisivel(Aluno aluno) { super(aluno); } // METODOS ABSTRATOS DA SUPERCLASSE IMPLEMENTADOS @Override public float getDedicacao() { return (float) Math.random(); } @Override public float getInteligencia() { return (float) Math.random(); } // METODO PARA CONVERTER UM Comportamento Imprevisivel PARA STRING public String toString() { return "Imprevisivel"; } }
package comportamentos; import base.Aluno; import base.Comportamento; // CLASSE DERIVADA DA CLASSE Comportamento, HAVENDO AQUI O CONCEITO DE HERANCA public class Pemba extends Comportamento { // CONSTRUCTOR public Pemba(Aluno aluno) { super(aluno); } // METODOS ABSTRATOS DA SUPERCLASSE IMPLEMENTADOS @Override public float getDedicacao() { return (float) Math.random() / 2; } @Override public float getInteligencia() { return (float) Math.random() / 2; } // METODO PARA CONVERTER UM Comportamento Pemba PARA STRING public String toString() { return "Pemba"; } }
package comportamentos; import base.Aluno; import base.Comportamento; import java.lang.Math; // CLASSE DERIVADA DA CLASSE Comportamento, HAVENDO AQUI O CONCEITO DE HERANCA public class SafoPreguicoso extends Comportamento { // CONSTRUCTOR public SafoPreguicoso(Aluno aluno) { super(aluno); } // METODOS ABSTRATOS DA SUPERCLASSE IMPLEMENTADOS @Override public float getDedicacao() { return (float) Math.random() / 2 ; } @Override public float getInteligencia() { return 1; } // METODO PARA CONVERTER UM Comportamento SafoPreguicoso PARA STRING public String toString() { return "Safo Preguicoso"; } }
package comportamentos; import base.Aluno; import base.Comportamento; // CLASSE DERIVADA DA CLASSE Comportamento, HAVENDO AQUI O CONCEITO DE HERANCA public class Summa extends Comportamento { // CONSTRUCTOR public Summa(Aluno aluno) { super(aluno); } // METODOS ABSTRATOS DA SUPERCLASSE IMPLEMENTADOS @Override public float getDedicacao() { return 1 ; } @Override public float getInteligencia() { return 1; } // METODO PARA CONVERTER UM Comportamento Summa PARA STRING @Override public String toString() { return "Summa"; } }
PACOTE GUI:
package gui; public class ExcecaoFrame extends javax.swing.JFrame { /** Creates new form ExcecaoFrame */ public ExcecaoFrame( String message ) { initComponents(); // EH EXIBIDA A MENSAGEM DE EXCEPTION LANCADA NO FRAME SIMULADOR messageLabel.setText(message); // SETANDO A LOCALIZACAO DO FRAME NA TELA this.setLocation(430, 220); } // CODIGO DE INCIALIZACAO DO FRAME, SUPRIMIDO AQUI POIS SAO MUITAS LINHAS @SuppressWarnings("unchecked") // BOTAO OK FECHA ESTE FRAME private void okButtonActionPerformed(java.awt.event.ActionEvent evt) { this.dispose(); } // TECLAR ENTER CHAMA A ACAO DO BOTAO OK private void okButtonKeyPressed(java.awt.event.KeyEvent evt) { if ( evt.getKeyCode() == evt.VK_ENTER ) okButton.doClick(); } // Variables declaration - do not modify private javax.swing.JLabel messageLabel; private javax.swing.JButton okButton; // End of variables declaration }
package gui; import alunos.*; import base.*; import comportamentos.*; import javax.swing.JComboBox; // CLASSE QUE ENCAPSULA OPERACOES REALIZADA COM ALUNOS public class Instancia { private static Aluno aluno; // METODO QUE RECEBE DO FRAME PRINCIPAL OS DADOS FORNECIDOS PELO USUARIO // E RETORNA UM ALUNO OBEDECENDO A ESTAS ESPECIFICACOES public static Aluno gerarAluno( String nome, String instituicao, String tipoDeAluno, RelaQueue queue) throws Exception{ if( instituicao.equals( "ITA") ) { aluno = new AlunoITA(nome, queue); } else if ( instituicao.equals( "USP" ) ) { aluno = new AlunoUSP(nome, queue); } else if ( instituicao.equals( "UNICAMP" ) ) { aluno = new AlunoUNICAMP(nome, queue); } if( tipoDeAluno.equals( "Burro") ) { aluno.setComportamento( new Burro(aluno)); } else if( tipoDeAluno.equals( "Esforcado") ) { aluno.setComportamento( new Esforcado(aluno)); } else if( tipoDeAluno.equals( "Imprevisivel") ) { aluno.setComportamento( new Imprevisivel(aluno)); } else if( tipoDeAluno.equals( "Pemba") ) { aluno.setComportamento( new Pemba(aluno)); } else if( tipoDeAluno.equals( "Safo Preguicoso") ) { aluno.setComportamento( new SafoPreguicoso(aluno)); } else if( tipoDeAluno.equals( "Summa") ) { aluno.setComportamento( new Summa(aluno)); } return aluno; } // METODO QUE SINALIZA SE 2 ALUNOS TEM O MESMO NOME // E SAO DE UMA MESMA INSTITUICAO public static boolean compara(Aluno aluno1, Aluno aluno2 ) { if( aluno1.getNome().equals(aluno2.getNome()) && aluno1.getClass() == aluno2.getClass() ) return true; else return false; } }
package gui; import alunos.*; import base.*; import comportamentos.*; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JComboBox; import javax.swing.table.DefaultTableColumnModel; import javax.swing.table.DefaultTableModel; // CLASSE QUE IMPLEMENTA A INTERFACE COM O USUARIO public class SimuladorFrame extends javax.swing.JFrame { /** Creates new form SimuladorFrame */ public SimuladorFrame() { initComponents(); // CRIANDO UMA RELAQUEUE PARA INICIALIZAR OS ALUNOS queue = new RelaQueue(); // SETANDO A POSICAO DESTE FRAME NA TELA this.setLocation(150, 70); } // CODIGO DE INCIALIZACAO DO FRAME, SUPRIMIDO AQUI POIS SAO MUITAS LINHAS @SuppressWarnings("unchecked") // ACAO GERADA AO CLICAR NESTE BOTAO private void adicionarButtonActionPerformed(java.awt.event.ActionEvent evt) { try { // INSTANCIA UM OBJETO Aluno A PARTIR DOS DADOS FORNECIDOS PELO USSUARIO aluno = Instancia.gerarAluno( nomeTextField.getText(), (String) instituicaoComboBox.getSelectedItem(), (String) tipoDeAlunoComboBox.getSelectedItem(), queue); // VERIFICA SE ESTE ALUNO JAH ESTA CADASTRADO, E LANCA EXCECAO EM CASO POSITIVO for(i = 0; i < AlunosTable.getRowCount(); i++) { if( Instancia.compara(aluno, (Aluno) AlunosTable.getValueAt(i, 0)) ) { throw new Exception("Este aluno ja foi cadastrado."); } } // GERANDO UMA NOVA LINHA NA TABELA A PARTIR DOS DADOS FORNECIDOS ((DefaultTableModel) AlunosTable.getModel()).addRow(new Object[]{aluno, 0, aluno.getClass().getName().substring(12), aluno.getComportamento().toString() }); } catch (Exception ex) { // CASO DE ALUNO JAH CADASTRADO, EXIBIR UM FRAME COM A MENSAGEM LANCADA NA EXCECAO ExcecaoFrame exFrame = new ExcecaoFrame( ex.getMessage() ); exFrame.setVisible(true); } } // CORRIGIR TODOS OS RELATORIOS ARMAZENADOS NA FILA RelaQueue queue private void corrigirRelatoriosButtonActionPerformed(java.awt.event.ActionEvent evt) { Professor prof = new Professor(queue); // EXIBIR RESULTADO NA AREA DE TEXTO resultadoTextArea.setText( prof.corrigirRelatoriosToFrame() ); // ZERANDO O NUMERO DE RELATORIOS ARMAZENADOS E EXIBINDO NO RESPECTIVO CAMPO totalRelas = 0; relatoriosACorrigirTextField.setText(totalRelas.toString()); // ZERANDO OS RELATORIOS A CORRIGIR PARA CADA ALUNO CADASTRADO for(i = 0; i < AlunosTable.getRowCount(); i++) { AlunosTable.setValueAt(0, i, 1); } } // METODO PARA OS ALUNOS SELECIONADOS FAZEREM RELATORIO private void fazerRalatorioButtonActionPerformed(java.awt.event.ActionEvent evt) { rows = AlunosTable.getSelectedRows(); for(i = 0; i < rows.length; i++) { // CARREGANDO O ALUNO E O NUMERO DE RELATORIOS DESTE aluno = (Aluno) AlunosTable.getValueAt( rows[i] , 0); numRelas = (Integer) AlunosTable.getValueAt(rows[i], 1); // ADICIONANDO UM RELA FEITO A ESTE ALUNO AlunosTable.setValueAt(numRelas+1, rows[i], 1); // ALUNO FAZ E ENTREGA RELATORIO NA FILA aluno.fazEEntregaRelatorio(); // ATUALIZANDO O NUMERO TOTAL DE RELATORIOS DE TODOS OS ALUNOS totalRelas++; relatoriosACorrigirTextField.setText(totalRelas.toString()); } } // TODOS OS ALUNOS FAZEM UM RELATORIO private void fazerRelatoriosButtonActionPerformed(java.awt.event.ActionEvent evt) { // PARA CADA ALUNO CADASTRADO for(i = 0; i < AlunosTable.getRowCount(); i++) { // CARREGANDO O ALUNO E O NUMERO DE RELATORIOS DESTE aluno = (Aluno) AlunosTable.getValueAt( i , 0); numRelas = (Integer) AlunosTable.getValueAt(i, 1); // ADICIONANDO UM RELA FEITO A ESTE ALUNO AlunosTable.setValueAt(numRelas+1, i, 1); // ALUNO FAZ E ENTREGA RELATORIO NA FILA aluno.fazEEntregaRelatorio(); // ATUALIZANDO O NUMERO TOTAL DE RELATORIOS DE TODOS OS ALUNOS totalRelas++; relatoriosACorrigirTextField.setText(totalRelas.toString()); } } // METODO PARA LIMPAR A TELA COM AS NOTAS DOS RELATORIOS CORRIGIDOS private void limparTelaButtonActionPerformed(java.awt.event.ActionEvent evt) { resultadoTextArea.setText(""); } // METODO PARA SAIR DO PROGRAMA ATRAVES DO MENU private void sairMenuItemActionPerformed(java.awt.event.ActionEvent evt) { this.dispose(); } // METODO PARA ABRIR O FRAME COM INSTRUCOES SOBRE O PROGRAMA private void sobreOAplicativoMenuItemActionPerformed(java.awt.event.ActionEvent evt) { SobreFrame sf = new SobreFrame(); sf.main(null); } // METODO MAIN PARA ABRIR O FRAME public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new SimuladorFrame().setVisible(true); } }); } // VARIAVEIS CRIADAS MANUALMENTE RelaQueue queue; int[] rows; Integer i, numRelas, totalRelas = 0; Aluno aluno; // Variables declaration - do not modify private javax.swing.JLabel AlunosCriadosLabel; private javax.swing.JTable AlunosTable; private javax.swing.JLabel CriandoAlunoLabel; private javax.swing.JButton adicionarButton; private javax.swing.JLabel alunosSelecionadosLabel; private javax.swing.JButton corrigirRelatoriosButton; private javax.swing.JButton fazerRalatorioButton; private javax.swing.JButton fazerRelatoriosButton; private javax.swing.JComboBox instituicaoComboBox; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel5; private javax.swing.JMenu jMenu1; private javax.swing.JMenu jMenu2; private javax.swing.JMenuBar jMenuBar1; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane2; private javax.swing.JButton limparTelaButton; private javax.swing.JLabel nomeLabel; private javax.swing.JTextField nomeTextField; private javax.swing.JTextField relatoriosACorrigirTextField; private javax.swing.JTextArea resultadoTextArea; private javax.swing.JMenuItem sairMenuItem; private javax.swing.JMenuItem sobreOAplicativoMenuItem; private javax.swing.JComboBox tipoDeAlunoComboBox; private javax.swing.JLabel tipoDeAlunoLabel; private javax.swing.JLabel todosOsAlunosLabel; // End of variables declaration }
package gui; public class SobreFrame extends javax.swing.JFrame { /** Creates new form SobreFrame */ public SobreFrame() { initComponents(); // SETA A LOCALIZACAO DO FRAME NA TELA this.setLocation(430, 220); } // CODIGO DE INCIALIZACAO DO FRAME, SUPRIMIDO AQUI POIS SAO MUITAS LINHAS @SuppressWarnings("unchecked") // BOTAO OK FECHA ESTE FRAME private void okButtonActionPerformed(java.awt.event.ActionEvent evt) { this.dispose(); } // TECLAR ENTER CHAMA A ACAO DO BOTAO OK private void jTextArea1KeyPressed(java.awt.event.KeyEvent evt) { if ( evt.getKeyCode() == evt.VK_ENTER ) okButton.doClick(); } // METODO MAIN PARA EXIBIR ESTE FRAME NA TELA public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new SobreFrame().setVisible(true); } }); } // Variables declaration - do not modify private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JPanel jPanel1; private javax.swing.JScrollPane jScrollPane3; private javax.swing.JTextArea jTextArea1; private javax.swing.JButton okButton; // End of variables declaration }
Nas Figura de 1 a 5 estão representados as estruturas de pacotes e classes do projeto. A figura 6 representa o resultado do conjunto de testes realizados, com estes aprovados. A figura 7 mostra a tela incial do projeto.

Figura 1 - Pacote alunos

Figura 2 - Pacote base

Figura 3 - Pacote comportamentos

Figura 4 - Pacote gui

Figura 5 - Visao geral dos pacotes

Figura 6 - Resultado dos testes

Figura 7 - Exemplo da tela inicial do projeto
Conclusão
Com as alterações implementadas no lab1, foi possível solidificar o aprendizado quanto a Programacao Orientada a Objetos - POO: Definiu-se classe com uso de genéricos, usou-se o conceito de heranca e polimorfismo e mensagens foram trocada entre objetos na aplicação.
Uma alternativa para a pergunta feita na seção de instrucoes para o lab2 é o uso de interface para a classe comportamento, pois esta está atuando de uma forma similar ao funcionamento de uma interface em Java.
Essa prática resumiu bem os principais conceitos iniciais que envolvem POO. Será possível explorar mais as potencialidades desta quando houver interação com Banco de Dados e/ou Programacao WEB.





