• Menu 1
  • Menu 2
  • Menu 3
  • Menu 4

Gravatar


Soy César Olea, programador desktop, Web y de sistemas embebidos. Originario de Ciudad Obregón, Sonora, México.

Actualmente he terminado mi maestría en Ciencias de la Computación y me dedico dar mantenimiento, administrar y programar el sitio aVeralCine.com, escribir en Geek&Roll, el Web-comic geeksofacto y distintos proyectos de programación. Mi trabajo oficial (o sea, el que paga las cuentas) es en Tiempo Development como Senior Software Engineer. Si eres un buen programador, hablas Inglés y te interesa trabajar en una empresa con excelente ambiente laboral y projectos interesantes, estamos buscando gente como tu.

Para contactarme puedes enviarme un mensaje si estoy conectado a gTalk.

Geek&Roll es el blog donde escribo sobre programación, cracking, cultura geek, Software Libre, Internet, y más. En conjunto con Axel y Rafyta mantenemos un blog de contenido (casi todo) original.

Últimas entradas

Formas dinámicas con GWT
Por: Cesar

Mi relación con GWT es una de amor – odio. Por un lado, tenemos a un toolkit que me permite utilizar mis conocimientos de Java para crear aplicaciones Web dinámicas, aplicando mejores prácticas en la arquitectura del código del cliente, mejorando el tiempo de respuesta gracias al uso de técnicas como agrupar imágenes para usarlas en el cliente con una sola descarga y código segmentado.

Por el otro lado, algunas tareas se vuelven más complicadas. Estoy convencido que las herramientas como GWT son el futuro, más no me queda claro si la actual implementación sea adecuada para toda la programación del lado del cliente. Además la curva de aprendizaje es más inclinada de lo que debería de ser; existen muchos gotchas todavía que hacen que el programador tenga que estar consciente de que esto es Web y no una aplicación regular.

En esta ocasión el requerimiento era el siguiente: tengo una aplicación que hace uso extensivo de formas para captura de datos. Necesito una manera de declarar dichas formas y que la aplicación automáticamente las ordene en diferentes tabs cuando estas crezcan demasiado. Las formas generadas deben poder ser insertadas en cualquier sitio, además de poder aplicarles estilos con CSS.

Como dije anteriormente, lo que me gusta de GWT es que puedo generar la solución a mis requerimientos de la misma manera en la que estoy acostumbrado a hacerlo. En este caso, creo una clase DynaForm que representa mi forma dinámica:

/*Represents the client side DynaForm*/
public class DynaForm {
	private String formSource;
	private ArrayList<String> panelTitles;
	private ArrayList<HTML> panels;
	private Node root;

	public DynaForm(String formSource){
		setFormSource(formSource);
	}

Ahora viene algo interesante. El método setFormSource(). Es aquí donde vamos a parsear el código de la forma para extraer los valores que nos interesan, y descomponerla en sus partes para después volverla a construir pero con las propiedades que nos interesan, en este caso los tabs.

public void setFormSource(String formSource){
	try{
		Document d = XMLParser.parse(formSource);
		root = d.getFirstChild();
		XMLParser.removeWhitespace(root);
		setPanels(root, formSource);
	}catch(Exception e){
		System.out.println(e.getMessage());
		e.printStackTrace();
	}

	this.formSource = formSource;
}

Como vemos, parseamos la fuente y de esa manera nos aseguramos que es código válido. Aquí podríamos aplicar otras reglas, como por ejemplo eliminar cualquier tag o propiedad maliciosa como una llamada a JavaScript. El método setPanels() es el que se encarga de construir los páneles necesarios.

/*
 * This method creates an array of HTML panels. Both panels and panelTitles must
 * contain the same number of elements. In case a <span> element doesn't provide
 * a 'name' attribute, it is replaced by an empty string.
 *
 * The number of HTML panels created is = # of <span> elements. All elements inside <form>
 * without a <span> are ignored.
 * */
private void setPanels(Node root, String formSource){
	panelTitles = new ArrayList<String>();
	panels = new ArrayList<HTML>();
	NamedNodeMap attribs;

	NodeList allElements = root.getChildNodes();

	/*
	 * Start looping all elements, and create new HTML panels as needed
	 * */
	for(int i=0; i<allElements.getLength(); i++){
		Node n = allElements.item(i);
		//if it's a span, create a new empty HTML panel and set its name.
		if(n.getNodeName().equals("span")){
			//Set the panel title entry
			attribs = n.getAttributes();
			panelTitles.add(getAttribValue(attribs, "name"));
			panels.add(new HTML());
		}else{
			try{
				//get the last panel
				HTML panel = panels.get(panels.size()-1);
				//add the node source to the panel HTML
				panel.setHTML(panel.getHTML() + n.toString());
			}catch(Exception e){
				System.out.println(e.getMessage());
			}
		}
	}
}

El método setPanels() toma todos los elementos de la forma y los analiza de la siguiente manera: Si es un elemento span, quiere decir que es el inicio de un nuevo tab. Toma la propiedad name del span y lo convierte en el título de la nueva tab. Si el elemento no es un span, entonces lo agrega a la lista de elementos que forman el tab actual.

Después, en el punto de entrada de la aplicación:

TabPanel tabPanel = new TabPanel();
dynaForm = new DynaForm(formSource);

//All each HTML panel to the tabPanel
for(int i=0; i<dynaForm.getPanels().size(); i++){
	quirksTabPanel.add(dynaForm.getPanels().get(i), dynaForm.getPanelTitles().get(i));
}

RootPanel.get("dynaForm").add(tabPanel);

Utilizando el siguiente código HTML como fuente de la forma:

<form method='POST' action='contactengine.php' name='contact'>
	<span name='Datos' />
	<label for='Nombre'>Nombre:</label>
    	<input type='text' name='Nombre' id='Nombre' />"

    	<label for='Correo'>Correo:</label>
    	<input type='text' name='Correo' id='Correo' />

	<label for='Mensaje'>Mensaje:</label>
	<textarea name='Mensaje' rows='20' cols='20' id='Mensaje'></textarea>

	<span name='Enviar' />
	<input type='submit' name='submit' value='Enviar' class='submit-button' />
</form>

El resultado es:
DynaForm

Claro que se deben usar estilos para hacer que la forma se vea más presentable. También creo que se puede lograr exactamente el mismo resultado utilizando una combinación de jQuery, selectores CSS y jQuery UI.

Everlasting Flame y Bold 2 (OS 5)
Por: Cesar

Everlasting Flame icon

Muchos usuarios han reportado problemas al utilizar Everlasting Flame con la BlackBerry Bold 2. Más particularmente, con el OS 5. Dicho problema no se presentaba en versiones anteriores a la 1.3.

El problema ha sido resuelto en la siguiente versión (2.0) sin embargo no se encuentra lista para consumo masivo. Por lo mismo, he subido de nuevo la versión 1.2 ligeramente modificada. Esta versión ha sido probada en la Bold 2, pero debería funcionar en cualquier dispositivo con OS 5.

Pueden descargar la versión 1.2 en el sitio oficial de Everlasting Flame. En la sección de descarga se encuentra la versión 1.2 para dispositivos anteriores.

Sus comentarios son bienvenidos.

Sonora al Software Libre y la desinformación
Por: Cesar

Por medio de Google Buzz me enteré de una noticia que me sorprendió de manera muy positiva: Sonora se pasa al Software Libre para sus sistemas de información. El Buzz en cuestión es de mi amigo y colega Roberto Ramirez, y linkea a un blog de Martin Llamas.

Cuando leí el post por primera vez, pensé que era una broma. Al leerlo por segunda ocasión y checar otros posts del mismo blog, me di cuenta de que no, no era una broma. Este señor esta convencido de que el cambio al software libre es una pérdida de dinero, ya que todo lo que se ha pagado hasta ahora en licencias se va a tirar a la basura, como si el pago de licencias fuera sólo una vez en la vida y ya.

El autor cita varios problemas con este cambio, veamos:

  • Se van a tirar millones de pesos a la basura, porque las licencias que ya pagamos ya no nos van a servir. Bajo esta lógica, entonces pagar renta tiene mucho sentido y nunca deberíamos de cambiarnos a nuestra propia casa, ya que estaríamos tirando a la basura millones de pesos pagados en renta.
  • Cuando pierda el PAN el siguiente sexenio, se van a volver a comprar las licencias y por lo tanto es pura gastadera de dinero. Haciendo a un lado toda la cuestión de ver el futuro, me sorprendería que los sistemas informáticos se cambiaran otra vez a sistemas privativos sin una buena razón. Si la razón es para apuntar el dedo y decir “es que los del otro partido…” eso dice mucho de la calidad de la gente que entrará al nuevo gobierno.
  • El software libre no es seguro, porque sólo se encuentra instalado en el 1% de las computadoras del mundo. Como si el software mágicamente se hiciera más seguro por cada instalación nueva. Por citar algunos ejemplos, el plugin de flash se encuentra instalado en la gran mayoría de las computadoras de escritorio del mundo, y es bien conocido que su historial de seguridad es por demás malo. Un contraejemplo es el servidor HTTP Apache, el cual es el servidor HTTP más usado en el mundo y es software libre, ciertamente más del 1% de los servidores HTTP lo tienen instalado. La seguridad llega por buen diseño, revisiones continuas y parches a tiempo, no por la base instalada.
  • Después lanza una serie de ejemplos en donde han salido a la luz errores en programas libres, en donde los parches han tardado bastante en llegar. El autor no proporciona ninguna liga, y dice que su fuente es “difícil de encontrar” pero no dudo que esos errores hayan existido. Lo que no se dice en el post es que en los sistemas de Microsoft que tanto pregona, hace poco se parchó un error en el sistema operativo Windows que tenía 17 años de vida. ¿O que? ¿No sabía? ¿Cuando viene de Microsoft es justificado?

Y bueno, después el autor habla de interoperabilidad, como si tener todos tus datos en un sistema privativo fuera la mejor idea. Hay en el post una sarta de opiniones desinformadas que sinceramente da tristeza que alguien quiera hacer un punto a favor del software privativo en el gobierno, siendo tan ignorante de la alternativa.

Señor Martin Llamas, si no sabe mejor limítese a decir “Chiquitibum a la bin bon ban, Microsoft! Microsoft! RA RA RA!!!!”

Ampache Stremeara Tu Musica Hasta Tombuctú
Por: Boynas

¿Estás aburrido este fin de semana? ¿O simplemente necesitas una manera de tener acceso a tu música (y de video) desde cualquier parte del MUNDOOO, o bien compartírsela a tu amigo en Tombuctú?

Hay muchas maneras de accesar archivos remotamente: servidor FTP, servidor web, algún servicio externo, pero de alguna manera he probado todas y creo que esta es la más chingona, y bueno, al menos para música.

Empecemos enumerando las posibles alternativas:

Orb – Es un servicio que te permite accesar a tus archivos multimedia y hasta televisión local, si tienes conectado el cable o antena a tu PC. Utiliza un cliente que reside en memoria el cual monitorea el contenido multimedia de tus discos duros y también “llama a casa” con tu IP y otras cosas, para que puedas accesar a tus datos utilizando el portal en myorb.com, ya que la mayoría del tiempo estas detrás de un firewall.

Slimserver – Este servidor con licencia GNU, fue particularmente creado para darle soporte a clientes de hardware, es decir, lo instalas en tu servidor para poder escuchar la música en tu cliente hardware; Slimdevices. Esta compañía fue comprada por Logitech, pero el desarrollo de slimserver, el cual ahora se llama Squeezebox server, sigue dando soporte a softclients por medio de cualquier navegador web. El problema es que afuercitas necesitas un “fat client” para poder aterrizar el stream; Algo como Winamp, WMP,  cualquier otro media player que acepte URLs.

Apache/Songbird – Si, ya se! Este es un servidor web, y pues que tiene de chilo utilizarlo para que te despliegue el contenido de tus carpetas. Por más bonito que estén los index de tu Apache, no sirven de nada si no tienes Songbird. Este tiene la abilidad de crear playlists desde websites. De manera que si navegas tu index te crea listas, desde las que puedes streamear o bajar directamente. Esta fue mi solución por mucho tiempo, y es buena tenerla como respaldo. El problema es que los archivos no están indexados en una base de datos, entonces tienes que realmente ordenar tu estructura del sistema de archivos y olvídate de tener un icono con una lupa para buscar algo.

Y aquí fue donde me hice a la tarea de investigar otras soluciones. Ahora ya tenía requisitos:

  • La solución tenía que implementarse en mi casa
  • Debería tener una forma de indexar los datos para la búsqueda y para la creación de playlists
  • Puede ser usado con “fat clients” o directamente desde el navegador
  • Darte la habilidad de poder bajar las canciones, ya sea individualmente o en grupo
  • Posible utilización desde dispositivos móviles.

Encontre dos posibles candidatos: Ampache y Jinzora.

Para terminar pronto, Jinzora apesta, al menos para mí. La documentación es tan mala como escasa. Prácticamente nula. Y una vez instalado, buena suerte importando toda tu música. Simplemente no la importa toda y ni siquiera te dice por qué.

Ampache. Alertas con el nombre ehh!, no es ni Tepache, ni tampoco Empache, ni la combinación de las dos: Empache de tepache.

ampacheMuy parecido a la idea del jizora ese pero con la diferencia de que este sirve.

Con Ampache puedes stremear tu música, bajarla, y crear playlists. Todo esto desde cualquier navegador. Utilza XSPF para hacerlo desde el navegador o puedes utilizar cualquier reproductor para streamear desde URL (incluso el cerrado itunes).

Lo que hace a Ampache mas poderoso es la implementación de su API, para que tengas control del contenido de tu servidor desde digamos, tu celular o un cliente, así no solo streameas sino puedes navegar por el contenido de tu base de datos. Así como si tuvieras los archivos localmente.

Además, tiene soporte para Scrobblear a Last.FM y existen algunos clientes que funcionan perfectamente para dispositivos móviles como Android (la neta es el único que he probado)

“Boynas, debiste de haber sido un vendedor de aspiradoras o de enciclopedias en tu otra vida, porque estoy completamente vendido con la idea. Dime como instalarlo YA!”

Ampache es muy ligero, la instalación es rapidísima, es mas ni siquiera te tienes que meter a MySQL a crear las bases de datos. Solamente descargas el archivo en un folder público y navegas a él y proporcionas credenciales para tu MySQL y punto.

Después creas tu catalogo de canciones. Las cuales, si las tienes bien identificadas con su respectivos ID tags, no necesitas nada, sin embargo el sistema también puede identificar los tags por medio de la estructura de carpetas.
Requisitos

  • Servidor Apache con PHP y MySQL (Linux o Windows)
  • Redirección de puertos en tu Router/Firewall
  • Tu aburrida-apunto-de-ser-divertida colección de música

Baja la última versión estable, de ampache.org; Ahora, si celebraste la caída del “Perro Aguayo” es porque no eres “técnico”, sino “rudo”; tu elección seria el “nightly snapshot”.

Estaba a punto de escribir instrucciones pero me di cuenta que sería una especie de falta de respeto a la comunidad que ha batallado tanto para crear documentación, la cual en este proyecto en particular fue clave para adoptar Ampache y no otra cosa. (http://ampache.org/wiki/install)

Eso sí, después de que tengan todo instalado, liberen el API para que tenga contacto con el mundo exterior. De esa manera podrán accesar la base de datos y las canciones desde tu Android (Amdroid) o incluso iPhone (amphone), o bien algún cliente como Amarok o winamp. Para hacer esto, te vas a la cejilla “admin” y a ACL para configurar o agregar un “Access List” para que las IPs exteriores puedan accesar el API. Asegúrate de abrirlo lo suficiente como para que un IP de Tombuctú pueda tener acceso.

Nota del autor: Si alguien sabe una manera menos pendeja de decir “stremear” en español diganmelo por el amor de Dios.

Rentar películas es molesto y obsoleto
Por: Cesar

La única razón por la que rento películas es por los BluRay. No que sea imposible descargarlos, pero el PS3 no soporta archivos MKV, y mi laptop no es lo suficientemente poderosa como para reproducirlos por medio de streaming. Así que la única manera que tengo para ver películas en HD en el PS3 son los BluRay.

Probablemente los lectores de este blog coincidan con que la idea de rentar una película, es decir ir al lugar, ver si tienen una copia disponible (o ver las portadas para elegir una), pagar y regresar a tu casa, sólo para unos días después tener que regresar al establecimiento a devolverla a tiempo o de lo contrario ser penalizados con recargos… la idea es un poco obsoleta, poco práctica, algo que debería ser del pasado.

Sin embargo lo sigo haciendo, por las razones antes mencionadas. Y es extremadamente idiota que cada vez que voy a rentar al mismo establecimiento me hacen las mismas preguntas: ¿Cuál es su teléfono? ¿Desea obtener la promoción de socio distinguido?

De las dos preguntas, la que más me molesta es la primera. En teoría es para prevenir que otra persona rente con tu misma credencial, pero entonces ¿para qué piden credencial, si no basta como método válido de identificación? Además de la credencial, me piden una identificación oficial y mi teléfono. Ni en el cajero me piden tanta cosa para sacar dinero. Además no aceptan otro teléfono que no sea fijo, así que la gente como yo que no tiene teléfono fijo en su casa tiene que dar el teléfono de un conocido.

Si van a ofrecer un servicio que está destinado a compartir la fortuna de la venta de CDs, ya de jodido deberían de hacerlo un poco más amigable. Yo se que cambiar al modelo digital de la noche a la mañana no va a suceder, pero en el inter podrían:

  • Tener kioskos donde consultar el catálogo de películas. Que te indique si la tienen en existencia, en que parte de la tienda está, si hay copias disponibles, etc.
  • El mismo kiosko lo podrían integrar con servicios de la Web para recomendación de películas. Y por favor no cometan la estupidez de utilizarlo para recomendar los estrenos, es suficiente con los carteles de afuera, las 2 millones de copias en los estantes de estrenos y los folletos en caja. No quiero ver comerciales, quiero una recomendación sincera.
  • Y el mismo servicio del kiosko, pero desde los smartphones más populares sería aún mejor.
  • Ofrecer modelos alternativos de suscripción. ¿Un Netflix local?

No me queda duda que en el futuro cercano, la renta de películas pasará a ser digital en su mayoría, quedando algunos nichos como los pequeños videoclubs a la “Be Kind Rewind“. En México nos queda el reto de los costos de las telecomunicaciones, para hacerlas más accesibles a la población, a su vez haciendo económicamente viable esto de los servicios de video digital.

Mientras todo esto sucede, seguiré bajando películas por medio de bittorrent, viéndolas en el PS3 y rentando BluRay… hasta que el hack de Geohot permita soporte para MKV, entonces sí al demonio con Blockbuster.

Controles custom en BlackBerry
Por: Cesar

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!

Opiniones de los G&R’ers sobre Google Buzz
Por: Cesar

El tema caliente de la semana es Google Buzz. Para muchos un quierosertwitter, para otros Twitter como debió ser desde el inicio. ¿Pero que opinan los Geek&Rollers del tema? Veamos:

Axel

No lo he checado porque me enmulé porque no hay en google apps for your domain, pero lo checo y te envío la opinión.

Rafyta

O sea que como no pego el wave a ver si con esta onda se arma?

Boynas

Cuantas veces hemos discutido en twitter y hemos sentido que es molesto para los que siguen nuestro timeline (respeto a los demas en contra de la funcionalidad).
La integracion a otros servicios tanto de fotografias, videos y contenido en general, se me hace menos forzada que la de twitter. Tiene mas features nativos.

Lo mas importante es que es mainstream. No necesito enseñar a un amigo a usarlo, es simple y amigable. A mi me interesa seguir a todo mundo no solo a geeks o a media freaks pesudo-periodistas, que son los que se meten a twitter. Esa es la unica razon por la que tengo FB!
Creo que Buzz es como twitter made right, tiene las threaded comments de FB sin las molestas apps; Sin embargo es ordenado no necesitas brincar de timeline en timeline para seguir una conversacion en la que comento una persona que no conoces.

Buzz esta tapando ese gap. Es lo que debio haber hecho twitter con su red de usuarios hace mucho tiempo.. Es perfectamente un twitter killer. (no mames, hasta rima)

César

Tiene más sentido que Twitter, para mi. Gmail siempre esta abierto en mi navegador. Ahora nomas falta que todos dejen de usar Hotmail y se pasen a Gmail, cosa que no se por qué no ha sucedido todavía. Ah, y que le arreglen eso de que se autorefresca el sitio pero te sigue marcando items no leídos. Y una opción para que cuando leo algo en Buzz, no me aparezca como no leído en la bandeja de entrada de Gmail.

Lo mejor de todo es que, en mi opinión, los clientes exclusivos van a perder relevancia, haciendo mucho más relevantes cosas como lo que está haciendo Ubuntu con su Me Menu y Gwibber. Si todo sale bien, vamos a estar un paso adelante. Eso si, su uso desde el Web siempre va a ser una mejor experiencia, como Google nos tiene acostumbrados.

¿De acuerdo? ¿Desacuerdo? Usen la caja de comentarios. Nos vemos en Buzz.

Desarrollo de software en un mundo post-agil
Por: Cesar

Del artículo:

Un proceso es un instrumento de autoridad. Un proceso es una proclamación de qué hacer, cómo debemos de hacerlo y en qué orden. Un proceso es conservador, jerárquico y formal. Un proceso mantiene el status quo. Es la administración imponiendo orden y control desde arriba. Si los procesos fueran un partido político, sería de derecha.

Es fácil ser seducido por las bondades de la metodología ágil. Promesas de equipos auto suficientes, entregas frecuentes y listas para producción, Yippi-kay-ay. Demasiado proceso y en vez de avanzar nos quedamos llenando reportes y formas; muy poco proceso y todo se vuelve un manojo de actividad descontrolada y poco empuje (y entrega).

El artículo discute la etiqueta “ágil” que tanto se usa en administración de proyectos de software hoy en día. Por ahí leí que “scrum” (intercambiado por ágil en esta ocasión) no es una bala de plata para tener proyectos exitosos. Existen factores como la experiencia y motivación del equipo, así como también la naturaleza del proyecto, por lo que una aproximación orientada a personas tiene más sentido que orientado a procesos, y viceversa.

Lean el artículo fuente (en Inglés), y los invito a dejar sus comentarios sobre el tema, experiencias personales, etc.

Estamos de vuelta!
Por: Cesar

Debido a que ocurrió un overflow cuando intentamos pagar el dominio, GoDaddy no permitió el acceso a este blog por medio de nuestro dominio. Los detalles no los se, solo que el BigInt que utilizan para guardar la cantidad del pago no alcanzó, y por tanto el overflow, causando todo tipo de problemas.

Gracias por su paciencia. Estamos de vuelta, keep on Geek&Rolling!

Cuidado con cambiar de BlackBerry en Telcel
Por: Cesar

Hace poco decidí cambiar de modelo de BlackBerry, de la viejita 8110 a la un poquito más moderna 8520. Al ir a Telcel me dijeron que con mi plan era imposible cambiar al equipo que yo quería, aún cuando quisiera pagar el costo total del mismo.

Como en Telcel me la hicieron difícil, compré el equipo aparte y le cambié el chip. Hasta ahí todo bien, sin embargo al llegar la factura veo que me cobran la conexión de datos, aún cuando mi plan incluye datos ilimitados. En la factura me cobran el plan (con datos ilimitados incluidos) más los datos consumidos. Obviamente algo andaba mal. Después de dos visitas al centro de “atención” al cliente – que de atención no tiene nada – no me pudieron resolver mi problema. Las dos personas que me atendieron coincidían en que “que raro!?!?” y levantaron un reporte.

Gracias a que tengo a una persona conocida que trabaja en el corporativo, después de unos cuantos SMS’s el problema quedó aclarado y resuelto. Bueno, resuelto a medias porque voy a tener que pagar el cargo excesivo.

El problema, y lo que nunca me pudieron explicar en el centro de pseudo-atención, fue que al cambiar de equipo si tienes un plan de datos ilimitados, esto no se te respeta. En ningún lugar te lo indican, tampoco te lo advierten en Telcel. Y lo que es peor, nunca me lo superion resolver. Tuve que usar “palancas” del corporativo para que me resolvieran, ya que los asesores del centro de atención se limitaron a rascarse la cabeza. Nunca me preguntaron ¿No cambió su equipo señor?

Así que si tienen una BlackBerry y deciden cambiar de equipo, antes de meter su chip en el equipo nuevo, vayan a su centro de atención y pidan que les hagan el cambio para evitar cargos excesivos. Esta información la deberían de proporcionar de primera mano en Telcel, pero como siempre con prácticas poco éticas para sacar hasta el último centavo.

No iba a proporcionar información, pero por el coraje que me hicieron pasar les muestro una captura de pantalla de lo que será Everlasting Flame 2.0. Descárguenlo y eviten pagarle más de la cuenta a Telcel.

ELF2

Proyectos locales

  • Everlasting Flame. Termina llamadas automáticamente (auto hangup) en tu BlackBerry.

Actividad en Github

"ELF.jad" is at cesarolea/Everlasting-Flame/downloads
When: 1 March 2010, 4:45 pm
"ELF.cod" is at cesarolea/Everlasting-Flame/downloads

Everlasting Flame 1.2 w/OS 5 fix.

When: 1 March 2010, 4:45 pm
Push
  • cesarolea committed c6d16e8
    Added reset to isMonitoring flag. Now works when calling for a second time.
When: 26 February 2010, 9:18 pm
Push
  • cesarolea committed 68721b2
    Added reset to isMonitoring flag. Now works when calling for a second time.
When: 26 February 2010, 9:06 pm
Push
  • cesarolea committed 554b9b5
    Fixed issue with 9700 where doCallMonitoring was fired twice.
  • cesarolea committed f3a06eb
    Deleted notifications since those were not available in 1.2
When: 26 February 2010, 8:23 pm
Push
  • cesarolea committed 024b3ec
    Added permission verification to CustomPhoneListener.java
When: 26 February 2010, 4:38 pm
Push
  • cesarolea committed 0db0120
    Modified end call injection. Added application permission verification.
When: 26 February 2010, 4:12 pm
Create
New branch is at cesarolea/Everlasting-Flame/tree/1.2
Compare 1.2 branch with master »
When: 26 February 2010, 2:07 pm
Push
  • cesarolea committed c6d570b
    Added redial feature. Needs testing.
When: 24 February 2010, 10:39 pm
Push
  • cesarolea committed 42e3c3c
    Implemented transition to non-contact based number list.
When: 24 February 2010, 10:37 pm
Push
  • cesarolea committed 476f5c4
    Created PIM screen and menu item.
When: 13 February 2010, 8:21 pm
Push
  • cesarolea committed eb02f91
    Added status bar buttons and started the PIM screen.
  • cesarolea committed 024bb07
    setCurrentTime and getCurrentTime methods added to TimePanel
  • cesarolea committed fd69e85
    Implemented TimePanel and started on the final Config Screen.
When: 21 January 2010, 9:01 pm
Create
New branch is at cesarolea/Everlasting-Flame/tree/gui
Compare gui branch with master »
When: 12 January 2010, 11:14 pm
Push
  • cesarolea committed 1e94dfb
    Fixed bug with init code. Selected notification method was not initialized correctly.
When: 5 January 2010, 10:55 pm
Push
  • cesarolea committed 3f41f4f
    Fixed Notification combo. Selected option is now persisted.
When: 5 January 2010, 9:06 pm
java-mateview's description:
A TextMate syntax compatible source editing widget. Current adapters are for SWT.
When: 30 November 2009, 12:16 pm
Create
New branch is at cesarolea/Everlasting-Flame/tree/notifications
Compare notifications branch with master »
When: 3 November 2009, 4:57 pm
Create
New branch is at cesarolea/Everlasting-Flame/tree/master
Compare master branch with master »
When: 3 November 2009, 4:47 pm
Create
New repository is at cesarolea/Everlasting-Flame
When: 3 November 2009, 1:42 pm
Push
  • cesarolea committed b2342b9
    Modified inventory handling and removed the global inventory
When: 3 November 2009, 1:31 pm
Push
  • cesarolea committed 57c68c1
    Modified the gitignore to include the dist directory
When: 22 October 2009, 5:02 pm
Push
  • cesarolea committed c0cfffe
    Inventory add product initial implementation
When: 28 September 2009, 6:53 pm

Stack Overflow Flair

Actividad reciente en Stack Overflow

StackOverflow
Inside your class that extends RemoteServiceServlet: public class MyServiceImpl extends RemoteServiceServlet implements MyService { public void myMethod(String s) { //Use ProcessBuilder here, or whatever you need. } }
Permalink
When: 9 March 2010, 8:41 pm
StackOverflow
Remote Procedure Calls (RPCs) are the main mechanism GWT uses to communicate with the server. A RPC is regular Java bytecode running on the server thus you can use basically any Java class as part of your RPC code. Read more on the official documentation: code.google.com/webtoolkit/doc/latest/…
Permalink
When: 9 March 2010, 7:01 pm
StackOverflow

Your question is about GWT supporting ProcessBuilder, but the error you get is from Google App Engine and not GWT related.

If you are using ProcessBuilder from a GWT RPC method you shouldn't have any problems. However, you are using Google App Engine as your application server. Google App Engine doesn't support ProcessBuilder, and a bunch of other things are not supported by GAE.

Check out the Will it play in Google App Engine? as a reference to know if your particular feature is supported in GAE.

It's important to note that ProcessBuilder is not supported by Google App Engine. GWT uses regular Java in its RPCs so ProcessBuilder can be used there.

Permalink
When: 9 March 2010, 6:50 pm
StackOverflow
Thanks for the insight. I wouldn't want to get into convoluted hacks to get it to work, but the JSON idea looks promising. I just wanted to be sure if there was anything in GWT that would allow me to do it directly.
Permalink
When: 3 March 2010, 6:03 pm
StackOverflow

Hi, I have the following requirement: Based on some user input, I need to generate a HTML form that the user can embed on a separate Web application. I thought on doing this with GWT since I'm familiar with it.

I'm clear on the input parsing and widget generation part. What I don't know how to do is how to export the root widget's (most probably a Panel) compiled code, so the user can take the code and include it in some other page.

Something like:

String rootPanelCode = rootPanel.exportCode();
Dialog codeDialog = new DialogBox();
codeDialog.setText(rootPanelCode);

Then the user copies the displayed code in some HTML file:

<script type="text/javascript" language="javascript">
    //copied code goes here
</script>

Requiring a particular <div id="required_id" /> in the HTML file is not a problem. Or maybe javascript code is not enough, and the user is required to download a zip file with js and html files, copy those to a directory and reference them in the page. This again is not a problem.

Is my use case possible with GWT?

Thanks in advance.

Permalink
When: 3 March 2010, 4:09 pm
StackOverflow

Try this:

public class DisposeJFrame extends JFrame{
    JPanel panel = new JPanel();
    JButton button = new JButton("Dispose JFrame");

    public DisposeJFrame(){
        super();
        setTitle("Hi");
        panel.add(button);
        add(panel);
        pack();

        button.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent arg0) {
                dispose();
            }
        });
    }

    public static void main(String args[]){
        SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                DisposeJFrame jf = new DisposeJFrame();
                    jf.setVisible(true);
            }
        });
    }
}
Permalink
When: 1 March 2010, 1:27 pm
StackOverflow

You can use ant to run your tests with a single command with the junit ant task. Here's an example on how to use it:

<target name="runtests" depends="clean,compiletests">           
    <junit printsummary="yes" haltonfailure="no">
        <classpath>
            <path refid="test.classpath" />                 
            <pathelement location="${test.classes}"/>
        </classpath>                                
        <formatter type="xml"/>     
        <batchtest fork="yes" todir="${test.reports}">
            <fileset dir="${test.src}">
                <include name="**/*Test*.java"/>
            </fileset>
        </batchtest>
    </junit>        
</target>

That target uses batchtest which is part of the junit ant task. It sets your test classpath so all your tests that contain the Test.java pattern in their class name will be included. Check out the JUnit Task documentation.

Permalink
When: 1 March 2010, 8:35 am
StackOverflow

With my current customer we are required to develop on Windows (virtualized, running on client owned servers) and deploy on AIX. With other customers I develop on Ubuntu and deploy to whatever OS the customer requires or already have. Just be sure to have a staging server mirroring the production architecture as close as possible and test there.

Permalink
When: 26 February 2010, 7:03 pm
StackOverflow
It would be very helpful if you could post the error you get when trying to compile.
Permalink
When: 26 February 2010, 8:25 am
StackOverflow
For the animation between squares, check out the GlassPane. A Glass Pane is like a sheet of glass that sits atop your frame, you can use that to paint custom animations between components, in this case your individual squares.
Permalink
When: 21 February 2010, 12:25 pm
StackOverflow

It's possible to do it with PHP. Not a typical use case scenario but it can be done. Since you are on Windows, a bat file would be better suited since then you don't need the PHP parser to run the script.

Put the same commands you would run in the console to convert your audio files with LAME in a *.bat. Then run the bat as if it was a regular executable file.

Permalink
When: 20 February 2010, 10:21 pm
StackOverflow

I don't see anything wrong with using JPanels. Here's my implementation:

First a ChessSquare, this represents one cell on the board:

public class ChessSquare extends JPanel{
    int x,y;

    public ChessSquare(int x, int y){
        super();
        this.setPreferredSize(new Dimension(50,50));
        this.setBorder(BorderFactory.createLineBorder(Color.black));
        this.x = x;
        this.y = y;
    }
}

Now the main board panel:

public class ChessPanel extends JPanel{
    JPanel positions[][] = new JPanel[8][8];
    ChessSquare move[] = new ChessSquare[2];

    public ChessPanel(){
        initComponents();
    }

    private void initComponents(){
        setLayout(new GridLayout(8,8));

        for(int i=0;i<positions.length;i++){
            for(int j=0;j<positions[i].length;j++){
                ChessSquare square = new ChessSquare(i,j);
                square.addMouseListener(new MouseListener(){
                    public void mouseClicked(MouseEvent me) {
                        ChessSquare cs = (ChessSquare)me.getComponent();
                        if(isValidMove(cs)){

                            System.out.println("Valid move!");
                            System.out.println("x1: "+move[0].x+" y1: "+move[0].y);
                            System.out.println("x2: "+move[1].x+" y2: "+move[1].y);
                            System.out.println("");

                            resetMove();
                        }
                    }

                    //Other mouse events

                });
                positions[i][j] = square;
                add(square);
            }
        }
    }

    private boolean isValidMove(ChessSquare square){
        //here you would check if the move is valid.
        if(move[0] == null){
            move[0] = square;
            return false; //first click
        }else{
            move[1] = square;
        }

        //Other chess rules go here...
        return true;
    }

    private void resetMove(){
        move = new ChessSquare[2];
    }
}

We keep a JPanel matrix to represent the board, and ChessSquare array to represent the current move. In isValidMove() we check to see if the current move is complete (both squares have been clicked, thus the move array already has one element). Once a move is complete, we reset the move and start again.

Permalink
When: 20 February 2010, 5:34 pm
StackOverflow

Use git. You have all the version control system benefits, but working locally. If your project code is already in SVN, it's possible to use git-svn to make both git and svn collaborate. Here's an easy to follow guide on git-svn by example.

With git it's easy to branch so you'll want to branch very often. Git branches are different from SVN branches: they are stored locally and it's not simply a copy of your whole project like in SVN. Finally, Set up Dropbox in both computers so your changes are synched automatically.

So your workflow could be something like this:

  • git-svn clone http://mysvnrepo local_dir to get your local repository
  • git checkout -b my_new_branch when you want to work on a new feature
  • Check in your code as often as you need, without worrying about breaking other people's code
  • Local changes are kept in sync automatically thanks to Dropbox
  • When your code is ready, merge it to the master branch with git merge my_new_branch
  • And commit your changes back to the subversion repository, first update your local repository with git-svn rebase and then commit with git-svn dcommit
Permalink
When: 20 February 2010, 4:26 pm
StackOverflow

You need to use a ListIterator you use that to traverse the List in either direction. The iterator contains methods such as previous() and next(). Check it out in the Javadocs.

To get the ListIterator for your current list, call its listIterator(int index) method.

Permalink
When: 19 February 2010, 8:55 am
StackOverflow
I never implied you are stupid, I'm just trying to help. In your comment you clearly stated that in the image I linked you don't see any SVN folder, which there is. I read your question clearly and I'm aware that what you linked is not your installation.
Permalink
When: 17 February 2010, 8:41 am
StackOverflow
I wasn't aware of that either.
Permalink
When: 16 February 2010, 7:46 pm
StackOverflow

There's no way you used the JRE to compile Java programs. javac, the Java compiler, only comes with the JDK.

  • You may write Java programs with whatever text editor, you don't need anything special to do this.
  • You need the JRE to run Java programs. The JRE includes the Java Virtual Machine, needed to run already compiled Java programs.
  • You need the JDK to compile Java programs. So if you are a Java developer, you may want to only install the JDK since it comes with the tools needed to compile, in addition to the Java Virtual Machine.
Permalink
When: 16 February 2010, 5:52 pm
StackOverflow

Even when approaches like serializing objects and then deserializing them is useful, you have to make sure you understand first why your objects "disappear".

HTTP, the protocol used to retrieve pages and other resources from Web servers, is stateless. It basically means one request knows nothing from another request, even when it came from the same user. Think of it this way, when you request your PHP page, the script is run and after it finishes Apache sends out the result to you. When you request the page again, it does the same thing as if it was the very first time you did it. It's stateless.

There are techniques to keep state between requests (make it to not forget your objects) and those involve things like cookies or URL rewriting. But you have to keep in mind the stateless nature of HTTP (and thus your PHP script) when developing Web applications.

Permalink
When: 16 February 2010, 5:47 pm
StackOverflow
What do you mean by in the image I linked above you don't see any SVN folder? Come on! It's right there, it's even the selected option!
Permalink
When: 16 February 2010, 5:23 pm
StackOverflow
Check this image: dokeos.com/wiki/images/2/29/Eclipse-svn-02.jpg If you don't see that, then Subclipse is not correctly installed. I suggest you install it again from Subclipse update site subclipse.tigris.org/update_1.6.x I installed it as I type this and it works flawlessly.
Permalink
When: 16 February 2010, 5:05 pm
StackOverflow
Assuming you installed Subclipse correctly, run Eclipse with the -clean argument to make it clear your cache data. Then you should have the checkout project from SVN option, which should be under the SVN project type.
Permalink
When: 16 February 2010, 4:52 pm
StackOverflow

I don't know what you are looking for. But after installing the Subclipse plugin, you should have a new entry in the File | New | Project dialog. Something along the lines of "Checkout project from SVN"

Then when you hit continue, you can enter your SVN repository details, check the branch you are interested in, etc. After checking out a project, you can right click on it and go to the "Team" submenu to get the features provided by Subclipse like check in code, diff, merge, etc.

Permalink
When: 16 February 2010, 4:42 pm
StackOverflow
Since you are restricted to multiplatform, AIR is a good option. Create a separate "bootstrap" program. You could store your main program version in a separate file, and send it via a HTTP request to your server. In the server you check to see if that version is the latest version and if it isn't, offer to download the new version.
Permalink
When: 16 February 2010, 4:33 pm
StackOverflow

If your target is Windows, you need to look at the autorun.inf file specification. This file needs to be located in the root directory, and you can use it to specify any program you want to run when the device is inserted. Please note that the feature can be disabled by the user.

The part to check if there's a new version and download it, etc... that depends heavily on the language you are using to develop such program.

Permalink
When: 16 February 2010, 4:16 pm
StackOverflow
+1 because I loathe TOAD.
Permalink
When: 16 February 2010, 10:53 am
StackOverflow

While reading about OO design and programming you'll come across two concepts: coupling and cohesion. The former is about how each class depends on each other, and the later is about a class focusing on those things that are its responsibility.

Without getting deeper on the topic, I bring up those two concepts because it has helped me a lot to thing on those terms. The first step is to be clear on what your application must do. Think about the "happy path" as well as what happens when things go wrong, for example the user not filling in the right information.

Now start designing your classes, how those relate and what each class provides to the system as a whole. This design phase is typically represented as a set of UML diagrams, but some written paragraphs would do if you are not familiar with UML. If you see a class is doing things that don't belong there, change your design. It's inexpensive to change it while on paper.

Don't start thinking on how to implement certain functions just yet. For example if your application will use the GPS hardware, don't worry on how to access it. Suppose that part is solved. Start thinking on what you'll do with the data? Which class will receive that data? Who's going to process it?

Permalink
When: 15 February 2010, 3:47 pm
StackOverflow

If what you want is minimum dependency with external files or DLLs you could statically compile all the required DLLs with the tool exe. Then you could use something like Visual C++ to develop such tool.

Permalink
When: 13 February 2010, 11:16 am
StackOverflow

You defined AssocCovList to have the following properties:

Integer id
Integer association_id
Integer cov_list_id
Date edit_date

And then try to create a new AssocCovList(association_id:3) using only the association_id. However, by default all properties are both persistent and required. To create a new AssocCovList you would need to provide also the id, cov_list_id and edit_date.

Permalink
When: 10 February 2010, 10:27 am
StackOverflow
Sorry for not being clear enough. The response you get from an async request made from JavaScript, is the same you would get if your request was not made via AJAX. In short, yes you can set cookies if your request was made with AJAX. It depends on the server side code to set response headers.
Permalink
When: 9 February 2010, 10:46 am
StackOverflow

An AJAX request contains the same request/response information as a traditional HTTP request. You can set cookies on the client once the async callback is executed, etc.

Permalink
When: 7 February 2010, 7:02 pm
StackOverflow
Agree, this is an easy question to answer by means of a Google search, but it is a programming related question so we should try to answer it. That's my opinion anyways.
Permalink
When: 7 February 2010, 12:41 pm
StackOverflow

REST stands for Representational State Transfer, and it was proposed in a doctorate dissertation (see here). It uses the four HTTP methods GET, POST, PUT and DELETE to execute different operations. This in contrast to SOAP for example, which creates new arbitrary commands (verbs) like getAccounts() or applyDiscount()

A REST API is a set of operations that can be invoked by means of any the four verbs, using the actual URI as parameters for your operations. For example you may have a method to query all your accounts which can be called from /accounts/all/ this invokes a HTTP GET and the 'all' parameter tells your application that it shall return all accounts.

Permalink
When: 7 February 2010, 12:36 pm
StackOverflow

If you want to create your own borderless window, instead of using a Frame/JFrame use a Window/JWindow. Frame/JFrame are extensions to Window/JWindow that provide borders and the maximize, minimize and close buttons. Usually those widgets are provided by the OS, but you can override them.

Permalink
When: 6 February 2010, 4:03 pm
StackOverflow

When you compile something in Java, the compiler generates bytecode. This is native code for the Java Virtual Machine. The JVM then translates the bytecode to native code for your processor/architecture, this is where the JIT happens. Without JIT, the JVM would translate the program one instruction at a time, which is very slow.

Permalink
When: 4 February 2010, 3:19 pm
StackOverflow

While XPath is a great choice, I would recommend JDom if your XML document is not huge, since it loads the entire document in memory.

Using JDom:

try {
    SAXBuilder builder = new SAXBuilder();
    Document firstDocument = builder.build(firstFile);
    Document secondDocument = builder.build(secondFile);

    Element firstRoot = firstDocument.getRootElement();
    Element secondRoot = secondDocument.getRootElement();

    List<Element> sourceListPost = secondRoot.getChild("listPost");
    firstRoot.addContent(sourceListPost);

    Document merged = new Document(firstRoot);
} catch(JDOMException e) {
    e.printStackTrace();
} catch(IOException e) {
    e.printStackTrace();
}

Now merged contains the merged Document. You can serialize it to a file with XMLOutputter.

Permalink
When: 3 February 2010, 12:24 pm
StackOverflow

You don't need an applet, from a grails controller you may use any Java library. Use the Java printing services available to the runtime in javax.print. This is assuming that the printer is installed where the grails runtime is running.

Permalink
When: 3 February 2010, 8:36 am
StackOverflow
It's very important to point out that Object Oriented Programming is language independent, so it stays the same when moving from language to language.
Permalink
When: 1 February 2010, 9:34 pm
StackOverflow
URLDecoder.decode(url);

See related question http://stackoverflow.com/questions/623861/how-do-you-unescape-urls-in-java

Permalink
When: 29 January 2010, 5:42 pm
StackOverflow

I think you would benefit greatly with a build tool, such as ant or maven. You can have a target to compile only one class without building the whole code, or any other related task.

Permalink
When: 28 January 2010, 10:14 pm
StackOverflow

There's nothing wrong with the way you are compiling, it's just cumbersome but certainly not wrong.

That being said, create a src directory to store your .java files, keeping your directory structure coherent with the package structure of your classes. In this case you would have src directory and inside it, directory A and directory B. Inside A put Test1.java and inside B put Test2.java

Then:

javac B/Test2.java

Why Test2.java? Because it depends on A, then the compiler is smart enough to first compile A/Test1.java and then B/Test2.java. At this point you have each .class files inside A and B

To run it:

java B.Test2
Permalink
When: 28 January 2010, 9:23 pm
StackOverflow

My only advise would be don't go that way. As Bill K already said, most implementations would be significantly faster and more complete. Even more important is that there are excellent resources to achieve what you are trying to do: OSGi for example which has Eclipse and Glassfish v3 under its belt.

Personally I implemented something similar to your description, loading plugins at runtime without needing to restart the container. It was a nightmare to maintain and debug. And more important, while it was relatively easy for me to implement new modules (after all, I designed the thing), it was very difficult to program to. I ended up learning a lot about classloaders, but that was it.

Permalink
When: 28 January 2010, 4:38 pm
StackOverflow

If you fix the scaleMod and initialDistance to powers of 2 you could use shifts for faster multiplication and division.

See here for reference.

Permalink
When: 27 January 2010, 1:54 pm
StackOverflow

Check out Web Harvest. It's both a library you can use and a data extraction tool, which sounds to me that's exactly what you want to do. You create XML script files to instruct the scraper how to extract the information you need and from where. The provided GUI is very useful to quickly test the scripts.

Check out the project's samples page to see if it's a good fit for what you are trying to do.

Permalink
When: 24 January 2010, 6:16 pm
StackOverflow

JComboBox constructor can take a ComboBoxModel as argument. DefaultComboBoxModel is a concrete implementation of the ComboBoxModel interface.

So, if you have a Personel class:

class Personel{
    String personelName;
    int personelId;
    //getters, setters

    //This will be your display member
    @Override
    public String toString(){
        return this.personelName;
    }
}

And supposing you obtained all personel via JDBC and have it stored in a new Vector, you can do:

DefaultComboBoxModel comboModel = new DefaultComboBoxModel(personel);
JComboBox myCombo = new JComboBox(comboModel);

At runtime, you can getModel and setModel to access the JComboBox model. The display member will be Personel's toString() method. The value member will be the actual object stored in the DefaultComboBoxModel vector, in this case a Personel instance.

I suggest you take a look at the API documentation for ComboBoxModel and DefaultComboBoxModel.

Permalink
When: 24 January 2010, 5:32 pm
StackOverflow

You would use a regular expression to search for @username and then turn that to the corresponding link.

I use the following for the @ in PHP:

$ret = preg_replace("#(^|[\n ])@([^ \"\t\n\r<]*)#ise", 
                    "'\\1<a href=\"http://www.twitter.com/\\2\" >@\\2</a>'", 
                    $ret);
Permalink
When: 9 January 2010, 1:17 pm
@cesarolea
@rafyta que show man? Donde andas?
5 hours, 21 minutes ago
@cesarolea
@gabrielcod inche JPA estandar mis polainas. Hibernate dicta el estandar y ademas lo implementa.
5 hours, 22 minutes ago
@cesarolea
Ya a la fregada con JPA. Back to basics con Hibernate.
7 hours, 34 minutes ago
@cesarolea
@mmosquedab groovy in action es la mejor referencia.
1 day, 10 hours ago
@cesarolea
El cielo de hermosillo. http://tweetphoto.com/13621206
2 days, 6 hours ago
@cesarolea
@moronimontoya jajajaja andale exactamente.
2 days, 21 hours ago
@cesarolea
Como tronco cayo. Bien por el canelo.
2 days, 21 hours ago
@cesarolea
Lo hizo pedazos el venezolano. Pedazos te digo!
2 days, 21 hours ago
@cesarolea
@btocastillon por fin supe! Queda aqui cerca de donde vivo y siempre me preguntaba que ira a ser?
2 days, 22 hours ago
@cesarolea
Hoy pelea el canelo. Chingazos pues!
2 days, 22 hours ago