UNIVERCIDADE FEDERAL DE SANTA CATARINA CENTRO TECNOLÓGICO DEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA CURSO DE BACHAREL EM SISTEMAS DE INFORMAÇÃO SISTEMA DE ANÁLISE ESTATÍSTICA BÁSICA WANDERLEI PASSOS FLORIANÓPOLIS 2007 WANDERLEI PASSOS SISTEMA DE ANÁLISE ESTATÍSTICA BÁSICA Trabalho de conclusão de curso apresentado como requisito parcial para a obtenção do grau de Bacharel em Sistemas de Informação. Orientador: Prof. Pedro Alberto Barbetta, Dr. FLORIANÓPOLIS 2007 SISTEMA DE ANÁLISE ESTATÍSTICA BÁSICA Por WANDERLEI PASSOS Trabalho de conclusão de curso aprovado para a obtenção do grau de Bacharel em Sistemas de Informação, pela Banca examinadora formada por: _________________________________________________ Presidente: Prof. Pedro Alberto Barbetta, Dr. - Orientador, UFSC _________________________________________________ Membro: Prof. José Eduardo De Lucca,Dr., UFSC _________________________________________________ Membro: Prof. Paulo José Ogliari, Dr., UFSC Florianópolis, 19 de novembro de 2007. Dedico este trabalho à minha família, em especial à minha filha Luana, que foi quem mais sentiu a minha falta durante esta jornada. RESUMO O uso da informática está presente em tudo o que fazemos, e a sua utilização nas atividades de ensino está a cada dia, mais intensa. Este trabalho busca então, desenvolver um Sistema para, Análise Estatística Básica que, servirá como ferramenta para os alunos porem em prática o conteúdo aprendido nas disciplinas de estatística. Podemos dizer que a estatística é uma ciência muito vasta, que abrange desde a organização, descrição, análise e interpretação de dados. Deste modo o software resultante se preocupa apenas com a parte de organização e descrição estatística dos dados. Palavras-chave: Estatística Básica, Desenvolvimento de Software. ABSTRACT The use of the computer science is present in everything that we do, and your use in the teaching activities is every day, more intense. This work looks for then, to develop a System for Basic Statistical Analysis that, it will serve as tool for the students to put in practice the content learned in statistics disciplines. We can say that the statistics is a very vast science that embraces from the organization, description, analysis and interpretation of data. This way the resulting software just worries about the organization part and statistical description of the data. Word-key: Basic statistics, Development of Software. LISTA DE ILUSTRAÇÕES Figura 1 - Esquema geral de Estatística..........................................................................................14 Figura 2 - Diagrama de Casos de Uso do Sistema.........................................................................28 Figura 3 - Diagrama de Classes do Domínio do Problema............................................................30 Figura 4 - Diagrama de Classes de Projeto....................................................................................33 Figura 5 - Tela Principal do Protótipo com um arquivo importado do Excel...............................35 Figura 6 – Tela com um gráfico construído com o protótipo.......................................................36 SUMÁRIO 1 INTRODUÇÃO ............................................................................................................ 10 1.1 OBJETIVOS ................................................................................................................... 10 1.1.1 Geral ............................................................................................................................... 10 1.1.2 Específicos ...................................................................................................................... 11 1.2 JUSTIFICATIVA PARA O DESENVOLVIMENTO DO PROJETO .......................... 11 1.3 ESTRUTURA DO TRABALHO ................................................................................... 12 2 FUNDAMENTOS TEÓRICOS DE ESTATÍSTICA ................................................ 12 2.1 POPULAÇÃO E AMOSTRA ........................................................................................ 13 2.2 DISTRIBUIÇÃO DE FREQÜÊNCIA ........................................................................... 14 2.3 MEDIDAS DESCRITIVAS ........................................................................................... 14 2.4 PARÂMETRO X ESTATÍSTICA ................................................................................. 15 2.5 ERRO AMOSTRAL ...................................................................................................... 15 2.6 TESTES DE HIPÓTESE ................................................................................................ 15 2.7 CORRELAÇÃO ............................................................................................................. 16 2.8 REGRESSÃO ................................................................................................................. 16 3 VISÃO GERAL DO PROCESSO DE DESENVOLVIMENTO.............................. 16 3.1 CARACTERÍSTICAS DO PROCESSO UNIFICADO ................................................. 17 3.2 ETAPAS DO DESENVOLVIMENTO .......................................................................... 17 3.3 CICLO DE VIDA DO DESENVOLVIMENTO ........................................................... 18 3.4 MODELAGEM DE SISTEMAS ................................................................................... 19 4 DEFINIÇÃO DO SISTEMA ....................................................................................... 19 4.1 VISÃO GERAL DO SISTEMA ..................................................................................... 19 4.2 ESPECIFICAÇÃO DOS REQUISITOS ........................................................................ 20 4.2.1 REQUISITOS FUNCIONAIS ........................................................................................ 20 4.2.2 REQUISITOS NÃO-FUNCIONAIS .............................................................................. 24 4.3 CASOS DE USO DE ALTO NÍVEL ............................................................................. 25 5 ANÁLISE ...................................................................................................................... 29 5.1 CASOS DE USO EXPANDIDOS ................................................................................. 30 5.2 MODELO CONCEITUAL............................................................................................. 31 6 PROJETO ..................................................................................................................... 33 6.1 ARQUITETURA DO SISTEMA ................................................................................... 33 6.2 CLASSES DE PROJETO............................................................................................... 34 7 IMPLEMENTAÇÃO ................................................................................................... 36 7.1 PROTÓTIPO DE INTERFACE COM USUÁRIO ........................................................ 36 8 CONSIDERAÇÕES FINAIS ....................................................................................... 39 8.1 OBJETIVOS ATINGIDOS ............................................................................................ 39 REFERÊNCIAS .......................................................................................................................... 40 ANEXO A – CÓDIGO FONTE DO 1º PROTÓTIPO DO SISTEMA ................................... 41 10 1 INTRODUÇÃO Vivemos atualmente em um mundo de informação e, onde o armazenamento e recuperação dessa informação é cada vez mais facilitada pelo atual desenvolvimento tecnológico. Muitas vezes a utilização dessa informação, não é simples e direta. Ou seja é preciso algum trabalho de processamento para que os dados que dispomos sejam transformados em informação e conhecimento. A estatística é justamente uma ciência que se preocupa com a transformação de dados em informações e conhecimento por meio da organização, descrição, análise e interpretação de dados e, é aplicável a qualquer ramo do conhecimento onde se manipulam dados. A estatística é uma ciência de inegável importância, tanto que é cadeira obrigatória na maioria dos cursos de nível superior. Levando-se em consideração as enormes quantidades de dados que temos de analisar, o uso da estatística se torna muito mais eficiente através de ferramentas de software que atomatizam as tarefas estatísticas, bem como facilitam a interpretação dos resultados, através da organização dos dados e apresentação de diversos tipos de gráficos de forma automática. De fato existem muitos softwares estatísticos no mercado, mas em geral são caros, e difíceis de usar por estudantes que estão se iniciando no aprendizado de estatística, de modo que a proposta deste trabalho é o desenvolvimento de um software livre para análise estatística básica, para ser utilizado por estudantes de estatística. 1.1 OBJETIVOS A seguir enunciam-se os objetivos geral e específicos do trabalho. 1.1.1 Geral O objetivo principal deste trabalho de conclusão de curso é, pôr em prática os conhecimentos adquiridos no transcorrer do curso de Sistemas de Informação, com ênfase na Engenharia de Software, Engenharia de Usabilidade e Estatística Básica, através da construção de um Software de Análise Estatística Básica, que busca atender as necessidades 11 dos alunos de Estatística dos cursos de graduação da UFSC. Então, pretende-se analisar os softwares existentes de modo a agregar ao sistema proposto as funcionalidades que forem consideradas mais adequadas, de acordo com critérios do professor-orientador 1.1.2 Específicos a) Como objetivos específicos, o trabalho busca, em um primeiro momento, entender o problema através do estudo da Estatística Básica, delimitando esse estudo à área de Estatística Descritiva. b) Fazer a análise e projeto do sistema utilizando a UML (Unified Modeling Language), como a linguagem de modelagem do sistema. c) Utilizar o Processo Unificado como a metodologia de desenvolvimento de software, que servirá como um guia durante o processo de desenvolvimento. d) Programar o sistema, utilizando a linguagem de programação orientada a objetos Java versão cinco, buscando maximizar o reuso através da utilização de bibliotecas Java, disponíveis na internet. e) Construir o software utilizando a arquitetura MVC (Model, View, Controller), de modo a separar as responsabilidades da interfase com o usuário (GUI), das responsabilidades das demais partes do sistema. f) E por fim, construir uma interface amigável para o usuário operar o sistema. 1.2 JUSTIFICATIVA PARA O DESENVOLVIMENTO DO PROJETO O desenvolvimento desse projeto é justificado pela necessidade do autor de pôr em prática o conhecimento adquirido no curso através do desenvolvimento de um software completo e funcional, e pela necessidade do professor-orientador de disponibilizar aos alunos 12 um software livre, simples e em português para análise estatística básica. Os softwares existentes são, em geral, caros e complexos demais para estudantes iniciantes em estatística e, estão em inglês, o que pode ser uma barreira no aprendizado dos estudantes. 1.3 ESTRUTURA DO TRABALHO O presente trabalho pode ser dividido em duas partes. Uma parte teórica, constituida pelos capítulos 2 e 3, e o relatório de desenvolvimento do software, dos capítulos 4 ao 7. Na parte teórica, o capítulo 2 explana de uma forma sucinta os principais conceitos de Estatística envolvidos no projeto. Já o capítulo 3, dá uma visão geral do processo de desenvolviomento de software, especificamente sobre o Processo Unificado, o qual foi utilizado neste projeto. No capítulo 4, Definição do Sistema, damos uma visão geral do sistema, definimos as funcionalidades do software através da especificação dos requisitos, e dos casos de uso do software. A etapa de análise é tratada no capítulo 5, onde abstraimos os conceitos do domínio do problema, relevantes em uma primeira análise e, desenhamos o diagrama conceitual do sistema. O capítulo 6, trata do projeto do sistema. Nele falamos sobre a arquitetura de software empregada no sistem e projetamos as classes do sistema, que deverão ser traduzidas em linguagem de programação Java. No capítulo 7, falamos sobre a implementação de um protótipo que foi construido com o intuito de compreender melhor os requisitos do sistema. E finalmente no capítulo 8, fazemos as considerações finais sobre o projeto no atual estágio de desenvolvimento. 2 FUNDAMENTOS TEÓRICOS DE ESTATÍSTICA A estatística é uma área do conhecimento e também uma ciência que, baseia-se na teoria estatística, um ramo da matemática aplicada, para explicação de eventos, estudos e experimentos. Tem por objetivo obter, organizar e analisar dados, determinar as correlações que apresentem, tirando delas suas conseqüências para descrição e explicação do que passou e previsão e organização do futuro (Wikipedia). 13 Segundo (Costa Neto,1977) a estatística pode ser dividida basicamente em duas partes: a Estatística Descritiva que, compreende a organização, apresentação e sintetização dos dados, e a Estatística Indutiva que cuida da análise e interpretação dos dados. O objetivo da Estatística Indutiva é o de tirar conclusões sobre populaçoes com base nos resultados observados em amostras extraídas dessas populações, dizendo também qual a precisão desses resultados e com que probabilidade se pode confiar nas conclusões obtidas. De acordo com (Costa Neto, 1977) um estudo estatístico completo que recorra às técnicas de Estatística Indutiva irá envolver também, direta ou indiretamente, tópicos de Estatística Descritiva, Cálculo de Probalidades e Técnicas de Amostragem, conforme Figura 1. Amostragem Estatística Descritiva Cálculo de Probabilidades Estatística Indutiva Figura 1 Esquema geral de Estatística - Fonte: Costa Neto,1977 A seguir veremos alguns conceitos importantes relacionados a estatística. 2.1 POPULAÇÃO E AMOSTRA População é o conjunto de elementos que formam o universo de estudo e que são passíveis de serem observados. Uma parte desses elementos é dita uma amostra (Barbetta,2002). 14 2.2 DISTRIBUIÇÃO DE FREQÜÊNCIA A distribuição de freqüência compreende a organização dos dados de acordo com as ocorrências dos diferentes resultados observados (Barbetta,2002). Por exemplo, supondo que temos os dados dos candidatos ao vestibular da UFSC , e que temos os dados de qual região do estado os candidatos pertencem, a distribuição de freqüência desses candidatos, seria contabilizar quantos candidatos (ou a percentagem de candidatos) se enquadram em cada região do estado. 2.3 MEDIDAS DESCRITIVAS Muitas vezes é necessário sumarizar certas características das distribuições de freqüências por meio de certas medidas usualmente denominadas de medidas da distribuição de freqüência (Costa Neto, 1977). Temos assim, medidas de posição, de dispersão, de assimetria e de achatamento ou curtose. As medidas de posição e de dispersão, são as mais importantes, tendo grande aplicação em problemas de Estatística Indutiva. Comentamos a seguir, apenas, as mais importantes. Como medidas de posição podemos citar a média, a mediana e a moda. As duas primeiras medidas indicam por critérios diferentes, o centro da distribuição de freqüência. A moda por sua vez é uma medida que indica a região de maior concentração de freqüências na distribuição. As medidas de dispersão complementam a informação fornecida pelas medidas de posição, indicando o quanto os dados se encontram dispersos em torno da região central (Costa Neto,19770). Exemplos de medidas de dispersão são a amplitude, a variância, o desvio-padrão e o coeficiente de variação. A amplitude é definida como a diferença entre o maior e o menor valor do conjunto de dados. Já a variância é, por definição, a média dos quadrados das diferenças dos valores em relação à sua média. Como a variância de um conjunto de dados é calculada em função dos desvios quadráticos, sua unidade de medida equivale à unidade de medida dos dados ao quadrado (Barbetta,2002). Na prática, esse incoveniente é sanado com a definição do desvio-padrão que nada mais é do que a raiz quadrada positiva da variância. 15 2.4 PARÂMETRO X ESTATÍSTICA Um parâmetro é alguma medida que descreve certa característica da população, enquanto que uma estatística é uma medida associada aos dados de uma amostra. Uma estatística, quando usada com o objetivo de fazer a estimação do valor de algum parâmetro, também é chamada de estimador (Barbetta,2002), e esse processo de estimar um parâmetro de uma determinada população, com base em uma estatística calculada em uma amostra dessa população é denomindo Estimação de Parâmetros. 2.5 ERRO AMOSTRAL Como mencionamos anteriomente a Estatística Indutiva se preocupa também com a precisão dos resultados e com que probabilidade se pode confiar nas conclusões obtidas. As operações realizadas com os dados da amostra resultam numa estatística que, pode ser basicamente uma proporção ou a média de ulguma característica dos elementos da amostra. E para que a análise dos resultados seja a mais correta possível também é feito o cáculo do erro amostral que, em geral é a diferença entre um parâmetro e a estatística usada para a estimação. Uma estimativa é tão mais precisa quanto menor for o seu erro amostral (Barbetta,2002). 2.6 TESTES DE HIPÓTESE Muitas vezes o pesquisador tem alguma hipótese sobre o comportamento de uma determinada variável, ou de uma associação entre variáveis. Neste caso é necessário utilizar técnicas denominadas testes de hipótese ou testes de significância para verificar se os dados fornecem evidência suficiente para que se possa aceitar como verdadeira a hipótese de pesquisa, precavendo-se, com certa segurança, de que as estatísticas observadas na amostra não são meramente casuais (Barbetta,2002). 16 2.7 CORRELAÇÃO Correlação é o estudo de associação entre duas variáveis que são mensuráveis quantitativamente. Duas variáveis X e Y, são positivamente correlacionadas, quando elas caminham num mesmo sentido, ou seja, elementos com valores pequenos de X tendem a ter valores pequenos de Y e vice versa. E são negativamente correlacionadas quando eles caminham em sentidos opostos, ou seja, elementos com valores pequenos de X tendem a ter valores grandes de Y e vice versa (Barbetta,2002). 2.8 REGRESSÃO A regressão é um termo que surgiu com os trabalhos de Galton no final do século XIX. Estes trabalhos procuravam explicar certas características de um indivíduo a partir das características de seus pais. Assim como num estudo de correlações, a análise de regressão também parte de um conjunto de observações pareadas (x, y), mas se distingue da correlação por supor uma relação de causalidade entre X e Y, descrita em termos de uma relação matemática (Barbetta,2002). 3 VISÃO GERAL DO PROCESSO DE DESENVOLVIMENTO Um processo de desenvolvimento de software provê uma base para a produção organizada de software, usando uma coleção de técnicas e notações predefinidas (Blaha; Rumbaugh, 2006). Existem hoje no mercado, diversos processos para desenvolvimento de software. Nesta seção abordaremos, bem superficialmente, algumas características do Processo Unificado o qual, pretendemos utilizar no desenvolvimento do Sistema de Análise Estatística Básica. Destacamos aqui que não pretendemos cumprir religiosamente todos os requisitos exigidos por este processo, visto que são muitos. E como não existe ainda uma metodologia considerada perfeita, no decorrer do desenvolvimento do projeto caso seja necessário, serão feitas adaptações a fim de conseguir sucesso no desenvolvimento do projeto. A seguir explanaremos as principais características do Processo Unificado. 17 3.1 CARACTERÍSTICAS DO PROCESSO UNIFICADO O processo unificado possui três características principais. Ele é um processo dirigido por Casos de Uso, é centrado em arquitetura e seu ciclo de vida é iterativo e incremental. Um processo dirigido por casos de uso, significa que o processo de desenvolvimento segue um fluxo, em que os casos de uso são especificados, projetados, implementados, e no fim são a fonte a partir dos quais os testes são definidos e realizados (SILVA;VIDEIRA,2001). Basicamente podemos dizer que casos de uso representam as funcionalidades que o sistema deve disponibilizar para o usuário do sistema. Um processo centrado na arquitetura, significa que há a preocupação de como vemos o software como um todo. Quando pensamos em questões de orçamento, tecnologias, se o software será ou não composto por camadas, ambientes de software e hardware sobre o qual o novo software estará pautado, estamos falando de sua arquitetura (MEDEIROS,2004). A terceira importante característica do Processo Unificado é que este processo é iterativo e incremental. O desenvolvimento de um software segundo esta metodologia, envolve a execução de várias atividades como, levantamento de requisitos, análise, projeto, implementação e testes. Uma passagem completa por este ciclo de atividades constitui uma iteração, e normalmente resulta como produto uma nova versão do software que está sendo desenvolvido. A cada iteração, novas funcionalidades(incrementos) vão sendo acrescentadas até que o software esteja completamente pronto. Por isso que esta metodologia é considerada iterativa e incremental. 3.2 ETAPAS DO DESENVOLVIMENTO Segundo (BLAHA;RUNBAUGH,2006), o desenvolvimento de um software se dá através de uma sequência de etapas bem definidas. A apresentação das etapas é linear , embora o processo real raramente o seja. Concepção do sistema: Nessa etapa alguém cancebe uma idéia para uma aplicação, levando em consideração as nessecidades do negócio e as capacidades tecnológicas. 18 Análise: Nesta etapa busca-se entender profundamente os requisitos construindo modelos. O objetivo da análise é especificar o que precisa ser feito, não como é feito. Projeto: Aqui é criada a arquitetura para resolver o problema da aplicação. O modelo desenvolvido na etapa de análise é ajustado a arquitetura definida, de modo que sejam passíveis de serem implementados em computador. Também devem ser determinados os agorítmos das operações. Implementação: O projeto é traduzido em código de programação e estruturas de bancos de dados. Teste: Esta etapa assegura que a aplicação esteja adequada para o uso real e que realmente satisfaça os requisitos. Treinamento: Os usuários devem ser treinados para dominar a nova aplicação, caso contrário o sucesso do projeto pode ser comprometido, devido a relutancia dos usuários em utilizar o software. Implantação: Consiste em colocar a aplicação em produção e, harmoniosamente, ajustar às demais aplicações quando for o caso. Manutenção: é um engano pensar que o desenvolvimento de um software termina com a sua implantação no cliente. Na verdade, a viabilidade de longo prazo da aplicação depende da manutenção que sem dúvida será necessária a nova aplicação, seja para corrigir problemas ou para atender a novas solicitações do cliente. 3.3 CICLO DE VIDA DO DESENVOLVIMENTO Uma abordagem Orientada a Objetos para desenvolvimento de software aceita vários tipos de ciclo de vida. Pode-se utilizar a abordagem em cascata para realizar a etapas de análise, projeto e implantação em uma sequência única para o sistema inteiro. Entretando o mais recomendado (BLAHA;RUMBAUGH,2006), e o que vai ser utilizado no desenvolvimento deste projeto, é uma estratégia de desenvolvimento iterativo, como é o caso do Processo Unificado explicado anteriormente no final seção 3.1. 19 3.4 MODELAGEM DE SISTEMAS Esta seção não pretende explicar o que é a UML(UNIFIED MODELING LANGUAGE), mas sim definila como a linguagem utilizada na modelagem do Sistema de Análise Estatística Básica. Uma das técnicadas de projeto é a criação de modelos que são abstrações do problema, com a finalidade de entendê-lo antes de construir uma solução. O desenvolvimento precisa abstrair diferentes visões do sistema, montar modelos com notações exatas, verificar se os modelos satisfazem aos requisitos do sistema e acrescentar detalhes gradualmente, a fim de transformar os modelos em uma implementação. A UML é a linguagem de modelagem que possibilita modelar um sistema a partir de vários pontos de vista diferentes. Para uma descrição completa de um sistema são necessários pelo menos três pontos de vista distintos, porém relacionados. O modelo de classes representa os aspectos estáticos, estruturais, de “dados” de um sistema. O modelo de estados representa os aspectos temporais, comportamentais, de “controle” de um sistema. E o modelo de interações representa a colaboração de objetos individuais, os aspectos de “interações” de um sistema. Cada modelo tem referências a entidades em outros modelos. Por exemplo, o modelo de classes anexa operações às classes, emquanto os modelos de estado e de interações elaboram as operações (BLAHA; RUMBAUGH,2006). 4 DEFINIÇÃO DO SISTEMA A primeira etapa do projeto foi, a concepção do sistema, quando definimos os objetivos do presente trabalho. No entanto, é preciso definir com mais detalhes que funcionalidades o sistema deverá ter, e quais os limites do sistema. 4.1 VISÃO GERAL DO SISTEMA Como vimos no capítulo 2, a Estatística pode ser dividida em Estatística Descritiva e Estatística Indutiva, e que a Estatística Indutiva depende das técnicas de organizaçao e descrição dos dados da Estatística Descritiva para poder fazer a análise e interpretação dos 20 dados observados. Tendo isso em vista, e que desenvolver um software estatístico completo, estaria além das espectativas para um TCC e dos recursos disponíveis, delimitamos o escopo do projeto ao desenvolvimento de um software que atenda apenas ao módulo de Estatística Descritiva. Para definir as funcionalidades que o Sisema de Análise Estatística Básica deve ter, fizemos uma pequena análise de alguns softwares estatísticos existentes (MINITAB, INSTAT e SPSS), procurando por funcionalidades que se adeqüem a proposta do nosso projeto e, então com base neste estudo definimos os requisitos do nosso sistema, que serão listados na seção 4.2 deste trabalho. Ressaltamos que o software que será desenvolvido não tem a pretenção de concorrer com esses softwares, ao contrário, tem a pretenção de ser um software simples para facilitar o seu uso por estudantes iniciantes no aprendizado de estatística. O software desenvolvido consitirá em uma aplicação desktop, desenvolvida com a tecnologia Java, e deverá ser distribuido sob os termos da GNU Lesser General Public Licence (LGPL), que permite uso em aplicações proprietárias. O software poderá ser instalado nos laboratórios da UFSC onde os professores poderão utilizá-lo em aulas práticas e, os alunos poderão baixar o software de algum repositório e instalá-lo nos seus computadores pessoais para a prática de exercícios passados pelo professor, bem como para realizar análises estatísticas de seu próprio interesse. 4.2 ESPECIFICAÇÃO DOS REQUISITOS Conforme apresentado nos tópicos anteriores a finalidade do software é atender as necessidades de análise de dados, dos estudantes de disciplinas de Estatística dos cursos de graduação da UFSC, e para isso foram levantadas os principais requisitos funcionais e não funcionais que o software deverá ter. 4.2.1 REQUISITOS FUNCIONAIS Os dados a serem analizados pelo sistema devem ser fornecidos pelo usuário e, serão tratados de forma indiferente quanto ao fato de os dados serem apenas uma amostra ou serem dados de toda a população em estudo. Para que seja possível fazer a análise dos dados do usuário um dos primeiros requisitos que o software deve atender é a capacidade de abrir o 21 arquivo em que os dados do usuário estão armazenados. Definimos então que o software terá a capacidade de importar, dados armazenados no formato Excel e, também de importar os dados a partir de arquivos texto, desde que os mesmos estejam dispostos de uma maneira estruturada, como é o caso de arquivos .cvs, em que os dados são separados por vírgulas. Uma vez que que o arquivo foi importado, e o usuário tenha feito suas atividades de análise, o sistema dever permitir que o arquivo seja salvo ou exportado, também para o formato Excel ou arquivo texto separado por vírgula. O sistema deverá ser capaz de manipular os dados, deixando-os em um estado propício para a análise estatística. Essa capacidade de manipular os dados constitui um requisito do software e pode ser dividido em várias funcionalidades, tais como ordenar dados, alterar tipos de dados das variáveis, etc. Uma lista completa, não só dessas funcionalidades, mas de todos os requitos do sistema é mostrada na tabela 1. Uma das principais tarefas estatísticas que o sistema deverá realizar é a distribuição de freqüências para uma determinada variável, devendo inclusive ter a capacidade de fazer a distribuição de freqüências contabilizando as freqüências desta variável, por categorias de uma outra variável qualquer. A apresentação dos resultados deverá ser feita através de tabelas, tabelas cruzadas, ou gráficos, tais como gráficos circulares, gráficos de barras, ou histogramas. As distribuições de freqüência poderão ser apresentas em valores absolutos ou relativos (percentual). Outro requisito do software, evidentemente, é a capacidade de fazer os cálculos de medidas descritivas estatísticas. Basicamente o software deve ser capaz de calcular as seguintes medidas descritivas: Média aritmética, Erro padrão da média, Desvio padrão, Variância, Coeficiente de variação, 1º Quartil, Mediana, 3º Quartil, Moda, Diferença entre 1º e 3º quartis, Soma, Mínimo, Máximo, Amplitude, Nº de valores perdidos, Nº total de valores, Nº cumulativo, Percentual, Percentual cumulativo, Soma dos quadrados, etc. Os resultados poderão ser apresentados em texto tabulado ou em uma tabela. O sistema deve ter a capacidade de construir diversos tipos de gráficos com a finalidade de permitir ao usuário uma fácil visualização dos resultados de suas análises. Como um conjunto mínimo de gráficos que o sistema deve fornecer, definimos os seguintes: Histograma, Histograma com Curva Normal, Gráfico de Caixas, Gráfico de Intervalos, Gráficos de Barras, Gráficos de Pizza, Gráfico de Séries Temporais, Gráficos de Áreas, Gráficos de freqüência, Gráficos Resumo e Scatterplot. 22 Tabela 1 Requisitos Funcionais # Requisito Funcional Função RF-1 Criar novo arquivo. RF-2 Abrir arquivo existente. RF-3 Fechar arquivo. RF-4 Salvar arquivo. RF-5 Salvar arquivo com outro nome. RF-6 Importar arquivo do Excel. RF-7 Importar arquivo de texto. RF-8 Exportar arquivo para Excel. RF-9 Exportar arquivo para texto. RF-10 Copiar seleção. RF-11 Colar valores copiados. RF-12 Limpar seleção. RF-13 Selecionar tudo. RF-14 Desfazer/Refazer última ação RF-15 Encontrar e substituir valores. RF-16 Criar nova coluna. RF-17 Duplicar coluna existente. 23 RF-18 Excluir coluna(s). RF-19 Editar propriedades de coluna: formato, nome, largura, alinhamento. RF-20 Codificar valores de variáveis. RF-21 Normalizar valores de variável. RF-22 Ordenar observações: ordem crescente/decrescente. RF-23 Criar seqüência regular. RF-24 Criar amostra aleatória. RF-25 Preencher valores faltantes pela média dos demais valores ou por uma constante. RF-26 Criar nova linha. RF-27 Excluir linha(s). RF-28 Calcular medidas descritivas: Média aritmética, Erro padrão da média, Desvio padrão, Variância, Coeficiente de variação, 1º Quartil, Mediana, 3º Quartil, Diferença entre 1º e 3º quartis, Soma, Mínimo, Máximo, Amplitude, Número valores perdidos, Número total valores, Número cumulativo, Percentual, Percentual cumulativo, Soma dos quadrados, etc. RF-29 Construir tabelas resumo com medidas descritivas por variável. RF-30 Fazer distribuição de freqüências RF-31 Construir tabelas de freqüências cruzadas RF-32 Exibir gráficos estatísticos: Histograma, Histograma com Curva Normal, Gráfico de Caixas, Gráfico de Intervalos, Gráficos de Barras, Gráficos de Pizza, Gráfico de Séries Temporais, Gráficos de Áreas, Gráficos de distribuição de freqüência, Gráficos Resumo e gráfico Scatterplot RF-33 Exportar os gráficos para arquivos arquivos de imagem 24 RF-34 Imprimir os dados, os resultados, tabelas e gráficos. RF-35 Exportar os resultados para Excel ou arquivo texto. 4.2.2 REQUISITOS NÃO-FUNCIONAIS Os requisitos não-funcionais não são funcionalidades do software mas sim atributos ou características que o sistema deve apresentar e, que podem ou não estar relacionados diretamente às funcionalidades do software. A tabela 2 relaciona os requisitos não-funcionais para o Sistema de Análise Estatística Básica. Tabela 2 Requistos não-funcionais # Requisito nãofuncional RNF-1 RNF-2 Atributo Metáfora Descrição de Aplicação desktop com janelas de formulários e caixas interface de diálogo. Tempo de resposta Ao realizar alguma tarefa estatística ou de manipulação de dados, o resultado deve ser exibido dentro de 5 segundos. RNF-3 Tratamento de erros O sistema deve informar ao usuário de forma clara, caso ocorra algum erro durante a realização das tarefas. RNF-4 Correção O sistema deve apresentar resultados corretos, tanto para resultados de cálculos realizados, quanto para a apresentação de gráficos. RNF-5 Simplicidade O software deve ser fácil de utilizar. RNF-6 Tamanho O software deve ser pequeno (máximo 10 MB), para facilitar a distribuição via download. 25 RNF-7 Robustez O software deve lidar adequadamente com os tipos de dados, avisando o usuário quando alguma incompatibilidade ocorrer. RNF-8 Compatibilidade Capacidade de trabalhar com diversos tipos de arquivos. No mínimo arquivos excel e arquivos de texto. RNF-9 Portabilidade O software deve funcionar em vários sistema operacionais. Windows, Linux, etc. 4.3 CASOS DE USO DE ALTO NÍVEL Um caso de uso é um documento narrativo que descreve a seqüência de eventos de um ator que usa uma sistema para completar um processo(Jacobson,1992). Um caso de uso de alto nível, conta de uma maneira suscinta a interação entre um ator e o sistema, a fim de realizar uma ou mais funcionalidades descritas nos requisitos funcionais. Um ator é um usuário externo direto do sistema, podendo ser pessoas, dispositivos e outros sistemas (qualquer coisa que interaja diretamente com o sistema). Para o nosso sistema identificamos apenas um ator, o usuário do software que, utilizará o software para fazer análises estatísticas. Tendo feito a análise dos requisitos, conseguimos identificar os seguintes casos de uso para o Sistema de Análise Estatística Básica: Manipular Dados, Calcular Medidas Descritivas, Fazer Distibuição de Freqüências e, Construir Gráficos. A princípio não considerávamos a manipulação dos dados como um caso de utilização do software, mas apenas pré-requisito para os casos de uso de análise estatística. No entanto, percebemos que nada impede que o usuário use o software apenas para manipular os dados, sem fazer qualquer análise estatística nos mesmos, e depois exporte dados para o excel e utilize os dados modificados para outra finalidade. As tabelas 4.3, 4.4, 4.5 e 4.6 mostram os casos de uso de alto nível identificados para o Sistema de Análise Estatística Básica. 26 Tabela 3 Caso de uso de alto nível 1 Caso de uso: Gerenciar Arquivos Atores: Usuário Visão geral: Um usuário inicia o sistema, e carrega uma arquivo, abrindo um arquivo pré-existente. Opcionalmente o usuário pode importar de um arquivo do Excel ou arquivo de texto. Após concluir as alterações desejadas o usuário fecha o arquivo salvando suas alterações ou exportando para o Excel ou arquivo de texto. Referências Funções: RF-1 a RF-9, RF-34 cruzadas: Tabela 4 Caso de uso de alto nível 2 Caso de uso: Manipular dados Atores: Usuário Visão geral: Um usuário inicia o sistema, e carrega uma arquivo, abrindo um arquivo pré-existente ou importando um arquivo do excel ou arquivo texto. Então manipula os dados executando as várias opções disponíveis no software, tais como ordenar os dados, criar seqüências regulares, etc. Após concluir as alterações desejadas o usuário salva ou exporta os dados, para uso em outra aplicação. Referências cruzadas: Funções: RF-1 a RF-27, RF-34 27 Tabela 5 Caso de uso de alto nível 3 Caso de uso: Calcular medidas descritivas Atores: Usuário Visão geral: Um usuário inicia o sistema, e carrega uma arquivo, abrindo um arquivo pré-existente ou importando um arquivo do excel ou arquivo texto. Então escolhe Medidas Descritivas. Na janela exibida pelo sistema escolhe as variáveis e, as opções de medidas disponíveis e executa os cálculos. Após concluir os cálculos desejados o usuário imprime ou exporta os resultados, para uso em outra aplicação. Referências Funções: RF-1 a RF-9, RF-28, RF-29, RF-34, RF-35 cruzadas: Tabela 6 Caso de uso de alto nível 4 Caso de uso: Fazer distribuição de freqüências Atores: Usuário Visão geral: Um usuário inicia o sistema, e carrega uma arquivo, abrindo um arquivo pré-existente ou importando um arquivo do excel ou arquivo texto. Então escolhe Distribuição de Freqüências. Na janela exibida pelo sistema escolhe a variável para fazer a distribuição de freqüência. Após concluir as distribuições de freqüências o usuário imprime ou exporta os resultados, para uso em outra aplicação. Referências cruzadas: Funções: RF-1 a RF-9, RF-30, RF-31, RF-34, RF-35 28 Tabela 7 Caso de uso de alto nível 5 Caso de uso: Construir Gráficos Atores: Usuário Visão geral: Um usuário inicia o sistema, e carrega uma arquivo, abrindo um arquivo pré-existente ou importando um arquivo do excel ou arquivo texto. Então escolhe Gráficos, e escolhe um dos gráficos disponíveis. Na janela exibida pelo sistema escolhe as variáveis de acordo com o tipo de gráfico. Após construir o gráfico o usuário imprime ou exporta o gráfico para um arquivo de imagem, para uso em outra aplicação. Referências Funções: RF-1 a RF-9, RF-32 a RF-35 cruzadas: Neste capítulo definimos o sistema dando uma visão geral dos requisitos e dos casos de uso do sistema que servirão como ponto de partida para a etapa de análise onde construiremos modelos mais detalhados do domínio do problema, que por sua vez servirão como ponto de partida para o projeto. A Figura 2 mostra o diagrama UML dos casos de uso definidos para o sistema. 29 Figura 2 Diagrama de Casos de Uso do Sistema 5 ANÁLISE Na etapa anterior do projeto definimos os requisitos e os casos de uso em um alto nível, de abstração. Ou seja, definimos o que o sistema deve fazer. Agora começamos o desenvolvimento propriamente dito, através de várias iterações, onde a cada ciclo de desenvolvimento passamos pelas etapas de análise, projeto e implementação, tendo como resultado, de cada iteração, uma versão do software funcionando. Verificamos as dependências entre os casos de uso levantados, e distribuímos os casos de uso em cinco ciclos de desenvolvimento, conforme está descrito na tabela 8 a seguir: 30 Tabela 8 Escalonamento dos casos de uso Ciclo/Iteração Casos de Uso Prazo 1 Gerenciar Arquivos 31 de Dezembro de 2007 2 Manipular Dados 31 de Janeiro de 2008 3 Fazer Distribuição de Freqüências 28 de Fevereiro de 2008 4 Calcular Medidas Descritivas 31 de Março de 2008 5 Construir Gráficos 30 de Abril de 2008 5.1 CASOS DE USO EXPANDIDOS Segundo (Larman, 2000), um caso de uso expandido descreve um processo com mais detalhes. A diferença básica em relação a um caso de uso de alto nível é que, o caso de uso expandido tem uma seção Seqüência típica de eventos, a qual descreve os eventos passo a passo. Não escreveremos o caso de uso expandido para o caso de uso de alto nível Gerenciar Arquivos. Achamos desnecessário escrever detalhadamente este caso de uso por vários motivos. Primeiro porque, gerenciar arquivos é uma tarefa comum de qualquer software e, suas seqüências de abrir, fechar, salvar, etc. já são bem conhecidas. Segundo porque é um caso de uso secundário, que não faz parte das funcionalidades essenciais do sistema o qual, objetiva a análise estatística descritiva. Para os demais casos de uso de alto nível, escreveremos os casos de uso expandidos, cada um em seu respectivo ciclo de desenvolvimento, quando só então serão anexados a esta seção do documento. 31 5.2 MODELO CONCEITUAL No modelo conceitual de análise fizemos a abstração dos conceitos mais relevantes do domínio do problema e deixamos os detalhes para as etapas de projeto e implementação. A figura 3 ilustra o digrama de classes com os principais conceitos do domínio do problema e, na seqüência damos uma breve descrição de cada classe do diagrama. Figura 3 Diagrama de Classes do Domínio do Problema A classe Dados representa uma tabela de dados que o usuário está analisando. Uma tabela de Dados contém um conjunto de objetos da classe Observação, que por sua vez 32 representa uma linha da tabela. Em Estatística uma Observação também é chamada de “elemento”. A classe Valor representa os dados propriamente ditos e como podemos ver no diagrama de classes, cada valor de dados está associado a uma Variável. A classe denominada Variável representa uma coluna na tabela de Dados e é quem dá significado ao conjunto de valores de cada Observação. Uma Variável, segundo a Estatística, pode ser classificada em dois grupos. Variável Quantitativa e Variável Qualitativa. As variáveis qualitativas são formadas por valores que representam categorias, como está representado no diagrama pela associação entre a classe VariavelQualitativa e a classe Categoria. É importante dizer que em Estatística as variáveis qualitativas podem ainda ser ordinais, o que significa que as categorias obedecem a uma certa ordem, e que as variáveis quantitativas podem ser divididas em discretas (números inteiros) e, contínuas. As contínuas são as que podem assumir qualquer valor dentro de um intervalo contínuo de valores. Desenhamos também no diagrama de classes, uma classe denominada Estatistica que, será responsável pelos processos estatíssticos no software, tais como realizar os cálculos de medidas descritivas e fazer a distribuição de freqüências. Por fim, representamos também no diagrama a classe Grafico. Esta classe representa os gráficos estatísticos que o software será capaz de produzir. Ela não será responsável por construir os gráficos. Como veremos na etapa de projeto a construção de gráficos será delegada a uma biblioteca Java com esse fim. A classe gráfico então, será uma classe controladora responsável por manipular as solicitações do usuário, referente a construção de gráficos e repassar os dados para a biblioteca Java no formato por ela esperados. A fase de análise enfatiza a compreenção dos resquisitos, dos conceitos e das operações do sistema, através da criação de diversos artefatos, tais como Casos de Uso, Modelo Conceitual, Diagramas de Seqüência e Contratos do sistema. Nesta primeira iteração, definimos os requisitos do software e, identificamos os Casos de Uso do sistema. Desenhamos também um diagrama de classes com o modelo conceitual onde identificamos os conceitos básicos envolvidos no sistema. No próximo ciclo de análise, enforcaremos na escrita dos Casos de Uso Expandidos, no desenho de diagramas de seqüência e na definição dos contratos do sistema, conforme escalonamento de Casos de Uso da Tabela 8, mostrada anteriormente. 33 6 PROJETO A análise trata do quê uma aplicação deve fazer e o projeto trata do como deve fazer. Nesta primeira iteração de projeto vamos então, definir a arquitetura do sistema e as classes de projeto, com base nas classes de domínio do sistema, definidas na etapa de análise e com base na arquitetura que será definida a seguir. 6.1 ARQUITETURA DO SISTEMA Como falamos no capítulo sobre o Processo Unificado, ele é um processo centrado em casos de uso e na arquitetura, alem de ser iterativo e incremental. Bem, é na etapa de projetos que definimos a arquitetura e, decidimos aplicar a arquitetura MVC, do inglês Model View Controller em nosso projeto. Os padrões de projeto arquiteturais como, é o caso do MVC incentivam o baixo acoplamento entre os subsistemas que compõem o software. O padrão MVC (Modelo, Visão e Controle) divide as responsabilidades do sistema em três partes: o modelo, contém todos os dados e a lógica do programa; a visão, fornece a apresentação visual para o modelo e; o controle, define o comportamento do sistema enviando a entrada do usuário para o modelo. Usando o controle, o usuário altera os dados no modelo. O modelo, então, informa à visão sobre a alteração nos dados. A visão altera sua apresentação visual para refletir as alterações no modelo [6]. Uma vantagem fundamental do padrão de arquitetura MVC é que os desenvolvedores podem modificar cada parte individualmente sem ter que modificar as outras partes. Por exemplo, os desenvolvedores podem modificar a componente visão do sistema, que representa a interface com o usuário, sem ter que fazer qualquer alteração nos componentes, controle ou modelo. 34 O objetivo da utilização dessa arquitetura no desenvolvimento do software proposto, é simplificar o processo de desenvolvimento através da divisão do problema em partes que tem propósitos diferentes e, da correta atribuição de responsabilidades. Na seção 6.2 fizemos a adequação do diagrama de classes, definido na etapa de análise, à arquitetura MVC e, explicamos as principais responsbilidades das classes. 6.2 CLASSES DE PROJETO A Figura 4, mostra o diagrama de classes de projeto que, aprimora o diagrama conceitual, adicionando classes reais (não apenas conceitos) que, na fase de implementação deverão ser codificadas em um programa de computador. Como pode ser visto no diagrama, distribuimos as classes em três pacotes diferentes, cada um contendo classes de Visão, Controle e Modelo do sistema. Figura 4 Diagram de Casses de Projeto 35 Segundo (Blaha; Rumbagh, 2006), um pacote é um grupo de elementos (classes, associações, generalizações e pacotes menores) com um tema comum. Um pacote particiona um modelo, tornando-o mais fácil de entender e gerenciar. Na Figura 4 temos um pacote maior, com a inscrição Sistema na parte superior que, representa o Sistema como um todo. Dentro do pacode Sistema temos três pacotes menores denominados de Visão, Controle e Modelo, contendo respectivamente, as classes que representam a interface com o usuário, as classes que controlam o comportamento do sistema e as classes que contém os dados e a lógica da aplicação. Um dos objetivos da Análise e Projeto Orientado à Objetos é o reaproveitamento de código. Buscamos portanto, utilizar bibliotecas externas de modo a simplificar o desenvolvimento do software. No caso, para o Sistema de Análise Estatística Básica, encontramos duas bibliotecas Java que nos pouparam muito trabalho. Delegamos a funcionalidade de importar/exportar arquivos do Excel a biblioteca JavaExcelAPI. A classe de controle C_Arquivo, será responsável pelo gerenciamento de arquivos, e fará a interação do Sistema com essa biblioteca externa quando o usuário quiser importar/exportar arquivos do Excel. Além disso, a classe C_Arquivo também será responsável por abrir, fechar e salvar arquivos do próprio software. Outra biblioteca Java que será de grande valia para o software, é a biblioteca JfreeChart a qual, delegamos as funcionalides de criação e exibição de gráficos. A classe C_Estatistica será responsável por controlar a interação do Sistema com a biblioteca JfreeChart. Note que a classe Gráfico que aparecia no modelo conceitual de análise foi retirada do diagrama de classes de projeto, visto que este conceito já é inteiramente modelado pela biblioteca JfreeChart. A classe controladora C_Estatistica também controlará a classe E_Estatistica que modela a lógica do Sitema, sendo portanto, responsável por fazer os cáculos estatísticos e as distribuições de freqüências. As demais classes do pacote Modelo são as mesmas definidas na etapa de análise e representam o modelo de dados da aplicação. O pacote Visão tem duas classes. A classe V_Principal que modela a visão principal do sistema, com a qual o usuário irá interagir para realizar suas atividades de análise. E a classe V_Dados que será responsável por exibir os dados ao usuário através de um tabela, e permitir o usuário manipular os dados. 36 7 IMPLEMENTAÇÃO Na etapa de implementação, devemos traduzir os artefatos de projeto em uma linguagem de programação, banco de dados ou hardware específicos. Buscando alcançar os objetivos de colocar em prática os conhecimentos adquiridos no curso, e de desenvolver um software simples, pequeno e de código livre, pretende-se implementar o sistema utilizando a linguagem de programação Java. Primeiro porque é uma linguagem livre e com uma vasta coleção de bibliotecas livres disponíveis na internet e, segundo porque é a linguagem de programação ensinada no curso e, portanto a linguagem de programação que o autor do trabalho tem domínio suficiente para poder desenvolver o software. Como ferramenta de desenvolvimento para a implementação do sistema, escolhemos a IDE (Interface Development Environment) NetBeans 5.5 que, é uma das mais completas e populares ferramentas livres, para programação Java. Embora existam plugins para o NetBeans, para modelagem UML, escolhemos o Jude Community 5.1. É uma ferramenta mais simples, mas excelente para a modelagem UML e, tem a funcionalidade de geração de código Java apartir do modelo de classes. Para encerrar este primeiro ciclo de desenvolvimento, desenvolvemos um protótipo mínimo que será descrito na seção 7.1. 7.1 PROTÓTIPO DE INTERFACE COM USUÁRIO Na fase inicial do presente trabalho, sentimos a necessidade de desenvolver um protótipo, com os seguintes objetivos. Primeiro compreender melhor os requisitos do sistema e segundo sentir as difilcudades reais de implementação do sistema. O protótipo foi desnvolvido em Java, com a utilização do NetBeans e, embora o NetBeans ofereça ferramentas de desenho de interfaces Java Swing, a manipulação dos dados da tabela não foi nada fácil. A idéia inicial era ancontrar alguma biblioteca Java que já implementasse uma Spreadsheet(estilo planilha do Excel), maximizando o reaproveitamento de código, mas não encontramos nada de código livre que se adequasse ao nosso projeto. 37 Esse protótipo persite os arquivos simplismente através do uso de serialização de objetos do Java e importa e exporta arquivos do Excel, através da biblioteca Java JavaExcelAPI, exibindo os dados em uma Jtable (Uma JTable é um componente gráfico do Java Swing que implementa a visão de uma tabela). Possui também um menu Estatística que já permite a geração de alguns gráficos simples através da utilização da biblioteca JfreeChart. A seguir as Figuras 5 e Figura 6, mostra alguns PrintScreen da interface desse protótipo e, no ANEXO A mostramos o código fonte. Figura 5 Tela Principal do Protótipo com um arquivo importado do Excel 38 A Figura 5 mostra o menu “Arquivo” aberto e uma tabela . A tabela exibe os dados de um arquivo que foi importado do Excel acionando o item “Importar Arquivo...” do menu “Arquivo”. Figura 6 Tela com gráfico construido pelo protótipo A Figura 6 mostra o menu “Gráficos” aberto e um gráfico de barras que foi produzido quando acionamos o item “Barras Verticais” do menu “Gráficos”. 39 8 8.1 CONSIDERAÇÕES FINAIS OBJETIVOS ATINGIDOS A conclusão desta etapa do trabalho resultou alguns artefatos tais como, requisitos funcionais e não-funcionais, casos de uso, modelo conceitual, definição da arquitetura do sistema e a implementação de um protótipo. Desejávamos estar mais adiantados no desnvolvimento do projeto, mas acabamos gastantando mais tempo do que o esperado na análise de requisitos. Contudo, refizemos o nosso planejamento, conforme repetição da Tabela 8 a seguir, e pretendemos concluir o projeto em tempo hábil. Tabela 8 Escalonamento dos casos de uso Ciclo/Iteração Casos de Uso Prazo 1 Gerenciar Arquivos 31 de Dezembro de 2007 2 Manipular Dados 31 de Janeiro de 2008 3 Fazer Distribuição de Freqüências 28 de Fevereiro de 2008 4 Calcular Medidas Descritivas 31 de Março de 2008 5 Construir Gráficos 30 de Abril de 2008 40 REFERÊNCIAS BARBETTA, Pedro Alberto. Estatística Aplicada às Ciências Sociais 5. ed. revisada Florianópolis: Ed. Da UFSC, 2002. COSTA NETO, Pedro Luiz de Oliveira. Estatística. São Paulo: Edgard Blücher, 1977. BLAHA, Michael; RUMBAUGH, James Modelagem e Projetos Baseados em Objetos com UML 2: Segunda Edição Revisada e Atualizada. Tradução: Daniel Vieira. Rio de Janeiro: Elsevier, 2006. LARMAN, Craig. R. Utilizando UML e Padrões: uma introdução à análise e ao projeto orientado a objetos. Tradução Luiz A. Meirelles Salgado. – Porto Alegre, 2000. SILVA, Alberto; VIDEIRA, Carlos UML, Metodologias e Ferramentas Case. Edições Centro Atlântico – Portugal/2001. Deitel, H. M.; Deitel, P. J. Java, como programar. 4Ed. Tradução: Carlos Arthur Lang Lisboa. Porto Alegre: Bookman, 2003. 41 ANEXO A – CÓDIGO FONTE DO 1º PROTÓTIPO DO SISTEMA Classe VisaoPrincipal package View; // Java core packages import Controller.ControleArquivos; import Controller.ControleEstatistica; import Controller.ControleExcel; import Controller.FiltroExcel; import Model.Dados; import Model.TableModel; import java.io.*; import java.util.Vector; // Java extension packages import javax.swing.*; import jxl.read.biff.BiffException; import jxl.write.WriteException; public class VisaoPrincipal extends javax.swing.JFrame { private javax.swing.UIManager.LookAndFeelInfo looks[]; private ImageIcon icon; private javax.swing.JInternalFrame frame; /** Creates new form VisaoPrincipal */ public VisaoPrincipal() { initComponents(); icon = new ImageIcon(getClass().getResource("imagens/h_statistic.gif")); setIconImage(icon.getImage()); looks = javax.swing.UIManager.getInstalledLookAndFeels(); try { javax.swing.UIManager.setLookAndFeel( looks[2].getClassName()); javax.swing.SwingUtilities.updateComponentTreeUI(this); } catch (InstantiationException ex) { JOptionPane.showMessageDialog(this,ex.getMessage(),"SAEB Erro",JOptionPane.ERROR_MESSAGE,icon); } catch (IllegalAccessException ex) { JOptionPane.showMessageDialog(this,ex.getMessage(),"SAEB Erro",JOptionPane.ERROR_MESSAGE,icon); } catch (UnsupportedLookAndFeelException ex) { 42 JOptionPane.showMessageDialog(this,ex.getMessage(),"SAEB Erro",JOptionPane.ERROR_MESSAGE,icon); } catch (ClassNotFoundException ex) { JOptionPane.showMessageDialog(this,ex.getMessage(),"SAEB Erro",JOptionPane.ERROR_MESSAGE,icon); } } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ // <editor-fold defaultstate="collapsed" desc=" Generated Code "> private void initComponents() { desktop = new javax.swing.JDesktopPane(); barrMenu = new javax.swing.JMenuBar(); menuArquivo = new javax.swing.JMenu(); abrirArquivo = new javax.swing.JMenuItem(); fecharArquivo = new javax.swing.JMenuItem(); novoArquivo = new javax.swing.JMenuItem(); salvarArquivo = new javax.swing.JMenuItem(); salvarComo = new javax.swing.JMenuItem(); jSeparator1 = new javax.swing.JSeparator(); importarExcel = new javax.swing.JMenuItem(); exportarExcel = new javax.swing.JMenuItem(); jSeparator2 = new javax.swing.JSeparator(); sairSAEB = new javax.swing.JMenuItem(); menuGraficos = new javax.swing.JMenu(); graficoPizza = new javax.swing.JMenuItem(); graficoBarrasV = new javax.swing.JMenuItem(); graficoBarrasH = new javax.swing.JMenuItem(); menuAjuda = new javax.swing.JMenu(); menuSobre = new javax.swing.JMenuItem(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle("SAEB - Sistema de An\u00e1lise Estat\u00edstica B\u00e1sica"); setIconImage(getIconImage()); setLocationByPlatform(true); desktop.setMinimumSize(new java.awt.Dimension(200, 150)); desktop.setPreferredSize(new java.awt.Dimension(760, 560)); getContentPane().add(desktop, java.awt.BorderLayout.CENTER); menuArquivo.setText("Arquivo"); abrirArquivo.setText("Abrir..."); abrirArquivo.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { abrirArquivoActionPerformed(evt); } }); 43 menuArquivo.add(abrirArquivo); fecharArquivo.setText("Fechar"); fecharArquivo.setEnabled(false); menuArquivo.add(fecharArquivo); novoArquivo.setText("Novo..."); novoArquivo.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { novoArquivoActionPerformed(evt); } }); menuArquivo.add(novoArquivo); salvarArquivo.setText("Salvar"); salvarArquivo.setEnabled(false); salvarArquivo.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { salvarArquivoActionPerformed(evt); } }); menuArquivo.add(salvarArquivo); salvarComo.setText("Salvar como..."); salvarComo.setEnabled(false); salvarComo.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { salvarComoActionPerformed(evt); } }); menuArquivo.add(salvarComo); menuArquivo.add(jSeparator1); importarExcel.setText("Importar arquivo..."); importarExcel.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { importarExcelActionPerformed(evt); } }); menuArquivo.add(importarExcel); exportarExcel.setText("Exportar arquivo..."); exportarExcel.setEnabled(false); exportarExcel.addActionListener(new java.awt.event.ActionListener() { 44 public void actionPerformed(java.awt.event.ActionEvent evt) { exportarExcelActionPerformed(evt); } }); menuArquivo.add(exportarExcel); menuArquivo.add(jSeparator2); sairSAEB.setText("Sair"); sairSAEB.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { sairSAEBActionPerformed(evt); } }); menuArquivo.add(sairSAEB); barrMenu.add(menuArquivo); menuGraficos.setText("Gr\u00e1ficos"); graficoPizza.setText("Pizza"); graficoPizza.setEnabled(false); graficoPizza.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { graficoPizzaActionPerformed(evt); } }); menuGraficos.add(graficoPizza); graficoBarrasV.setText("Barras Verticais"); graficoBarrasV.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { graficoBarrasVActionPerformed(evt); } }); menuGraficos.add(graficoBarrasV); graficoBarrasH.setText("Barras Horizontais"); graficoBarrasH.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { graficoBarrasHActionPerformed(evt); } }); menuGraficos.add(graficoBarrasH); barrMenu.add(menuGraficos); 45 menuAjuda.setText("Ajuda"); menuSobre.setText("Sobre o sistema..."); menuSobre.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuSobreActionPerformed(evt); } }); menuAjuda.add(menuSobre); barrMenu.add(menuAjuda); setJMenuBar(barrMenu); pack(); }// </editor-fold> private void graficoBarrasHActionPerformed(java.awt.event.ActionEvent evt) { criarGraficoBarrasH(); } private void graficoBarrasVActionPerformed(java.awt.event.ActionEvent evt) { criarGraficoBarrasV(); } private void graficoPizzaActionPerformed(java.awt.event.ActionEvent evt) { criarGraficoPizza(); } private void exportarExcelActionPerformed(java.awt.event.ActionEvent evt) { exportarExcel(); } private void importarExcelActionPerformed(java.awt.event.ActionEvent evt) { importarExcel(); } private void menuSobreActionPerformed(java.awt.event.ActionEvent evt) { javax.swing.JOptionPane.showMessageDialog(null, "\nSAEB - Sistema de Análise Estatística Básica\n\n" + "Versão: Protótipo de interface\n\nAutor: Wanderlei Passos\n\n" + "Data: 27/08/2007","Sobre o sistema",javax.swing.JOptionPane.INFORMATION_MESSAGE); } private void salvarComoActionPerformed(java.awt.event.ActionEvent evt) { salvarComo(); } 46 private void sairSAEBActionPerformed(java.awt.event.ActionEvent evt) { frame.doDefaultCloseAction(); System.exit(0); } private void novoArquivoActionPerformed(java.awt.event.ActionEvent evt) { novoArquivo(); } private void salvarArquivoActionPerformed(java.awt.event.ActionEvent evt) { salvarArquivo(); } private void abrirArquivoActionPerformed(java.awt.event.ActionEvent evt) { abrirArquivo(); } private void novoFrame(String nomeArquivo, TableModel novosDados){ frame = new VisaoDados(novosDados); frame.setClosable(true); frame.setIconifiable(true); frame.setMaximizable(true); frame.setResizable(true); frame.setTitle(nomeArquivo); desktop.add(frame, javax.swing.JLayeredPane.DEFAULT_LAYER); frame.addInternalFrameListener(new javax.swing.event.InternalFrameListener() { public void internalFrameActivated(javax.swing.event.InternalFrameEvent evt) { } public void internalFrameClosed(javax.swing.event.InternalFrameEvent evt) { frameInternalFrameClosed(evt); } public void internalFrameClosing(javax.swing.event.InternalFrameEvent evt) { } public void internalFrameDeactivated(javax.swing.event.InternalFrameEvent evt) { } public void internalFrameDeiconified(javax.swing.event.InternalFrameEvent evt) { } public void internalFrameIconified(javax.swing.event.InternalFrameEvent evt) { } public void internalFrameOpened(javax.swing.event.InternalFrameEvent evt) { } }); frame.setVisible(true); abrirArquivo.setEnabled(false); novoArquivo.setEnabled(false); salvarArquivo.setEnabled(true); 47 salvarComo.setEnabled(true); fecharArquivo.setEnabled(true); importarExcel.setEnabled(false); exportarExcel.setEnabled(true); graficoPizza.setEnabled(true); } public void frameInternalFrameClosed(javax.swing.event.InternalFrameEvent evt) { abrirArquivo.setEnabled(true); novoArquivo.setEnabled(true); salvarArquivo.setEnabled(false); salvarComo.setEnabled(false); fecharArquivo.setEnabled(false); importarExcel.setEnabled(true); exportarExcel.setEnabled(false); graficoPizza.setEnabled(false); } public void fecharArquivo(){ frame.dispose(); } private void importarExcel(){ JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileFilter(new FiltroExcel()); fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY ); int resultado = fileChooser.showOpenDialog( this ); if ( resultado == JFileChooser.CANCEL_OPTION ) return; File arquivo = fileChooser.getSelectedFile(); TableModel novosDados = null; try { novosDados = ControleExcel.importarExcel(arquivo); } catch (BiffException ex) { JOptionPane.showMessageDialog(this,ex.getMessage(),"SAEB Erro",JOptionPane.ERROR_MESSAGE,icon); } catch (IOException ex) { JOptionPane.showMessageDialog(this,ex.getMessage(),"SAEB Erro",JOptionPane.ERROR_MESSAGE,icon); } if (!(novosDados == null) ){ novoFrame(arquivo.getName(),novosDados); } } 48 private void abrirArquivo(){ TableModel novosDados = null; JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY ); int resultado = fileChooser.showOpenDialog( this ); if ( resultado == JFileChooser.CANCEL_OPTION ) return; File arquivo = fileChooser.getSelectedFile(); try { novosDados = ControleArquivos.abrirArquivo(arquivo); } catch (IOException ex) { JOptionPane.showMessageDialog(this,ex.getMessage(),"SAEB Erro",JOptionPane.ERROR_MESSAGE,icon); } catch (ClassNotFoundException ex) { JOptionPane.showMessageDialog(this,ex.getMessage(),"SAEB Erro",JOptionPane.ERROR_MESSAGE,icon); } if (! (novosDados == null) ){ novoFrame(arquivo.getName(),novosDados); } } private void novoArquivo() { Vector nomeColunas = new Vector(0); String retorno = ""; while(retorno != null){ if(retorno != ""){ nomeColunas.addElement(retorno); } retorno = JOptionPane.showInputDialog( "Informe o nome da variável e click em Ok.\nPara terminar click em Cancel."); } int numObservacoes = 0; int numVariaveis = nomeColunas.size(); String strNomeColunas[] = new String[numVariaveis]; for(int i = 0; i < numVariaveis; i++){ strNomeColunas[i] = (String) nomeColunas.elementAt(i); } TableModel novosDados = ControleArquivos.novoArquivo(strNomeColunas); 49 if ( !(novosDados == null) ){ novoFrame("Novo arquivo",novosDados); }else JOptionPane.showMessageDialog(this, "Não foi possível criar o arquivo", "Erro ao criar o arquivo", JOptionPane.ERROR_MESSAGE ); } private void salvarArquivo() { boolean arquivoSalvo = ControleArquivos.eArquivoSalvo(); if(!arquivoSalvo){ salvarComo(); }else{ try { ControleArquivos.salvarArquivo(); } catch (IOException ex) { JOptionPane.showMessageDialog(this,ex.getMessage(),"SAEB Erro",JOptionPane.ERROR_MESSAGE,icon); } } } private void salvarComo() { JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY ); int resultado = fileChooser.showSaveDialog( this ); if ( resultado == JFileChooser.CANCEL_OPTION ) return; File arquivo = fileChooser.getSelectedFile(); frame.setTitle(arquivo.getName()); try { ControleArquivos.salvarComo(arquivo); } catch (IOException ex) { JOptionPane.showMessageDialog(this,ex.getMessage(),"SAEB Erro",JOptionPane.ERROR_MESSAGE,icon); } } // Variables declaration - do not modify private javax.swing.JMenuItem abrirArquivo; private javax.swing.JMenuBar barrMenu; private javax.swing.JDesktopPane desktop; private javax.swing.JMenuItem exportarExcel; private javax.swing.JMenuItem fecharArquivo; 50 private javax.swing.JMenuItem graficoBarrasH; private javax.swing.JMenuItem graficoBarrasV; private javax.swing.JMenuItem graficoPizza; private javax.swing.JMenuItem importarExcel; private javax.swing.JSeparator jSeparator1; private javax.swing.JSeparator jSeparator2; private javax.swing.JMenu menuAjuda; private javax.swing.JMenu menuArquivo; private javax.swing.JMenu menuGraficos; private javax.swing.JMenuItem menuSobre; private javax.swing.JMenuItem novoArquivo; private javax.swing.JMenuItem sairSAEB; private javax.swing.JMenuItem salvarArquivo; private javax.swing.JMenuItem salvarComo; // End of variables declaration /** * @param args the command line arguments */ public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new VisaoPrincipal().setVisible(true); } }); } public void exportarExcel() { JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileFilter(new FiltroExcel()); fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY ); int resultado = fileChooser.showSaveDialog( this ); if ( resultado == JFileChooser.CANCEL_OPTION ) return; File arquivo = fileChooser.getSelectedFile(); try { ControleExcel.exportarExcel(arquivo); } catch (WriteException ex) { JOptionPane.showMessageDialog(this,ex.getMessage(),"SAEB Erro",JOptionPane.ERROR_MESSAGE,icon); } catch (IOException ex) { JOptionPane.showMessageDialog(this,ex.getMessage(),"SAEB Erro",JOptionPane.ERROR_MESSAGE,icon); 51 } } private void criarGraficoPizza() { Dados dados = ControleArquivos.getDados(); String[] selecao = dados.getNomesColunas(); String variavel = (String) JOptionPane.showInputDialog(this,"Escolha a variável para a qual você deseja criar o gráfico de pizza.", "Gráfico de Pizza",JOptionPane.INFORMATION_MESSAGE,icon,selecao, selecao[0]); ControleEstatistica.graficoPizza(variavel); } private void criarGraficoBarrasH() { Dados dados = ControleArquivos.getDados(); String[] selecao = dados.getNomesColunas(); String variavel = (String) JOptionPane.showInputDialog(this,"Escolha a variável para a qual você deseja criar o gráfico de pizza.", "Gráfico de Pizza",JOptionPane.INFORMATION_MESSAGE,icon,selecao, selecao[0]); ControleEstatistica.graficoBarraHorizontal(variavel); } private void criarGraficoBarrasV() { Dados dados = ControleArquivos.getDados(); String[] selecao = dados.getNomesColunas(); String variavel = (String) JOptionPane.showInputDialog(this,"Escolha a variável para a qual você deseja criar o gráfico de pizza.", "Gráfico de Pizza",JOptionPane.INFORMATION_MESSAGE,icon,selecao, selecao[0]); ControleEstatistica.graficoBarraVertical(variavel); } } Classe VisaoDados package View; import Model.TableModel; import java.awt.Component; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JInternalFrame; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.JScrollPane; 52 import javax.swing.JTable; public class VisaoDados extends JInternalFrame { protected JTable table; protected JScrollPane scroller; protected TableModel tableModel; public VisaoDados(TableModel tableModel) { this.tableModel = tableModel; initComponent(); } public void initComponent() { tableModel.addTableModelListener(new VisaoDados.InteractiveTableModelListener()); table = new JTable(); table.setModel(tableModel); table.setCellSelectionEnabled(true); table.setAutoResizeMode(table.AUTO_RESIZE_OFF); table.setSurrendersFocusOnKeystroke(true); table.setFillsViewportHeight(true); table.setAutoCreateRowSorter(true); if (!tableModel.hasEmptyRow()) { //tableModel.addEmptyRow(); } scroller = new javax.swing.JScrollPane(table); table.setPreferredScrollableViewportSize(new java.awt.Dimension(500, 300)); TableColumn hidden = table.getColumnModel().getColumn(tableModel.getColumnCount() - 1); hidden.setMinWidth(2); hidden.setPreferredWidth(2); hidden.setMaxWidth(2); hidden.setCellRenderer(new InteractiveRenderer(tableModel.getColumnCount() - 1)); org.jdesktop.layout.GroupLayout frameInternoLayout = new org.jdesktop.layout.GroupLayout(this.getContentPane()); this.getContentPane().setLayout(frameInternoLayout); frameInternoLayout.setHorizontalGroup( frameInternoLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(scroller, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE) ); frameInternoLayout.setVerticalGroup( frameInternoLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(frameInternoLayout.createSequentialGroup() 53 .add(scroller, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 1000, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE) .addContainerGap(32, Short.MAX_VALUE)) ); this.setBounds(5, 5, 700, 500); } public void highlightLastRow(int row) { int lastrow = tableModel.getRowCount(); if (row == lastrow - 1) { table.setRowSelectionInterval(lastrow - 1, lastrow - 1); } else { table.setRowSelectionInterval(row + 1, row + 1); } table.setColumnSelectionInterval(0, 0); } class InteractiveRenderer extends DefaultTableCellRenderer { protected int interactiveColumn; public InteractiveRenderer(int interactiveColumn) { this.interactiveColumn = interactiveColumn; } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if (column == interactiveColumn && hasFocus) { if ((tableModel.getRowCount() - 1) == row && !tableModel.hasEmptyRow()) { tableModel.addEmptyRow(); } highlightLastRow(row); } return c; } } public class InteractiveTableModelListener implements TableModelListener{ public void tableChanged(TableModelEvent evt) { if (evt.getType() == TableModelEvent.UPDATE) { int column = evt.getColumn(); int row = evt.getFirstRow(); System.out.println("row: " + row + " column: " + column); table.setColumnSelectionInterval(column + 1, column + 1); table.setRowSelectionInterval(row, row); 54 } } } } Classe TableModel package Model; import java.util.Vector; import javax.swing.table.AbstractTableModel; public class TableModel extends AbstractTableModel { private Dados dados; protected String[] columnNames; protected Vector dataVector; public TableModel(Dados novosDados) { String columnNameTemp[] = novosDados.getNomesColunas(); int numCol = columnNameTemp.length; columnNames = new String[numCol + 1]; for(int i = 0; i < numCol; i++){ columnNames[i] = columnNameTemp[i]; } columnNames[numCol] = ""; dataVector = novosDados.getDados(); dados = novosDados; } public String getColumnName(int column) { return columnNames[column]; } public boolean isCellEditable(int row, int column) { if (column == getColumnCount() - 1) return false; else return true; } public Object getValueAt(int row, int column) { if(column < getColumnCount() - 1){ Observacao obs = dados.getElementAt(row); return obs.getElementAt(column); }else return null; } 55 /* * JTable uses this method to determine the default renderer/ * editor for each cell. If we didn't implement this method, * then the last column would contain text ("true"/"false"), * rather than a check box. */ public Class getColumnClass(int c) { return getValueAt(0, c-1).getClass(); } public void setValueAt(Object value, int row, int column) { Observacao obs = dados.getElementAt(row); obs.setElementAt(value,column); fireTableCellUpdated(row, column); } public int getRowCount() { return dataVector.size(); } public int getColumnCount() { return columnNames.length; } public boolean hasEmptyRow() { if ( dados.getDados().size() == 0) return false; Observacao obs = (Observacao) dataVector.get(dataVector.size() - 1); int numVariaveis = obs.getObservacao().size(); for( int i = 0; i < numVariaveis; i++){ if(!((String)obs.getElementAt(i)).equals("")) return false; } return true; } public void addEmptyRow() { Observacao obs = new Observacao(getColumnCount()-1); dataVector.addElement(obs); fireTableRowsInserted( dataVector.size() - 1 , dataVector.size() - 1 ); } } 56 Classe Dados package Model; import java.io.Serializable; import java.util.Vector; /** * * @author usuario */ public class Dados implements Serializable { private String[] nomesColunas; private Vector observacoes; public Dados(String pNomeColunas[]) { nomesColunas = pNomeColunas; observacoes = new Vector(); observacoes.add(new Observacao(pNomeColunas.length)); } public Dados(String pNomeColunas[], Object pDados[][], int numObservacoes) { int numVariaveis = pNomeColunas.length; nomesColunas = pNomeColunas; observacoes = new Vector(0); for( int i = 0; i < numObservacoes; i++){ Observacao obs = new Observacao(numVariaveis); observacoes.addElement(obs); for( int k = 0; k < numVariaveis; k++){ obs.setElementAt(pDados[i][k],k); } } } public void configurarValorEm(Object valor, int linha, int coluna){ Observacao obs = (Observacao) observacoes.elementAt(linha); obs.setElementAt(valor, coluna); } public String[] getNomesColunas() { return nomesColunas; } public Vector getDados() { return observacoes; } /** 57 * Getter for property numObservacoes. * @return Value of property numObservacoes. */ public int getNumDados() { return observacoes.size(); } void addObservacao(Observacao obs) { observacoes.addElement(obs); } public void setNomesColunas(String[] nomesColunas) { this.nomesColunas = nomesColunas; } public Observacao getElementAt(int row) { return (Observacao) observacoes.get(row); } public Vector getVariavel(String variavel){ int indice = getIndiceVariavel( variavel ); Vector vctVariavel = new Vector(); int numObs = observacoes.size(); for(int i = 0; i < numObs; i++){ vctVariavel.addElement(((Observacao)observacoes.elementAt(i)).getElementAt(indice)); } return vctVariavel; } public String getNomeVariavel(int col){ return nomesColunas[col]; } public int getIndiceVariavel(String nome){ int numCol = nomesColunas.length; int indice = -1; for(int i=0 ; i<numCol ; i++){ if(nomesColunas[i].equalsIgnoreCase(nome)){ return i; } } return indice; } } 58 Classe Observação package Model; import java.io.Serializable; import java.util.Vector; public class Observacao implements Serializable{ private Vector observacao; public Observacao(int numVariaveis) { observacao = new Vector(numVariaveis); for( int i = 0; i < numVariaveis; i++){ observacao.addElement(""); } } public Vector getObservacao() { return observacao; } public void addVariavel(Object object) { if(!object.equals(null)){ observacao.addElement(object); }else observacao.addElement(""); } public void setElementAt(Object valor, int coluna) { if(!valor.equals(null) && (String)valor != "" && coluna < observacao.size()){ observacao.setElementAt(valor,coluna); } } public Object getElementAt(int coluna) { Object obj = null; try { obj = observacao.elementAt(coluna); return obj; } catch(ArrayIndexOutOfBoundsException e){ obj = ""; } return obj; } } Classe FrequenciaCategoria 59 package Model; /** * * @author usuario */ public class FrequenciaCategoria { private String categoria; private int frequencia; /** Creates a new instance of FrequenciaCategoria */ public FrequenciaCategoria(String categoria) { this.categoria = categoria; frequencia = 1; } public String getCategoria() { return categoria; } public int getFrequencia() { return frequencia; } public void incrementarFrequencia(){ frequencia++; } } Classe ControladorArquivo package Controller; import Model.Dados; import java.io.File; import Model.TableModel; import java.io.*; public class ControleArquivos { private static Dados dados; private static File arquivo; private static boolean arquivoSalvo = false; public static TableModel novoArquivo(String nomeColunas[]){ dados = new Dados(nomeColunas); TableModel modeloDados = new TableModel(dados); 60 arquivoSalvo = false; return modeloDados; } public static TableModel novoArquivo(String nomeColunas[], Object pDados[][], int numDados){ dados = new Dados(nomeColunas, pDados, numDados); TableModel modeloDados = new TableModel(dados); arquivoSalvo = false; return modeloDados; } public static TableModel abrirArquivo(File novoArquivo) throws IOException, ClassNotFoundException{ dados = null; TableModel modeloDados = null; arquivo = novoArquivo; if ( arquivo == null || arquivo.getName().equals( "" ) ) return null; else { ObjectInputStream input = new ObjectInputStream( new FileInputStream( arquivo ) ); dados = (Dados)input.readObject(); modeloDados = new TableModel(dados); input.close(); arquivoSalvo = true; } return modeloDados; } public static boolean eArquivoSalvo(){ return arquivoSalvo; } public static void salvarArquivo() throws IOException { ObjectOutputStream output = new ObjectOutputStream( new FileOutputStream(arquivo)); output.writeObject(dados); output.flush(); output.close(); arquivoSalvo = true; } public static void salvarComo(File novoArquivo) throws IOException{ arquivo = novoArquivo; salvarArquivo(); } 61 public static Dados getDados(){ return dados; } } Classe ControleExcel package Controller; import Model.Dados; import Model.TableModel; import Model.ModeloDados; import Model.Observacao; import java.io.File; import java.io.IOException; import java.util.Date; import java.util.Vector; import jxl.*; import jxl.read.biff.BiffException; import jxl.write.*; public class ControleExcel { public static TableModel importarExcel(File arquivo) throws IOException, BiffException{ Workbook workbook = null; Sheet sheet; workbook = Workbook.getWorkbook(arquivo); sheet = workbook.getSheet(0); String nomeColunas[] = new String[sheet.getColumns()]; for(int c = 0; c < sheet.getColumns(); c++){ nomeColunas[c] = sheet.getCell(c,0).getContents(); } Object dadosXLS[][] = new Object[sheet.getRows()-1][sheet.getColumns()]; for(int l = 1; l < sheet.getRows(); l++) for(int c = 0; c < sheet.getColumns(); c++){ dadosXLS[l-1][c] = sheet.getCell(c,l).getContents(); } TableModel modDados = ControleArquivos.novoArquivo(nomeColunas, dadosXLS, sheet.getRows()-1); return modDados; } public static void exportarExcel(File arquivo) throws WriteException, IOException{ 62 String nomeArquivo = arquivo.getAbsolutePath(); if(!nomeArquivo.endsWith(".xls")) nomeArquivo += ".xls"; Dados dados = ControleArquivos.getDados(); WritableWorkbook workbook = Workbook.createWorkbook(new File(nomeArquivo)); WritableSheet sheet = workbook.createSheet("Planilha 1", 0); String colunas[] = dados.getNomesColunas(); Vector celulas = dados.getDados(); int numColunas = colunas.length; for(int c = 0; c < numColunas; c++){ Label label = new Label(c, 0, colunas[c]); sheet.addCell(label); } int numLinhas = dados.getNumDados(); for(int l = 0; l < numLinhas; l++){ Observacao obs = (Observacao) celulas.elementAt(l); for(int c = 0; c < numColunas; c++ ){ Label label = new Label(c, l+1, (String)obs.getElementAt(c)); sheet.addCell(label); } } workbook.write(); workbook.close(); } } Classe ControleEstatistica package Controller; import Model.Dados; import Model.FrequenciaCategoria; import java.util.Vector; import java.awt.Color; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFrame; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.PiePlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.data.general.DefaultPieDataset; public class ControleEstatistica { 63 private static Vector distribuicaoFrequencias; public static void graficoPizza(String variavel){ criarDistribuicaoFrequencias(variavel); // create a dataset... int numCategorias = distribuicaoFrequencias.size() -1; DefaultPieDataset dataset = new DefaultPieDataset(); for( int i = 1; i < numCategorias; i++){ FrequenciaCategoria fc = (FrequenciaCategoria) distribuicaoFrequencias.elementAt(i); dataset.setValue( fc.getCategoria(), fc.getFrequencia()); } // create a chart... JFreeChart chart = ChartFactory.createPieChart( "Distribuição de Frequência: \nVariável "+ (String)distribuicaoFrequencias.elementAt(0), dataset, true, // legend? true, // tooltips? true // URLs? ); // create and display a frame... ChartFrame frame = new ChartFrame("Gráfico de Pizza", chart); frame.pack(); frame.setVisible(true); } public static void graficoBarraVertical(String variavel){ criarDistribuicaoFrequencias(variavel); // create a dataset... int numCategorias = distribuicaoFrequencias.size() -1; DefaultCategoryDataset dataset = new DefaultCategoryDataset(); for( int i = 1; i < numCategorias; i++){ FrequenciaCategoria fc = (FrequenciaCategoria) distribuicaoFrequencias.elementAt(i); dataset.addValue(fc.getFrequencia(), fc.getCategoria(), ""); } // create a chart... JFreeChart chart = ChartFactory.createBarChart( "Distribuição de Frequência: \nVariável " + (String)distribuicaoFrequencias.elementAt(0), // chart title (String)distribuicaoFrequencias.elementAt(0), // domain axis label 64 "Freqüência", // range axis label dataset, // data PlotOrientation.VERTICAL, // orientation true, // include legend true, // tooltips? false // URLs? ); // create and display a frame... ChartFrame frame = new ChartFrame("Gráfico de Barras Verticais", chart); frame.pack(); frame.setVisible(true); } public static void graficoBarraHorizontal(String variavel){ criarDistribuicaoFrequencias(variavel); // create a dataset... int numCategorias = distribuicaoFrequencias.size() -1; DefaultCategoryDataset dataset = new DefaultCategoryDataset(); for( int i = 1; i < numCategorias; i++){ FrequenciaCategoria fc = (FrequenciaCategoria) distribuicaoFrequencias.elementAt(i); dataset.addValue(fc.getFrequencia(), fc.getCategoria(), ""); } // create a chart... JFreeChart chart = ChartFactory.createBarChart( "Distribuição de Frequência: \nVariável " + (String)distribuicaoFrequencias.elementAt(0), // chart title (String)distribuicaoFrequencias.elementAt(0), // domain axis label "Freqüência", // range axis label dataset, // data PlotOrientation.HORIZONTAL, // orientation true, // include legend true, // tooltips? false // URLs? ); //controlling de color and outline of section chart //PiePlot plot = (PiePlot) chart.getPlot(); //plot.setForegroundAlpha((float)0.3); // create and display a frame... ChartFrame frame = new ChartFrame("Gráfico de Barras Horizontais", chart); frame.pack(); frame.setVisible(true); } 65 public static void criarDistribuicaoFrequencias(String variavel){ distribuicaoFrequencias = new Vector(); distribuicaoFrequencias.addElement(variavel); Dados dados = ControleArquivos.getDados(); Vector vctVariaveis = dados.getVariavel(variavel); int numVariaveis = vctVariaveis.size(); addCategoria( (String) vctVariaveis.elementAt(0)); for(int i = 1; i < numVariaveis; i++){ String categoria = (String) vctVariaveis.elementAt(i); int indice = getIndiceCategoria(categoria); if(indice == distribuicaoFrequencias.size()){ addCategoria(categoria); }else{ FrequenciaCategoria fc = (FrequenciaCategoria) distribuicaoFrequencias.elementAt(indice); fc.incrementarFrequencia(); } } } public static int getIndiceCategoria(String valor){ int indice = distribuicaoFrequencias.size(); for(int i = 1; i < indice; i++){ FrequenciaCategoria fc = (FrequenciaCategoria) distribuicaoFrequencias.elementAt(i); if(fc.getCategoria().equalsIgnoreCase(valor)){ return i; } } return indice; } public static void addCategoria(String categoria){ FrequenciaCategoria fc = new FrequenciaCategoria(categoria); distribuicaoFrequencias.addElement(fc); } }