O gráfico do Caelum Mock

Por Guilherme de Almeida Moreira em 29/01/07

Eu gostaria de começar esse post já comentando de como eu criei o gráfico, mas eu recomendo aos leitores que visitem a página Caelumock, façam um teste e vejam o gráfico de aproveitamento no final dele, pois é sobre ele que escreverei a partir de agora.

Em geral no JFreechart temos que seguir alguns passos para montar um gráfico, o primeiro deles é definir qual o tipo de gráfico que desejamos montar, pois a partir dessa escolha é que vamos montar o conjunto de dados, o Dataset.

Como conferimos no site, o tipo do gráfico escolhido foi um do tipo de barras. Um gráfico com barras requer um Dataset do tipo categoria.

DefaultCategoryDataset dataset = new DefaultCategoryDataset();

Este tipo de Dataset permite ao usuário definir vários conjuntos, que iriam gerar várias barras com cores diferentes para cada conjunto. No exemplo atual vamos utilizar apenas um conjunto, o de “Acertos (%)”.

O primeiro dado que inseriremos no gráfico é a porcentagem geral de acertos, repare que além do valor e do conjunto, também temos que avisar qual o nome daquela barra, ou seja primeiro parâmetro é o valor, o segundo é o conjunto e o terceiro é o nome da barra, o segundo e o terceiro devem ser Comparable’s pois o Jfreechart vai comparar os grupos para organizar a ordem e as cores das barras e vai comparar os nomes das barras para poder juntar as que tiverem o mesmo nome.

dataset.addValue(mockStatistics.getPercentageOfTotal()"Acertos (%)""Geral");

Agora os próximos dados são as taxas de acerto por categoria. Os dados pertencem à outra classe, que não está em questão, mas o nome já é auto-explicativo.

for (int i = 0; i < mockStatistics.getListOfCategories().size(); i++) {
  dataset.addValue(mockStatistics.getPercentageByCategory(i),
  "Acertos (%)", mockStatistics.getListOfCategories().get(i).getId().getName());
}

Já temos os dados mas ainda falta criar o gráfico. O JFreechart disponibiliza uma classe (abstrata) que cria os gráficos, ela se chama ChartFactory (nada sugestivo hein ;) ) e contém métodos estáticos que devolvem objetos do tipo JFreechart.

No caso do gráfico em barras temos que passar 8 (oito) parâmtros:
1º - String - título (pode ser null)
2º - String - nome que vão aparecer nas categorias (pode ser null)
3º - String - nome que vai aparecer ao lado dos dados (pode ser null)
4º - CategoryDataset - Dataset que criamos
5º - PlotOrientation - indica se o gráfico vai ser na horizontal ou vertical (o JFreechart já tem uma ajudinha pronta pra isso)
6º - boolean - mostrar ou não legendas
7º - boolean - gerar ou não tooltips
8º - boolean/code> - gerar ou não url's

Assim, na pŕoxima instrução vamos usar o ChartFactory (abstrata) para criar um gráfico de Barra 3D, definindo o título como "Sua Pontuação", o nome das categorias não precisa de nada, o nome dos dados como "Pontos (%)", utilizando o Dataset criado anteriormente, passando a constante HORIZONTAL da classe PlotOrientation para avisar que o gráfico é na horizontal, mostrando as legendas e ignorando tooltip e as URL’s.

JFreeChart chart = ChartFactory.createBarChart3D("Sua Pontuação",
        null, "Pontos (%)", dataset, PlotOrientation.HORIZONTAL,
        true, false, false);

Finalizando, temos que colocar o gráfico no response da Servlet (no site uso o VRaptor assim eu tenho uma lógica que não devolve view nenhuma, apenas um response do tipo “image/png”).

Primeiro mudamos o tipo de do conteúdo do response para image/png

response.setContentType("image/png");

Com o objeto response, pegamos o seu OutputStream e atribuimos a uma nova variável que será usada na hora de renderizar o gráfico.

OutputStream os = response.getOutputStream();

O JFreechart também disponibiliza algumas ferramentas que auxiliam os programadores a renderizar os gráficos de várias maneiras, como, renderizar direto para um arquivo, para um outputstream ou mesmo no formato JPEG ou PNG, definir qualidade e etc..

ChartUtilities.writeChartAsPNG(os, chart, 500300);

Depois é só fechar o Outputstream e fim!

os.close();

Além do apresentado ainda podemos utilizar algumas opções um pouco mais avançadas, como mudar o range dos números (como o gráfico representa valores em porcentagem, o mais correto a se fazer é deixar o limite dos números entre 0 à 100), mudar a cor das barras:

Para ambas modificações temos que que pegar o CategoryPlot do gráfico:

CategoryPlot plot = chart.getCategoryPlot();

Mudar o range(limite) para números de 0 à 100:

plot.getRangeAxis().setRange(0100);

Mudar as cores das barras é um pouco mais complicado, mas não se assustem esse pouco mais complicado é bem pouco, do objeto plot você deve pegar o Renderer, mas ele vai devolver um CategoryItemRender, então você deve fazer um cast para o tipo BarRender. Depois o método a ser chamado no renderer é o setSeriesPaint, que vai pintar uma série escolhida, que no caso é a primeira (índice 0) e da cor escolhida.

BarRenderer renderer = (BarRenderer)plot.getRenderer();
renderer.setSeriesPaint(0, Color.BLUE);

Outra coisa que ainda podemos mudar é a altura do gráfico dinâmicamente, pois a altura vai depender de quantas categorias a prova teve. Assim podemos especificar uma altura mínima, e somar com uma altura multiplicada por quantas categorias a prova teve:

int height = dataset.getColumnCount()*45 65;
ChartUtilities.writeChartAsPNG(os, chart, 500, height);

Obs: Os valores da altura foram obtidos através de testes!

Veja o código completo:

@Viewless
  public void render() {
    DefaultCategoryDataset dataset = new DefaultCategoryDataset();
    dataset.addValue(mockStatistics.getPercentageOfTotal(),
        "Acertos (%)""Geral");
    for (int i = 0; i < mockStatistics.getListOfCategories().size(); i++) {
      dataset.addValue(mockStatistics.getPercentageByCategory(i),
          "Acertos (%)", mockStatistics
              .getListOfCategories().get(i).getId().getName());
    }

    JFreeChart chart = ChartFactory.createBarChart3D("Sua Pontuação",
        """Pontos (%)", dataset, PlotOrientation.HORIZONTAL, true, false,
        false);
    
    CategoryPlot plot = chart.getCategoryPlot();
    plot.getRangeAxis().setRange(0100);
    BarRenderer renderer = (BarRenderer)plot.getRenderer();
    renderer.setSeriesPaint(0, Color.BLUE);
    
    
    try {
      response.setContentType("image/png");
      OutputStream os = response.getOutputStream();
      int height = dataset.getColumnCount()*45 65;
      ChartUtilities.writeChartAsPNG(os, chart, 500, height);
      os.close();
    catch (IOException e) {
      System.err.println("Problem occurred creating chart.");
    }
  }

Distribuições do Eclipse

Por Sérgio Lopes em 13/01/07

O Eclipse é hoje a IDE mais utilizada pelos programadores Java. Possui diversos recursos e ferramentas que tornam o desenvolvimento em Java extremamente rápido e prático.

Mas todo desenvolvedor mais experiente sabe que o Eclipse “pelado” que a gente baixa direto lá no eclipse.org é de pouca utilidade para aplicações “reais”. Sempre damos uma turbinada no Eclipse com algum pluginzinho aqui e ali pra Web, outro pra celulares, outro talvez pra JSF e quem sabe até algum pra Ruby On Rails.

A arquitetura de plugins do Eclipse é um de seus pontos fortes. Por isso ele tão usado por aí, até servindo como base para outros produtos bastante conhecidos. Mas quem já teve que instalar plugins no Eclipse sabe que isso pode ser um processo meio chato. Principalmente porque frequentemente baixamos vários plugins, de vários lugares diferentes e depois temos que instalar todos. (tudo bem, os update sites e o recente callisto tentam minimizar o problema)

Mas não seria bom baixar um único zip com o Eclipse e seus plugins preferidos pré-instalados? Melhor: plugins testados e verificados, sem problemas de incompatibilidade com sua versão do Eclipse? Pois nossas preces foram ouvidas! Um projeto recente chamado EasyEclipse traz várias distribuições do Eclipse que você baixa no Site deles que já incluem pré-instalados os plugins mais comuns.

Existem várias distribuições, com focos diferentes. Por exemplo, a Server Java traz dezenas de plugins para trabalhar com ambiente servidor. Traz o Amateras e o Sysdeo, que usamos no treinamento web aqui da Caelum, o Amateras JSF, que usamos no treinamento jsf e hibernate, e até o WebTools, meu preferido pra Web. Confira lá!

Mas se você desenvolve para celulares, há a distribuição Mobile Java que traz, entre seus plugins, o EclipseME, que inclusive usamos no treinamento Java ME aqui da Caelum. Tem ainda a distribuição Desktop Java, voltado para desenvolvimento das “telinhas” e traz plugins como o famoso VEP.

Mas mesmo que você não use Java, o EasyEclipse é pra você. Pra turma do RubyOnRails, por exemplo, existe uma distribuição específica, que traz por exemplo o RadRails que a gente usa aqui no treinamento de Ruby On Rails. Há ainda outra voltada pra Python, outra pra PHP, e mais algumas.

A idéia é baixar um ambiente completo de desenvolvimento para o seu trabalho, sem precisar ficar baixando milhões de coisas de milhões de lugares. E ainda contar com um ambiente 100% testado e estável. Além disso, todos os plugins são livres, bem como o Eclipse, e o download gratuito.

O EasyEclipse possui versões para Windows, Linux e Mac. Entre lá e baixe o seu!

Caelum 2006: uma retrospectiva

Por Paulo Silveira em 08/01/07

Alguns pontos altos e cenas memoráveis de 2006 (e fotos!):

petrobras2 petrobras

A Petrobrás foi um dos clientes grandes com quem fechamos treinamentos neste ano. A foto é da equipe responsável pelo desenvolvimento de frameworks da empresa, composta por analistas da Bahia, Rio de Janeiro, Rio Grande do Norte e Sergipe e Alagoas, jantando em uma tradicional tratoria em São Paulo. Foi o treinamento de JSF e Hibernate, o FJ-26, adaptado com JBoss Seam. Outros grandes clientes também fecharam cursos, como UOL e Fujitsu.

A Caelum também recebe cada vez mais alunos de locais distantes. Somente nesta semana, durante o treinamento integral, temos alunos de Campo Grande (MS), Assis Chateaubriand e Maringá (PR), Vitória (ES), Poços de Caldas (MG) e Niterói (RJ).

CIMG0603 CIMG0576

Marcamos presença no Conexão Java, JustJava, Sun Tech Days, e o Servidores de Aplicação e Linguagens de Programação da TempoReal eventos.

Equipe caelum! CIMG0553

O encontro da Caelum em uma lanchonete da Aclimação foi muito bom, agora já somos em 15 pessoas em São Paulo (Rafael Cosentino e Suellen Campana não puderam comparecer).

CIMG0640 CIMG0668
Maputo CIMG0758

Também atravessamos mares e realizamos cinco dos nossos treinamentos em Maputo, capital de Moçambique, na África, para 30 desenvolvedores.

DSC01339 Fabio Jaqueline e Rodrigo

E em Porto Alegre a Caelum iniciou a parceria com a Wansoft, que realiza também nesta semana o primeiro FJ-11 em POA.

amigo2 amigo1

A empresa atingiu massa crítica para ter 13 participantes e realizar um amigo secreto!

Ainda tivemos muitos outros acontecimentos: o novo treinamento de Ruby on Rails, artigos na MundoJava, os cursos de verão da USP, apostilas reformuladas e disponíveis livremente, os novos e competentes instrutores da Caelum, a expansão em mais uma sala, a medalha de ouro do Guilherme Silveira na maratona de programação brasileira e sua participação no mundial do Japão em 2007, novos funcionários na administração, novos projetos e o nosso blog! Em 2007 o trabalho só vai aumentar, em especial em qualidade, e só podemos agradecer a dedicação da equipe e a vocês!

Atribuindo null

Por Paulo Silveira em 03/01/07

Um post bem curto sobre uma prática que aparece comumente em códigos por aí:

public void metodoQueListaUsuarios() {
  List<Usuario> lista = dao.pegaListaDeUsuarios();
  for(Usuario u : lista) {
    System.out.println(u.getNome());
  }
  lista = null// pra que isso?
}

Essa atribuição da lista para null, como muitos de vocês sabem, é totalmente desnecessária, pois ao fim do método o escopo da variável lista termina e ela morre automaticamente, já que essa é uma variável de pilha. Achar que isto está ajudando o Garbage Collector é um engano.

Porém tem alguns casos que isto é aplicável. O primeiro é se lista fosse um atributo, e não uma variável local ao método. Mas se você está atribuindo null a um atributo no fim de todo método, ele tem grande potencial de ser refatorado para varíaveis locais.

O segundo caso é quando você tem um objeto X alocado no heap e não vai usá-lo mais, porém você ainda tem trabalho a fazer no escopo da variável que referencia X. O Garbage Collector não poderá coletar X, nem mesmo marca-lo para coleta, enquanto a sua referência existir, e pode ser que ela continue existindo por muito tempo, como no código abaixo:

public void metodoQueListaUsuarios() {
  List<Usuario> lista = dao.pegaListaDeUsuarios();
  for(Usuario u : lista) {
    System.out.println(u.getNome());
  }
  lista = null;
  dao.fazOperacaoDemorada();  // lista ainda em uso?
}

Neste caso faz sentido tentar liberar a variável o mais rápido possível. Caso contrário, durante a nossa dao.fazOperacaoDemorada(), o objeto estará presente na memória e não poderá ser coletado (as vezes, em vez de atribuir null, podemos obter o mesmo efeito criando um novo escopo com {}). Claro que essa atribuição merece ser documentada. Essa operacaoDemorada poderia ser mais grave ainda caso a thread vá ser colocada em wait.

Dizem também, mas aí já está além do meu conhecimento, que a virtual machine hoje em dia consegue detectar essas variáveis que não tem mais uso em um determinado escopo, eliminando-a antes mesmo que o seu escopo feche.