Geek & Roll - Blog Archive » Controles custom en BlackBerry

Controles custom en BlackBerry

Cesar February 12th, 2010 gadgets, programacion Haz un comentario

Crear un control custom para una aplicación de BlackBerry es muy similar a crearlo para una aplicación Java con Swing. La arquitectura del toolkit de Swing es una de las cosas que más me gustan de Java, haciendo muy claro el cómo reemplazar algo por una implementación propia.

En este caso, mi requerimiento era tener una gran “palomita” o checkmark cuando cierta variable era verdadera, y una gran cruz o tache cuando la misma variable era falsa. En otras palabras, un checkbox pero con otra interfaz, más bonita (aunque bonita es una variable que depende del observador, y como eso no lo puedo controlar…)

Como muchas cosas en Java, todo comienza extendiendo una clase, en este caso la clase CheckboxField

public class CustomCheckBox extends CheckboxField

Este checkbox, contrario al checkbox normal, no va a tener un texto asociado, solo la parte gráfica. Así que sobreescribimos el constructor:

public CustomCheckBox(){
	super();
}

public CustomCheckBox(boolean check){
	super("",check);
}

Similar a Swing, hay que sobreescribir el método paint para ahí pintar lo que nosotros queremos. Cuando el checkbox esta check dibujamos la palomita, y cuando esta uncheck, dibujamos la cruz:

public void paint(Graphics g){
	if(getChecked()){
		drawCheck(g);
	}else{
		drawCross(g);
	}
}

Esos dos métodos drawCheck y drawCross son los responsables de pintar el control. El método getChecked heredado de CheckboxField nos dice si el control esta checked o unchecked.

Primero veamos drawCheck

private void drawCheck(Graphics g){
	int left = getBorderLeft();
	int top = getBorderTop();

	int x0 = left, x1 = x0, x2 = x1+20, x3 = x2+50, x4 = x3,
		x5 = x4-50, x6 = x5-20;
	int y0 = top, y1 = y0+30, y2 = y1+15, y3 = y2-45,
		y4 = y3+25, y5 = y4+45, y6 = y5-15;

	g.setColor(0x5B9058);
	g.setBackgroundColor(isFocus() ? 0xEEEEEE : 0xFFFFFF);
	drawBackground(g);
	g.setDrawingStyle(Graphics.DRAWSTYLE_AAPOLYGONS, true);

	int[] xPts = {x1, x2, x3, x4, x5, x6};
	int[] yPts = {y1, y2, y3, y4, y5, y6};
	g.drawFilledPath(xPts, yPts, null, null);

	g.setDrawingStyle(Graphics.DRAWSTYLE_AAPOLYGONS, false);
}

De antemano perdonen ustedes el uso de números mágicos. Lo interesante es el método drawFilledPath, que toma dos arreglos con coordenadas XY y dibuja, como su nombre lo indica, un polígono. Es algo como dibujar con Logo, uno de mis primeros lenguajes de programación muy similar a Lisp. Primero preparamos las coordenadas, después verificamos si nuestro control tiene el foco para dibujarle un fondo distintivo.

El otro método, drawCross, es muy parecido solo que las coordenadas cambian para formar una cruz:

private void drawCross(Graphics g){
	int left = 0;
	int top = 10;

	int x0 = left, x1=x0, x2=x1+25, x3=x2+10, x4=x3+10, x5=x4+25,
		x6=x4+5, x7=x5, x8=x4, x9=x3, x10=x2, x11=x1, x12=x2-5;
	int y0 = top, y1=y0,y2=y1, y3=y2+15, y4=y2, y5=y4, y6=y5+25,
		y7=y6+25, y8=y7, y9=y8-15, y10=y8, y11=y10, y12=y6;

	g.setColor(0xB54E41);
	g.setBackgroundColor(isFocus() ? 0xEEEEEE : 0xFFFFFF);
	drawBackground(g);
	g.setDrawingStyle(Graphics.DRAWSTYLE_AAPOLYGONS, true);

	int[] xPts = {x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12};
	int[] yPts = {y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12};
	g.drawFilledPath(xPts, yPts, null, null);

	g.setDrawingStyle(Graphics.DRAWSTYLE_AAPOLYGONS, false);
}

Y finalmente la clase completa

public class CustomCheckBox extends CheckboxField{
	public CustomCheckBox(){
		super();
	}

	public CustomCheckBox(boolean check){
		super("",check);
	}

	public void paint(Graphics g){
		if(getChecked()){
			drawCheck(g);
		}else{
			drawCross(g);
		}
	}

	protected void drawFocus(Graphics g, boolean focus){
		//do nothing
	}

	protected void onFocus(int direction){
		super.onFocus(direction);
		invalidate();
	}

	protected void onUnfocus(){
		super.onUnfocus();
		invalidate();
	}

	protected void layout(int width, int height){
		width = 71;
		height = 71;
		setExtent(width, height);
	}

	private void drawCheck(Graphics g){
		int left = getBorderLeft();
		int top = getBorderTop();

		int x0 = left, x1 = x0, x2 = x1+20, x3 = x2+50, x4 = x3,
			x5 = x4-50, x6 = x5-20;
		int y0 = top, y1 = y0+30, y2 = y1+15, y3 = y2-45,
			y4 = y3+25, y5 = y4+45, y6 = y5-15;

		g.setColor(0x5B9058);
		g.setBackgroundColor(isFocus() ? 0xEEEEEE : 0xFFFFFF);
		drawBackground(g);
		g.setDrawingStyle(Graphics.DRAWSTYLE_AAPOLYGONS, true);

		int[] xPts = {x1, x2, x3, x4, x5, x6};
		int[] yPts = {y1, y2, y3, y4, y5, y6};
		g.drawFilledPath(xPts, yPts, null, null);

		g.setDrawingStyle(Graphics.DRAWSTYLE_AAPOLYGONS, false);
	}

	private void drawCross(Graphics g){
		int left = 0;
		int top = 10;

		int x0 = left, x1=x0, x2=x1+25, x3=x2+10, x4=x3+10, x5=x4+25,
			x6=x4+5, x7=x5, x8=x4, x9=x3, x10=x2, x11=x1, x12=x2-5;
		int y0 = top, y1=y0,y2=y1, y3=y2+15, y4=y2, y5=y4, y6=y5+25,
			y7=y6+25, y8=y7, y9=y8-15, y10=y8, y11=y10, y12=y6;

		g.setColor(0xB54E41);
		g.setBackgroundColor(isFocus() ? 0xEEEEEE : 0xFFFFFF);
		drawBackground(g);
		g.setDrawingStyle(Graphics.DRAWSTYLE_AAPOLYGONS, true);

		int[] xPts = {x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12};
		int[] yPts = {y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12};
		g.drawFilledPath(xPts, yPts, null, null);

		g.setDrawingStyle(Graphics.DRAWSTYLE_AAPOLYGONS, false);
	}

	private void drawBackground(Graphics g){
		g.clear();
	}

	public boolean isFocusable(){
		return true;
	}
}

El resultado:
customcheckbox

Look ma! custom controls with no images!

Haz un comentario:

Es necesario que dejes tu nombre y correo electrónico (no se publicarán).

Si dejas un comentario anónimo, con insultos o ajeno al tema, iremos hasta tu casa y le diremos a tu mamá la cantidad de porno que hay en tu computadora. Si, lo sabemos.