A maioria dos sistemas comerciais, seja móvel ou não, necessita de relatórios para mostrar de forma resumida a entrada e processamento dos dados. Através do blog Mobilidade é tudo descobrimos o MEReport, responsável por realizar essa tarefa de forma bastante simples.
A API ainda está sendo construída e precisando de desenvolvedores para contribuir no andamento do projeto. Quem quiser ajudar é só entrar em contato.
Segue uam prévia da classe Relatorio.java, que através da CustomItem, cria um layout de relatório com componentes personalizáveis.
import java.util.Vector; import javax.microedition.lcdui.*; class Relatorio extends CustomItem{ private int minContentWidth; private int minContentHeight; private int prefContentHeight; private int prefContentWidth; private String title = ""; private boolean titleBorder; private boolean titleFillColor; private int[] titleColorText; private int[] titleColorBack; private int[] titleColorBorder; private Font titleFont; private Font titleHeader; private short titleAlignment; public static final short LEFT = 0; public static final short CENTER = 1; public static final short RIGHT = 2; public String[] columnsText; public int[] columnsPercents; private boolean columnsBorder; private boolean columnsFillColor; private int[] columnsColorText; private int[] columnsColorBack; private int[] columnsColorBorder; private Font columnsFont; private short columnsAlignment; private Font textFont; private int[] textColor; private boolean textGridH; private boolean textGridV; private int[] textLinesColor; private Vector[] textData; private short textAlignment; private int[] posYInicial; private int[] posYFinal; private int indice; private Image imgBrasao; private int[] tamColunas; private int sobra; public Relatorio(int width, int height) { super(""); titleFont = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_LARGE); titleColorText = new int[]{230, 230, 230}; columnsColorText = new int[]{40, 40, 40}; columnsFont = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_MEDIUM); textFont = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_SMALL); textColor = new int[]{0, 0, 0}; titleAlignment = CENTER; titleBorder = true; titleColorBorder = new int[]{0, 0, 0}; titleFillColor = true; titleColorBack = new int[]{50, 50, 50}; prefContentHeight = height; prefContentWidth = width; minContentHeight = height; minContentWidth = width; } public void setImgBrasao(Image imgBrasao) { this.imgBrasao = imgBrasao; } //métodos referentes a barra superior, que contém o título //começo public void setTitle(String title) { this.title = title; } public void setTitleAlignment(short alignment) { this.titleAlignment = alignment; } public void setTitleFont(Font titleFont) { this.titleFont = titleFont; } public void setTitleFontHeader(Font titleFont) { this.titleHeader = titleFont; } public void setTitleBorder(boolean titleBorder) { this.titleBorder = titleBorder; } public void setTitleFillColor(boolean titleFillColor) { this.titleFillColor = titleFillColor; } public void setTitleColorText(int[] color) { this.titleColorText = color; } public void setTitleColorBack(int[] color) { this.titleColorBack = color; } public void setTitleColorBorder(int[] color) { this.titleColorBorder = color; } //fim //métodos referentes as colunas //começa public void setColumns(String[] columns) { this.columnsText = columns; } public void setColumnsPercents(int[] percents) { this.columnsPercents = percents; tamColunas = new int[columnsPercents.length]; int total = 0; for (int i = percents.length-1; i >= 0; i--) { tamColunas[i] = ((prefContentWidth) / 100) * percents[i]; total += tamColunas[i]; } int sobra = ((prefContentWidth) - total) / 3; for (int i = percents.length-1; i >= 0; i--) { tamColunas[i] += sobra; } } public void setColumnsBorder(boolean columnsBorder) { this.columnsBorder = columnsBorder; } public void setColumnsFillColor(boolean fillColor) { this.columnsFillColor = fillColor; } public void setColumnsColorText(int[] color) { this.columnsColorText = color; } public void setColumnsColorBack(int[] color) { this.columnsColorBack = color; } public void setColumnsColorBorder(int[] color) { this.columnsColorBorder = color; } public void setColumnsFont(Font fontColumns) { this.columnsFont = fontColumns; } public void setColumnsAlignment(short alignment) { this.columnsAlignment = alignment; } //termina //métodos do texto //começa public void setTextFont(Font font) { this.textFont = font; } public void setTextData(Vector[] data) { this.textData = data; } public void setTextAlignment(short alignment) { this.textAlignment = alignment; } public void setTextColor(int[] color) { this.textColor = color; } public void setTextLineColor(int[] color) { this.textLinesColor = color; } public void setTextGridH(boolean grid) { this.textGridH = grid; } public void setTextGridV(boolean grid) { this.textGridV = grid; } //termina protected int getMinContentWidth() { return minContentWidth; } protected int getMinContentHeight() { return minContentHeight; } protected int getPrefContentWidth(int arg0) { return prefContentWidth; } protected int getPrefContentHeight(int arg0) { return prefContentHeight; } protected void paint(Graphics g, int largura, int altura) { int aux = 0; g.setColor(255, 255, 255); g.fillRect(0, 0, largura, altura); int tamTitulo = Math.max( (titleFont.getHeight() + 2), (imgBrasao == null?0:imgBrasao.getHeight())); //espaço do título //se a variável titleFillColor for true significa que o usuário quer que o //espaço do título seja preenchida com a cor definida no vetor //titleColorBack if (titleFillColor) // se sim, o título tem cor de fundo { g.setColor(titleColorBack[0], titleColorBack[1], titleColorBack[2]); g.fillRect(0, 0, largura, tamTitulo); if (imgBrasao != null) { g.drawImage(imgBrasao, 0, 0, Graphics.LEFT|Graphics.TOP); } } //configura a cor que vai ser usada no título, para isso usa a variável //titleColorText //em seguida é verificado o alinhamento escolhido para o título //na variável //titleAlignment //o título está armazenado na variável //title g.setColor(titleColorText[0], titleColorText[1], titleColorText[2]); g.setFont(titleFont); if (titleAlignment == LEFT) g.drawString(title, largura/2, tamTitulo/2 - titleFont.getHeight()/2, Graphics.LEFT|Graphics.TOP); else if (titleAlignment == CENTER) g.drawString(title, largura/2, tamTitulo/2 - titleFont.getHeight()/2, Graphics.HCENTER|Graphics.TOP); else g.drawString(title, largura/2, tamTitulo/2 - titleFont.getHeight()/26, Graphics.RIGHT|Graphics.TOP); //verifica se o usuário quer que o título seja contornado por uma borda //a variável titleBorder especifica isso //o vetor titleColorBorder Ccontém a cor da borda if (titleBorder) //verifica se o título tem borda { g.setColor(titleColorBorder[0], titleColorBorder[1], titleColorBorder[2]); g.drawRect(0, 0, largura, tamTitulo); } //desenha as colunas do título dos dados //ou seja, o cabeçalho aux = tamTitulo + 4; if (columnsFillColor)//se sim, as colunas tem background, senão, é transparente { int auxW = 0; g.setColor(columnsColorBack[0], columnsColorBack[1], columnsColorBack[2]); for (int i = 0; i < columnsText.length; i++) { g.fillRect(auxW - 1, aux, tamColunas[i]-1, titleHeader.getHeight() + 2); auxW += tamColunas[i]; } } int auxW = 0; if (columnsBorder) { g.setColor(columnsColorBorder[0], columnsColorBorder[1], columnsColorBorder[2]); for (int i = 0; i < columnsText.length; i++) { g.drawRect(auxW - 1, aux, tamColunas[i]-1, titleHeader.getHeight() + 2); auxW += tamColunas[i]; } } //escreve os títulos que representam os headers dos dados g.setColor(columnsColorText[0], columnsColorText[1], columnsColorText[2]); g.setFont(titleHeader); auxW = 0; for (int i = 0; i < columnsText.length; i++) { if (columnsAlignment == LEFT) g.drawString(columnsText[i], auxW, aux, Graphics.LEFT|Graphics.TOP); else if (columnsAlignment == RIGHT) g.drawString(columnsText[i], auxW + tamColunas[i] - 1, aux, Graphics.RIGHT|Graphics.TOP); else g.drawString(columnsText[i], (auxW + tamColunas[i]/2), aux, Graphics.HCENTER|Graphics.TOP); auxW += tamColunas[i]; } //Desenha as linhas verticais da tabela de dados aux += columnsFont.getHeight() + 8; g.setColor(0, 0, 0); g.drawLine(0, aux, largura, aux); if (textGridV) { g.setColor(textLinesColor[0], textLinesColor[1], textLinesColor[2]); auxW = 0; for (int i = 0; i < tamColunas.length-1; i++) { auxW += tamColunas[i]; g.drawLine(auxW, aux, auxW, aux + (textFont.getHeight() * textData.length)); } } //Desenha as linhas verticais da tabela de dados if (textGridH) { g.setColor(textLinesColor[0], textLinesColor[1], textLinesColor[2]); int aux2 = aux; for (int i = 0; i < textData.length; i++) { aux2 += textFont.getHeight(); g.drawLine(0, aux2, largura, aux2); } } //preenche os valores da tabela posYInicial = new int[textData.length]; posYFinal = new int[textData.length]; g.setFont(textFont); for (int i = 0; i < textData.length; i++) { Vector dados = textData[i]; auxW = 0; posYInicial[i] = aux; if (indice == i) { g.setColor(230, 230, 230); g.fillRect(0, aux+1, largura, textFont.getHeight()-1); } aux += textFont.getHeight(); posYFinal[i] = aux; for (int j = 0; j < tamColunas.length; j++) { g.setColor(textColor[0], textColor[1], textColor[2]); if (textAlignment == LEFT) g.drawString(dados.elementAt(j).toString(), auxW + 2, aux, Graphics.LEFT|Graphics.BOTTOM); auxW += tamColunas[j]; } } } protected void pointerPressed(int x, int y) { for (int i = 0; i < posYFinal.length; i++) { if (y >= posYInicial[i] && y <= posYFinal[i]) { indice = i; repaint(); return; } } } protected void pointerDragged(int x, int y) { } protected void pointerReleased(int x, int y) { } protected boolean traverse(int dir, int viewportWidth, int viewportHeight, int[] visRect_inout) { if (dir == 6)//pra baixo { if (indice < textData.length) { indice++; repaint(); return true; } else { return false; } } else if (dir == 1)//para cima { if (indice > 0) { indice--; repaint(); return true; } else { return false; } } else { return true; } } protected void traverseOut() { indice = 0; repaint(); } }
A a classe MEReportMidlet.java mostra como podemos trabalhar com o MEReport.
import java.util.Vector; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class MEReportMidlet extends MIDlet { private Display display; private Relatorio relatorio; private StringItem titulo; private Form fmMain; private Font fonte; private Font fonte2; private Font fonte4; private Image imgBrasao; public void startApp() { display = Display.getDisplay(this); fmMain = new Form("Relatório de Cidades"); titulo = new StringItem("Estado: ", "Rio Grande do Sul"); fmMain.append(titulo); try{ imgBrasao = Image.createImage("/brasao.PNG"); } catch (Exception e){ System.out.println("Erro na imagem: " + e.getMessage()); } relatorio = new Relatorio(fmMain.getWidth(), 200); fonte = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_LARGE); fonte2 = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_MEDIUM); fonte4 = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_SMALL); relatorio.setTitle("Cidades - RS"); relatorio.setImgBrasao(imgBrasao); relatorio.setTitleBorder(true); relatorio.setTitleFillColor(true); relatorio.setTitleFont(fonte); relatorio.setTitleFontHeader(fonte2); relatorio.setTitleColorBack(new int[]{22, 50, 117}); relatorio.setTitleColorText(new int[]{255, 255, 255}); relatorio.setTitleColorBorder(new int[]{0, 0, 0}); relatorio.setTitleAlignment(Relatorio.CENTER); relatorio.setColumns(new String[]{"Cód.", "Cidade", "Pop."}); relatorio.setColumnsAlignment(Relatorio.LEFT); relatorio.setColumnsBorder(true); relatorio.setColumnsColorBorder(new int[]{0, 0, 0}); relatorio.setColumnsColorBack(new int[]{200, 200, 255}); relatorio.setColumnsColorText(new int[]{0, 0, 0}); relatorio.setColumnsFillColor(true); relatorio.setColumnsFont(fonte); relatorio.setTextColor(new int[]{0, 0, 0}); relatorio.setTextLineColor(new int[]{22, 50, 117}); relatorio.setTextFont(fonte2); relatorio.setTextGridH(true); relatorio.setTextGridV(true); Vector[] dados = new Vector[5]; Vector passoFundo = new Vector(); passoFundo.addElement("0"); passoFundo.addElement("Passo Fundo"); passoFundo.addElement("212.700"); Vector portoAlegre = new Vector(); portoAlegre.addElement("2"); portoAlegre.addElement("Porto Alegre"); portoAlegre.addElement("1.400.500"); Vector davidCanabarro = new Vector(); davidCanabarro.addElement("3"); davidCanabarro.addElement("David Canabarro"); davidCanabarro.addElement("960.300"); Vector gramado = new Vector(); gramado.addElement("5"); gramado.addElement("Gramado"); gramado.addElement("87.000"); Vector uruguaiana = new Vector(); uruguaiana.addElement("6"); uruguaiana.addElement("Uruguaiana"); uruguaiana.addElement("134.820"); dados[0] = passoFundo; dados[1] = portoAlegre; dados[2] = davidCanabarro; dados[3] = gramado; dados[4] = uruguaiana; relatorio.setTextData(dados); relatorio.setColumnsPercents(new int[]{10, 58, 32}); fmMain.append(relatorio); display.setCurrent(fmMain); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } }
Referência: Mobilidade é tudo