Lab2 Rodrigo Almeida

aluno: Rodrigo Simões de Almeida
ano/sem: 2008/2o.

Introdução

Foram executadas melhorias nas aplicações do Lab 2, basicamente a delegação dos métodos getInteligencia() e getDedicacao() para subclasses de Comportamento e a inclusão de um Simulador (interface gráfica) para que objetos possam ser criados sem o uso do Blue Jay / código

Desenvolvimento

Irei citar apenas os trechos de código não feitos conforme sugerido nas instruções para o lab:

Na classe Aluno, foi criado um método protected acceptable para dizer se um comportamento pode ou não ser aceito para alunos daquela classe. Isso, ainda que faça pouca diferença, reduz um pouco a duplicação de código nas subclasses e deixa mais claro o que se está alterando nas classes filha. O ideal seria esse método ser estático, mas infelizmente o Java não permite que métodos estáticos sejam sobrescritos (mesmo que você sobrescreva, chamar Aluno.metodo_estático não exibe comportamento polimórfico, isto é, a implementação de Aluno, e não das subclasses, seria chamada). Ao mesmo tempo, sendo um método de instância, e possível colocar restrições de comportamento para alunos individuais (entretanto isso não é um requisito do projeto).

protected boolean acceptable(Comportamento comportamento) {
        return true;
    }
 
    public void setComportamento(Comportamento comportamento) throws Exception {
        if (acceptable(comportamento))
            this.comportamento = comportamento;
        else
            throw new Exception("Comportamento " + comportamento.getClass().getName() + " incompatível com " + this.getClass().getName());
    }

Para interface gráfica, como foi usado o NetBeans, não faria muita diferença programar para o Console ou para Swing, em termos de tempo de desenvolvimento, assim a segunda opção foi preferida. O JDialog em si não faz nada, ele só repassa as entradas para uma central (que implementou o padrão Singleton, observar que justamente por isso ela tornou o RelaQueue do sistema num singleton implicitamente), que coordena as ações.

Código dos botões do JDialog

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        String nomeAluno = inNomeAluno.getText();
        Integracao.Comportamento comportamento = (Integracao.Comportamento)inComportamento.getSelectedItem();
        Integracao.Faculdade tipoAluno = (Integracao.Faculdade)inInstituicao.getSelectedItem();
 
        try {
            central.addAluno(comportamento, tipoAluno, nomeAluno);
        }
        catch (Exception e) {
            JOptionPane.showMessageDialog(this, e.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE);
        }
    }                                        
 
    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        String resultado = central.corrigeRelatorios();
        JOptionPane.showMessageDialog(this, resultado, "Relatórios Corrigidos!!!", JOptionPane.INFORMATION_MESSAGE);
    }

Inicializadores dos Combo Boxes

inInstituicao.setModel(new javax.swing.DefaultComboBoxModel(central.getFaculdades()));
        inComportamento.setModel(new javax.swing.DefaultComboBoxModel(central.getComportamentos()));

As classes do sistema foram divididas em três pacotes (util, models e main), para facilitar a organização, imports foram incluídos onde necessários para manter a sintaxe enxuta:

public class Integracao {
 
   // (...)
 
    public void addAluno(Comportamento comportamento, Faculdade faculdade, String nome) throws Exception {
        Aluno aluno = faculdade.getNewAluno(nome, queue);
        try {
            aluno.setComportamento(comportamento.getNewComportamento(aluno));
        }
        catch (Exception e) {
            throw new Exception("Aluno da faculdade " + faculdade.toString() + " não pode ter comportamento " + comportamento.toString());
        }
        aluno.fazEEntregaRelatorio();
    }
 
    public String corrigeRelatorios() {
        Professor prof = new Professor(queue);
 
        PrintStream oldOut = System.out;
        PrintfGetter output = new PrintfGetter(new ByteArrayOutputStream());
        PrintStream aPrintStream  = new PrintStream(output);
 
        try {
            System.setOut(aPrintStream);
            prof.corrigirRelatorios();
        }
        finally {
            System.setOut(oldOut);
        }
 
        return output.getOutput();
    }
}

Comportamento e Faculdade acima são enums, especialmente configurados para poderem ser diretamente usados para inicializar um Combo Box.

public enum Faculdade {
        ITA("ITA"),
        USP("USP"),
        Unicamp("Unicamp"),
        nenhuma("(Não definida)");
 
        private String representacaoTextual;
 
        Faculdade(String representacaoTextual) {
            this.representacaoTextual = representacaoTextual;
        }
 
        public Aluno getNewAluno(String nome, RelaQueue queue) {
            switch (this) {
                case ITA: return new AlunoITA(nome, queue);
                case USP: return new AlunoUSP(nome, queue);
                case Unicamp: return new AlunoUnicamp(nome, queue);
                default: return new Aluno(nome, queue);
            }
        }
 
        @Override
        public String toString() {
            return representacaoTextual;
        }
    }
 
    public enum Comportamento {
 
        Burro("Burro"),
        Esforcado("Esforçado"),
        Imprevisivel("Imprevisível"),
        Summa("Summa"),
        Pemba("Pema"),
        SafoPreguicoso("Safo Preguiçoso");
 
        private String representacaoTextual;
 
        Comportamento(String representacaoTextual) {
            this.representacaoTextual = representacaoTextual;
        }
 
        public models.Comportamento getNewComportamento(Aluno aluno) {
            switch (this) {
                case Burro: return new Burro(aluno);
                case Esforcado: return new Esforcado(aluno);
                case Imprevisivel: return new Imprevisivel(aluno);
                case Summa: return new Summa(aluno);
                case Pemba: return new Pemba(aluno);
                case SafoPreguicoso: return new SafoPreguicoso(aluno);
                default: return null;
            }
        }
 
        @Override
        public String toString() {
            return representacaoTextual;
        }
    }

Por último, o PrintfGetter é uma classe usada para extrair o conteúdo imprimido pelo professor ao corrigir relatórios para ser posteriormente exibido ao usuário na forma de uma mensagem

class PrintfGetter extends FilterOutputStream {
    private String output = new String();
 
    public PrintfGetter(OutputStream out) {
        super(out);
    }
 
    @Override
    public void write(byte[] b) throws IOException {
        output = output.concat(new String(b));
    }
 
    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        output = output.concat(new String(b, off, len));
    }
 
    public String getOutput() {
        return output;
    }
}

Screenshots Simulador

simulador-em-branco.jpg
simulador-erro-comportamento.jpg
simulador-resultado-correcao.jpg

Screenshots Teste

junit-test-results.jpg

Conclusão

O Lab permitiu a aplicação de alguns padrões de projeto (como delegação e Singleton), assim como o estudo de como redirecionar o System.out em Java.

Add a New Comment
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License