Home > Artigos > Java ME >
Gráficos em Java ME com MECHART 2.0
Publicado por Tutoriais Admin em 15/08/2009 - 4.904 visualizações
Introdução
A API MECHART foi criada com o objetivo de suprir uma necessidade na programação Java ME, a falta de uma API que pudesse construir gráficos de maneira simples e rápida, sem a necessidade de programar diretamente na classe Canvas . Na programação para plataforma Java SE temos o exemplo do framework JFreeChart . Além disso, é crescente a preocupação com a interface dos programas móveis, devido ao avanço dos telefones celulares e também a facilidade de criação de interface ricas em outras linguagens e / ou frameworks para programação de dispositivos móveis.
Na primeira versão da API MECHART era possível a criação de três tipos de gráficos: gráficos de linhas, gráfico pizza e gráfico de barras. Na segunda versão um novo tipo de gráfico foi adicionado, o gráfico combinado. Este, por sua vez, combina barras e linhas. Além disso, nesta nova versão, é possível criar gráficos passando cores no formato RGB, tirando a limitação de uso das cores pré-definidas na API. Também, existe um método createImage para todos os tipos de gráficos, que retorna um objeto Image , permitindo seu uso em uma tela Canvas . Por fim, a criação de gráficos em Canvas , e não somente como CustomItem , também foi adicionada a esta versão mais recente da MECHART.
O presente artigo visa fornecer uma visão geral de como adicionar a MECHART ao seu projeto, além de fazer uma síntese sobre os métodos necessários para a criação dos quatro tipos disponíveis de gráficos. Por fim, deixamos o convite para que mais pessoas contribuam no crescimento da API.
MECHART: O Projeto
A mechart está registrada como um projeto no java.net, o link para acesso é: https://mechart.dev.java.net/ . Neste endereço pode-se encontrar o .jar que é usado na aplicação, além de documentação e dos códigos fontes, é importante ressaltar que a API está registrada sobre GPL e aguarda contribuições para seu crescimento. A API ainda está em fase inicial, sendo desenvolvida apenas por dois programadores. Atualmente, é possível a criação de quatro tipos de gráficos: gráfico combinado (Figura 1), gráfico de barras (Figura 2), gráfico de linhas (Figura 3) e gráfico de pizza (Figura 4). A Figura 1 ilustra um gráfico herdado da versão 1.0 da API, sendo que, o mesmo é construído como uma instância da classe CustomItem. O gráfico de barras, ilustrado na Figura 2, também representa uma instância da mesma classe. A Figura 3 mostra um gráfico de linhas, que usa uma das novas funcionalidades da nosa versão da API MECHART, a construção de gráficos como uma instância da classe Canvas. Por fim, a Figura 4 apresenta o uso do método createImage, que retorna uma instância da classe Image, sendo assim, esta instância pode ser usado em um Canvas ou em um Form da maneira como o usuário achar adequada.
| | |
| |
Utilizando a API com o NetBeans e Wireless Toolkit
O uso de determinada IDE fica a cargo do leitor, porém, não seria possível apresentar aqui o uso da API com todas as IDEs existentes, portanto, foi escolhido o NetBeans, que é muito popular entre programadores Java, de forma similar, o Sun Java Wireless Toolkit é bastante usado para emular programas Java ME, e para a conseqüente distribuição. Aqui, é necessário fazer uma divisão entre duas versões do NetBeans, a versão 3.6 representa a ferramenta no momento em que ainda seguia a idéia de criação de filesystems , sem criar sua própria estrutura para projetos, a partir da versão 4.1, o NetBeans passou a criar uma estrutura de projetos própria, suas versões mais atuais, como a 5.0 (que será demonstrada aqui) continuam a seguir este padrão.
NetBeans 3.6:
Usando a versão 3.6 do NetBeans, o leitor também deve usar uma versão do Sun Java Wireless Toolkit (WTK) independente da IDE, se o leitor não tem conhecimento dos dois softwares citados anteriormente, aconselha-se a leitura sobre essas ferramentas antes de prosseguir a leitura do presente artigo. Através do WTK cria-se o projeto, define-se o nome, configuração e perfil usado, dentre outras características. Feito isso, uma árvore de diretórios semelhante a Figura 5 deve ser formada no diretório apps da instalação do WTK. Para usar a mechart basta colocar o jar da API na pasta lib da referida hierarquia.
Figura 5: Hierarquia do projeto
NetBeans 5.0:
Usando o NetBeans 5.0 o leitor terá uma facilidade maior, isso porque o WTK pode ser acoplado diretamente a IDE, evitando a necessidade de constantes troca de janelas para poder executar sua MIDlet. É presumido que o NetBeans já tenha o Mobility Pack instalado, e o WTK mapeado, como esse não é o foco desse artigo, entende-se que o leitor já tenha conhecimento de como fazer isso.
Depois de criado o projeto, o leitor deve acessar as propriedades do mesmo, uma tela semelhante à Figura 6 corresponde à parte de configuração das propriedades do projeto. Observe que a opção "Libraries & Resources" na parte esquerda está selecionado, e na parte direita aparece o endereço de onde se encontra o jar da mechart, para isso basta selecionar a opção "Add Jar/Zip..." na parte direita, e posteriormente, mapear o endereço de onde o .jar da mechart está salvo.
Figura 6: Tela de configurações do projeto.
Usando a mechart
Para continuar, é imprescindível que o leitor tenha um conhecimento básico da Java ME. A Listagem 1 mostra o esqueleto básico da nossa MIDlet, sem o uso da mechart, ainda. Observe que já foi criado um Form, pois como todo CustomItem é um Item, o mesmo só pode ser adicionado em um formulário.
| import java.util.Vector; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import com.mechart.chart.*; public class Midlet extends MIDlet { private Display display; private Form fmMain; public void startApp() { display = Display.getDisplay(this); fmMain = new Form("Teste CustomItem"); display.setCurrent(fmMain); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} } |
Listagem 1: MIDlet básica.
Para usar qualquer um dos quatro gráficos podemos fazer o import através da seguinte linha de código Java:
import com.mechart.chart.*;
LineChart:
Depois de criar o objeto nos atributos da classe, deve-se criar a instância da classe e em seguida adicionar o item ao Form. O construtor da classe LineChart recebe nove parâmetros no total, sendo eles: a largura total do gráfico, a altura total do gráfico, os valores que formam a linha do gráficos, legenda dos dados, identificação dos dados, tamanho da fonte, cores das linhas, cor do fundo do gráfico e o valor máximo para o gráfico. Para as cores, a LineChart já traz alguns valores definidos como constantes para você usar, sem a necessidade de conhecer os códigos RGB das cores desejadas. Porém, para alguns casos específicos, as cores devem ser definidas com códigos RGB,. Por exemplo, o programador recebe do design gráfico um esboço do menu do aplicativo móvel, as cores que ele usou não existem nas constantes da LineChart, sendo assim, ele deverá usar seus códigos RGB. Veja a Listagem 2 com o código da MIDlet que mostraria o gráfico da Figura 7. A Listagem 3 ilustra apenas a criação do objeto lineChart com códigos RGB e seu resultado na Figura 8.
| import com.mechart.chart.LineChart; import java.util.Vector; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class UsoLineChart extends MIDlet{ private Display display; private Form fmMain; private LineChart lineChart; public void startApp() { display = Display.getDisplay(this); fmMain = new Form(""); ClCanvas cv = new ClCanvas(); fmMain.append(new StringItem("Balancete 1º Semestre", null)); short[][] posicoes = new short[][]{{50, 43, 19, 47, 90, 63}, {30, 13, 15, 82, 79, 50}, {23, 24, 49, 51, 70, 81}}; String[] legenda = new String[]{"Jan", "Fev", "Mar", "Abr", "Mai", "Jun"}; byte[] cores = new byte[]{LineChart.MAROON, LineChart.BLUE, LineChart.WHITE}; lineChart = new LineChart(cv.getWidth(), 75, posicoes, legenda, new String[]{"Produção", "Vendas", "Gastos"}, 1, cores, LineChart.GRAY, (short)90); fmMain.append(lineChart); display.setCurrent(fmMain); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} } class ClCanvas extends Canvas { protected void paint(Graphics graphics) {} } |
Listagem 2: Uso do LineChart.
| int[][] coresMat = new int[][]{new int[]{255, 0, 0}, new int[]{0, 255, 0}, new int[]{0, 0, 255}}; lineChart = new LineChart(cv.getWidth(), 75, posicoes, legenda, new String[]{"Produção", "Vendas", " Estoque"}, 1, coresMat, new int[]{220, 220, 220}, (short)90); |
Listagem 3: Uso do LineChart com códigos RGB.
| | |
Perceba que também foi criada uma classe interna que herda de Canvas, para recuperar a largura e a altura do display do device, se o projeto é direcionado para uma plataforma alvo de celulares, e suas dimensões são conhecidas, o uso do Canvas não é necessário. Nesta nova versão da API MECHART podem ser citadas algumas melhorias: · Possibilidade de criação do gráfico com códigos RGB; · Gráfico de múltiplas linhas; · Possibilidade de criação de gráfico com Canvas; · Possibilidade de criação de um objeto Image de um gráfico. Os dois primeiros itens foram mostrados anteriormente. Para a criação de um gráfico de linhas como uma instância de Canvas e não de CustomItem, existe a classe LineChartCanvas. Seu uso é mostrado na Listagem 4, perceba que apenas o método startApp() foi alterado, não existe mais o uso da classe Form. Além disso, no contrutor da classe LineChartCanvas são passados onze parâmetros e não nove, sendo que, apenas os dois últimos diferem, sendo estes parâmetros: um byte que representa o posicionamento, um vetor de inteiros que forma o código RGB da cor de fundo do Canvas, não do gráfico. O parâmetro de posicionamento pode ser uma das duas constantes existentes na classe: FULL e NONE. Usando a constante NONE o gráfico terá a altura passado por parâmetro para o construtor, de contrário, o altura do gráfico será a altura do display do celular, útil em caso onde o programador deseja que o gráfico seja mostrado em toda tela do aparelho celular, sem se importar em obter a altura do display. A Figura 9 ilustra o resultado da Listagem 4 e a Figura 10 ilustra o resultado com o uso de LineChartCanvas.NONE e não de LineChartCanvas.FULL. Assim como na explicação anteriormente, também é possível criar o gráfico passando os códigos RGB das cores, o mesmo gráfico da Figura 9 pode ser criado com o código da Listagem 5. As mudanças estão no sétimo e oitavo parâmetros, onde um vetor de bytes é substituído por uma matriz de inteiros e, uma constante da classe LineChartCanvas é substituída por um vetor de inteiros. display = Display.getDisplay(this); short[][] posicoes = new short[][]{{50, 43, 19, 47, 90, 63}, {30, 13, 15, 82, 79, 50}, {23, 24, 49, 51, 70, 81}}; String[] legenda = new String[]{"Jan", "Fev", "Mar", "Abr", "Mai", "Jun"}; byte[] cores = new byte[]{LineChart.MAROON, LineChart.BLUE, LineChart.WHITE}; int[][] coresMat = new int[][]{new int[]{255, 0, 0}, new int[]{0, 255, 0}, new int[]{0, 0, 255}}; display.setCurrent(new LineChartCanvas(cv.getWidth(), 100, posicoes, legenda, new String[]{"Produção", "Vendas", "Gastos"}, 1, cores, LineChart.GRAY, (short)90, LineChartCanvas.FULL, new int[]{20, 200, 200})); Listagem 4: Uso do LineChartCanvas. display.setCurrent(new LineChartCanvas(cv.getWidth(), 100, posicoes, legenda, new String[]{"Produção", "Vendas", "Gastos"}, 1, coresMat, new int[]{180, 180, 180}, (short)90, LineChartCanvas.FULL, new int[]{200, 200, 200}));
Figura 9: LineChartCanvas com FULL.
Figura 10: LineChartCanvas com NONE.
Listagem 5: Uso do LineChartCanvas com códigos RGB.
Além disso, o usuário da MECHART pode criar um objeto Image usando o método createImage da LineChartCanvas. A Listagem 6 apresenta na primeira parte, o método startApp e, na segunda, o código da classe Canvas. Perceba que os parâmetros necessários no método createImage são os mesmos para instanciar um objeto da classe LineChartCanvas. O resultado do código está na Figura 11.
| public void startApp() { display = Display.getDisplay(this); ClCanvas cv = new ClCanvas(); display.setCurrent(cv); } --------------------------------------//--------------------------------------- class ClCanvas extends Canvas { Image img = null; Font fonte = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_MEDIUM); short[][] posicoes = new short[][]{{50, 43, 19, 47, 32, 90}, {30, 13, 15, 82, 79, 50}, {23, 24, 49, 51, 70, 81}}; String[] legenda = new String[]{"Jan", "Fev", "Mar", "Abr", "Mai", "Jun"}; int[][] coresMat = new int[][]{new int[]{255, 0, 0}, new int[]{0, 255, 0}, new int[]{0, 0, 255}}; public ClCanvas() { img = LineChartCanvas.createImage(getWidth(), 100, posicoes, legenda, new String[]{"Produção", "Vendas", "Gastos"}, 1, coresMat, new int[]{255, 255, 255}, (short)90, LineChartCanvas.NONE, new int[]{200, 200, 200}); setFullScreenMode(true); } protected void paint(Graphics g) { g.setColor(220, 220, 220); g.fillRect(0, 0, getWidth(), getHeight()); g.setFont(fonte); g.setColor(0, 0, 0); g.drawString("Teste da MECHART", getWidth()/2, 0, Graphics.HCENTER|Graphics.TOP); g.drawString("Dados empresariais", getWidth()/2, fonte.getHeight(), Graphics.HCENTER|Graphics.TOP); g.drawImage(img, 0, fonte.getHeight()*2, Graphics.LEFT|Graphics.TOP); g.setColor(255, 0, 0); g.drawLine(0, fonte.getHeight()*2, getWidth(), fonte.getHeight()*2); } } |
Listagem 6: Código necessário na MIDlet e no Canvas para utilização do método createImage.

Figura 11: gráfico de linhas criado com o método createImage() da classe LineChartCanvas.
PieChart:
O gráfico de pizza, talvez um dos mais conhecidos, é criado com a classe PieChart. Seu construtor recebe cinco parâmetros, sendo eles: a largura total do gráfico, a altura total do gráfico, dados que formam a pizza, altura da fonte e as cores de cada fatia da pizza. O último parâmetro é passado em um vetor de byte, sendo que os bytes que definem as principais cores, estão disponíveis como constantes estáticas na PieChart. Observe a Listagem 7 com o código para uso da PieChart.
| import com.mechart.chart.PieChart; import java.util.Vector; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class UsoPieChart extends MIDlet { private PieChart pieChart; private Form fmMain; private Display display; public void startApp() { display = Display.getDisplay(this); Vector dados = new Vector(); dados.addElement(new String[]{"Brasil", "50"}); dados.addElement(new String[]{"Alemanha", "88"}); dados.addElement(new String[]{"Itália", "71"}); dados.addElement(new String[]{"Argentina", "45"}); dados.addElement(new String[]{"Uruguai", "22"}); Canvas cv = new Canvas() { protected void paint(Graphics graphics) { } }; fmMain = new Form(""); fmMain.append(new StringItem("Gráfico: ", "Participação PIB")); pieChart = new PieChart(cv.getWidth(), 70, dados, 1, new byte[]{PieChart.BLACK, PieChart.BLUE, PieChart.GREEN, PieChart.WHITE, PieChart.RED}); fmMain.append(pieChart); display.setCurrent(fmMain); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} } |
Listagem 7: : Uso da PieChart
A criação do gráfico de pizza tem dois pontos cruciais, um instância da classe Vector que informa os dados e o vetor de bytes com as cores de cada pedaço da pizza. A Figura 12 apresenta o resultado da Listagem 7. Também, é possível passar uma matriz de inteiros com os códigos RGB ao invés de um vetor de bytes, veja sua forma de implementação no trecho da Listagem 8.

Figura 12: gráfico de pizza criado com a PieChart.
| pieChart = new PieChart(cv.getWidth(), 70, dados, 1, new int[][]{new int[]{0, 0, 0}, new int[]{0, 0, 255}, new int[]{0, 255, 0}, new int[]{255, 255, 255}, new int[]{255, 0, 0}}); fmMain.append(pieChart); |
Listagem 8: Uso da PieChart com o código RGB das cores .
De forma análoga ao gráfico de linhas, o de pizza também teve melhorias nesta última versão da MECHART, exceto pelo uso de múltiplas linhas, os avanços se aplicam aos dois tipos de gráficos. Para criação de gráficos como instância de Canvas, existe a classe PieChartCanvas. A Listagem 9 apresenta o código necessário para criação de um gráfico através da PieChartCanvas. É importante ressaltar dois pontos, primeiro, as mudanças ocorrem somente no método startApp, e segundo, apenas dois parâmetros foram adicionados aos já usados anteriormente. Um byte que identifica a posição do gráfico, FULL ou NONE, com funcionamento análogo ao LineChartCanvas, e, um vetor de inteiros que representa a cor de fundo do Canvas. A Listagem 10 mostra o uso da classe com valores RGB. A Figura 13 apresenta o resultado deste código.
| display = Display.getDisplay(this); Vector dados = new Vector(); dados.addElement(new String[]{"Brasil", "50"}); dados.addElement(new String[]{"Alemanha", "88"}); dados.addElement(new String[]{"Itália", "71"}); dados.addElement(new String[]{"Argentina", "45"}); dados.addElement(new String[]{"Uruguai", "22"}); Canvas cv = new Canvas() { protected void paint(Graphics graphics) { } }; int[][] coresMat = new int[][]{new int[]{0, 0, 0}, new int[]{0, 0, 255}, new int[]{0, 255, 0}, new int[]{255, 255, 255}, new int[]{255, 0, 0}}; display.setCurrent(new PieChartCanvas(cv.getWidth(), 100, dados, 1, new byte[]{PieChartCanvas.BLACK, PieChartCanvas.BLUE, PieChartCanvas.GREEN, PieChartCanvas.WHITE, PieChartCanvas.RED}, PieChartCanvas.FULL, new int[]{200, 200, 200})); |
Listagem 9: Uso das PieChartCanvas.
| int[][] coresMat = new int[][]{new int[]{0, 0, 0}, new int[]{0, 0, 255}, new int[]{0, 255, 0}, new int[]{255, 255, 255}, new int[]{255, 0, 0}}; display.setCurrent(new PieChartCanvas(cv.getWidth(), 100, dados, 1, coresMat, PieChartCanvas.FULL, new int[]{200, 200, 200})); |
Listagem 10: Usa PieChartCanvas com RGB.

Figura 13: gráfico de pizza criado com a PieChartCanvas.
O método createImage da classe PieChartCanvas recebe os mesmos parâmetros que a classe recebe em seu construtor. Seu uso é igual ao da LineChartCanvas. A Listagem 11 mostra o uso deste método de duas formas, na primeira, usando códigos RGB e, na segunda, usando as constantes pré-definidas na classe. A Figura 14 mostra o resultado das duas listagens.
| img = PieChartCanvas.createImage(getWidth(), 100, dados, 1, new int[][]{new int[]{0, 0, 0}, new int[]{255, 255, 255}, new int[]{0, 255, 0}, new int[]{255, 0, 0}, new int[]{100, 100, 100}}, PieChartCanvas.NONE, new int[]{200, 200, 200}); -------------------------------------//---------------------------------------- img = PieChartCanvas.createImage(getWidth(), 100, dados123, 1, new byte[]{PieChartCanvas.WHITE, ...}, PieChartCanvas.NONE, new int[]{200, 200, 200}); |
Listagem 11: Uso do método createImage da classe PieChartCanvas.

Figura 14: gráfico de pizza criado com o método createImage da classe PieChartCanvas.
Gráfico de Barras:
O Gráfico de Barras é construído com a utilização da classe BarChart da mechart, seu construtor é semelhante aos demais gráficos da API, os parâmetros passados são: a largura total do gráfico, a altura total do gráfico, dados que formam o gráfico (detalhe, os dados são passados em um Vector, e cada elemento do vetor é uma das "barras" do gráfico), tamanho da fonte, vetor de bytes representando as cores usadas (mesma lógica do PieChart), um byte que representa a cor de fundo do gráfico, e o valor máximo que o gráfico irá receber. Assim como as outras classes da API, a BarChart também tem valores constantes e estáticos para definir algumas das principais cores. Veja na Listagem 12 como utilizar a classe:
Depois de chegar até este último gráfico, o leitor não terá dificuldade de entender o funcionamento do gráfico de barras, porém, preste atenção no método fullChart(boolean fullChart), este método especifica se as barras que compõe o gráfico ocuparão um espaço uniforme, ou seja, todas com o mesmo tamanho e ocupando toda a área do gráfico, ou cada barra terá um tamanho menor, que será especificado no método sizeBar(int tamBar). Para entender melhor este conceito, veja as figuras 15 e 16, a Figura 15 mostra o gráfico segundo a Listagem 12, já a Figura 15 mostra como ficaria o gráfico se na linha:
barChart.fullChart(false);
Fosse usado:
barChart.fullChart(true);
A Listagem 13 mostra o código de criação do gráfico de barras passando os códigos RGB das cores. Pode haver uma disparidade entre as cores dos códigos das listagens e o resultado nas figuras, mas isso fica para surpresa do leitor.
| import com.mechart.chart.BarChart; |



