Tuesday September 26, 2006
Humanética
db4o
Bueno, y después de escuchar tanto de sobre db4o y sus maravillas he decidido probarlo. Estoy leyendo la documentación (con la idea adicional de buscar un proyecto real en el cual utilizarlo; algo pequeño, para comenzar).
Qué fácil es persistir objetos y realizar las operaciones asociadas, incluso con objetos estructurados. También es sencillo realizar consultas, utilizar filtros con diferentes criterios, y manejar la herencia. Hay soporte para transacciones y se puede trabajar de forma embebida o como un servidor.
Los problemas que hasta ahora he encontrado (ya sea por ignorancia o porque realmente es una limitación de db4o) son los siguientes:
- Si se envía una orden de borrar a un objeto que es referenciado por otro, se borra sin más, quedando objetos que referencian a uno que ya no existe. Es decir, no hay una restricción tipo Foreign Key de una base de datos relacional.
- Para identificar un objeto, hay que recuperarlo. Al parecer no existe una forma de generar identificadores únicos para los mismos (bueno, tal vez esta no sea una limitación, sino mi forma de pensar).
- No encuentro una forma de establecer una regla en la que solo exista un objeto con un valor en una de sus propiedades (por decir algo, no pueden existir dos ciudadanos con el mismo documento de identidad).
- Los cálculos matemáticos sobre propiedades de los objetos no parece tan sencillo. El sql siempre me maravilló por su capacidad de crear "miles" de consultas distintas, algunas de las cuales pueden incluir cálculos verdaderamente complejos.
- Tampoco veo claro como realizar consultas que abarquen varios objetos de forma masiva (algo así como consultas con join en una rdbms).
Posted at 11:42PM Sep 26, 2006 by Ricardo in Java |
JDeveloper, primera impresion
Hasta ahora he usado como IDEs de desarrollo en Java Eclipse y Netbeans. Ambos me parecen buenos, sobre todo desde la última versión (5.0) de Netbeas que ha mejorado bastante.
Ayer decidí bajar el JDeveloper de la página de Oracle para probarlo, ya que se tiene una versión gratuita. Tiene un aspecto bastante parecido al Netbeans (¿no estará construido sobre la misma base?), al menos en su apariencia inicial. Su manejo se siente "suave". Hay dos cosas que me han agradado mucho: 1)Tiene muy buena documentación (en inglés). Incluye tutoriales y presentaciones de demostración (si visitan los tutoriales en línea no se olviden de poner el cursor encima de los anteojos para ver las capturas de pantalla) 2)Al parecer viene integrado con todo lo necesario para comenzar a desarrollar tanto aplicaciones web como de escritorio sin necesidad de instalarle plugins y otras cosas (he bajado el Studio Download). Eso sí, el archivo pesa más de 250 MB y además requiere es exigente con los recursos.
Por otra parte me ha llamado mucho la atención el Oracle Application Development Framework (ADF).
ADF consta de:
- Oracle ADF Model
- Oracle ADF Controller (permite integrar Struts y JSF con el Oracle ADF Model )
- Oracle ADF Faces (ofrece una librería de componentes para aplicaciones web construidas con JSF). Si mal no recuerdo esta es la parte que Oracle donó a la fundación Apache.
- Oracle ADF Swing (extiende el Oracle ADF Model para construir aplicaciones con Swing )
- Oracle ADF Business Components (simplifica la creación de servicios de negocios a los desarrolladores familiarizados con herramientas 4GL como Oracle Forms).
En la página de Oracle hay un diagrama con la arquitectura de estos componentes, así como explicaciones mucho más detalladas.
Otro aspecto interesante es el uso de TopLink como mecanismo de persistencia. Encima del cual se ha construido una implementación compatible con EJB3 (algo similar a lo que ocurre con hibernate y la implementación de EJB3 construida sobre el mismo). Esta es la razón por la que llegué ha descargar JDeveloper, buscando una implementación de EJB3 distinta de hibernate.
Nota.- Para acceder a la descarga (y posiblemente también la documentación) necesitan registrarse (de forma gratuita).
Posted at 02:32AM Feb 06, 2006 by Ricardo in Java | Comentarios[0]
Cáñamo (o Canyamo)
Sí, ya formo parte del grupo de desarrolladores de Cáñamo. Fue Al quién me capturó (o re-capturó) cuando puse unos post de HSQLDB (aquí mismo), indicándome que andaba buscando alguién que elabore un servicio que levante esta BD para que con solo descargar el paquete se pueda instalar algo funcional de la forma mas fácil posible (seguramente a la fecha está arrepentido de haberme hecho esa invitación ;) ). Aún no he terminado esta primera tarea, al menos no he dejado las cosas como me gustaría.
Dicho sea de paso ya he metido las cuatro (patas) subiendo cosas al CVS que no debería o haciendolo en un formato inadecuado. En fin, mientras no borre el trabajo efectuado durante años, supongo que podrán tolerarme :D. Aunque he de decir que ahora ando con un poco mas de cuidado al hacer algo que desconozco.
Para quienes no estén enterados que es Cáñamo(también conocido como Canyamo) pueden visitar su sitio web recientemente remodelado y enterarse que es un framework para elaborar aplicaciones web. Además, si eres un visitante habitual de javaHispano saber que el mismo utiliza Cáñamo para funcionar es casi una obligación.
Este framework consta de un núcleo y varias aplicaciones (se pueden construir tantas como se necesiten). El núcleo tiene una licencia libre (tipo BSD) y cada una de las aplicaciones puede tener una licencia distinta dependiendo de su creador (hasta el momento, todas tienen algún tipo de licencia libre). De modo que lo puedes descargar y utilizar sin ningún problema. Si necesitas ayuda puedes inscribirte a alguna de las listas de distribución (el enlace está en la sección Contactar).
Quizá uno de los puntos más flojos que tenemos (por ahora) es la documentación. Y eso que somos varios los que hemos indicado que podíamos aportar en este sentido (incluyendo alguno que ya tienen registrado los pasos que han seguido para instalarlo) y hasta ahora no lo hemos hecho. Pero ya llegará (si no somos nosotros lo hará otro :D, es broma ;) ). Uno de mis errores fue pensar que podía documentar algo que no domino; y una de las paradojas de esto es que mientras más fácil quieras hacer tu explicación tienes que conocer mas del tema. Así que un poquito (o un pocote) de paciencia. Por el momento, lo mejor es inscribirse a la lista de usuarios y hacer las preguntas por ese medio y utilizar los pocos documentos existentes.
Bien, en otro post les estaré relatando mas cosas sobre este framework; conforme vaya aprendiendo. Tal vez inclusive como instalarlo y esas cosillas (como un ensayo a información que pueda luego utilizarse en la documentación).
Posted at 08:50PM Jun 05, 2004 by Ricardo in Java | Comentarios[0]
SWT e Impresión
En estas dos semanas he estado luchando con la impresión en Java. Busqué dentro de las clases estándar, y quedé un poco mareado ... hay cosas por aquí y por allá, y no sabía cual utilizar (al final de cuentas existen muchas formas para imprimir). Parece ser que la evolución de los métodos de impresión con el objetivo de mejorar ha hecho que coexista lo antiguo y lo nuevo.
Bien, una de las últimas cosas que encontré fue un tutorial sobre Java Print Service (JPS) en una página de Sun. Se menciona que es el nuevo API de Java para impresión (no estoy seguro si ahora se podrá hacer esta afirmación), que permite impresión multiplataforma etc. etc. También se hace una breve reseña histórica de la impresión en Java. Luego se pasa a explicar varios temas, incluyendo como usar el API, con ejemplos. Sin embargo, no me fue tan fácil entenderlo, y como andaba apurado busqué otras alternativas, como el uso de herramientas preparadas para elaborar informes: Datavision, JasperReports (complementado con iReport) y algún otro por ahí que no recuerdo el nombre.
Probé el Datavision. Y sí, obtuve unos informes casi como los quería. Pero no estaba convencido. Para comenzar requiere una librería como de unas 6 archivos jar y yo estaba tratando de que mi aplicación (con librerías y todo) sea lo más pequeña posible. Luego, como que está mas preparado para elaborar listados y ese tipo de cosas obteniendo los datos de una BD. Yo estaba buscando algo mas sencillo y flexible a la vez.
Así que me fuí a mirar las clases de SWT. Más concretamente el paquete org.eclipse.swt.printing. Ya le había hechado el ojo desde mucho antes, pero no estoy seguro porque lo deje para el final. Sí, era lo que buscaba. El paquete cuenta con 3 clases: PrintDialog, Printer y PrinterData. La primera sirve para seleccionar una impresora mediante un cuadro de diálogo. La segunda es para enviar las tareas propias de impresión y la tercera para describir el trabajo de impresión (ejemplo el número de páginas y copias).
A grandes rasgos, el trabajo de impresión se realiza creando una instancia de la clase GC (una clase de SWT diseñada para tareas de dibujo) sobre una impresora (new GC(printer)) y luego dibujando el texto, las líneas, gráficos, etc. en el GC. Para ello esta clase dispone de una serie de métodos especialmente diseñados. Si desean tener mayor dominio de impresión con el paquete de SWT les recomiendo estudiar la clase GC. No voy a explicar más detalles porque creo que la documentación esta bastante clara, complementada con los snippets que contiene en la parte inferior.
La impresión se realiza en modo gráfico. Y claro no todo es color de rosas. Tuve problemas con una impresora Epson LX-300 conectada a una PC con Windows 98. Las letras salían pequeñitas y "no me hacía caso" cuando le cambiaba de tamaño. Luego probé con otra impresora del mismo modelo conectada a otra PC con Windows XP y todo salía bien. La pregunta es ¿es problema de la impresora?, ¿del driver?, ¿de la clase?.
No estoy seguro si en el fondo este paquete de SWT utiliza las librerías de Java o hace un puente a través de JNI. Aunque con mucha probabilidad es esta última opción. Lo que si estoy seguro es que se podrían elaborar herramientas bastante potentes para elaborar informes sobre este paquete, y con eso se tendría todo bien complementado. Aunque quien sabe no sea necesario y las herramientas existente sean lo suficientemente buenas (al propósito el JasperReports se veía muy interesante pero la documentación es escasa -creo- a menos que se compre el tutorial).
Posted at 03:10AM May 21, 2004 by Ricardo in Java | Comentarios[2]
HSQL: CREAR FUNCIONES Y SP
Les decía que los procedimientos almacenados en HSQL no lo son en realidad. Por lo tanto no podrán utilizar los conocidos comandos CREATE/ALTER/DROP PROCEDURE.
Para crear un procedimiento almacenado (y también funciones) hay que seguir los siguientes pasos (esto es casi una traducción de un mensaje de Campbell Boucher-Burnet):
- Escribir una clase con métodos estáticos y públicos que harán de procedimientos almacenados (o funciones).
- Iniciar la base de datos con esa clase en el classpath.
- Hacer uso de los métodos, llamándolos de la siguiente forma "paquete.Clase.método"(arg1, arg2 ... argN). Es decir, ha de especificarse su ubicación completa encerrando entre comillas. Los paréntesis y argumentos van fuera de las comillas.
- Si se desea se puede crear un alias enviando un comando del siguiente tipo CREATE ALIAS MI_ALIAS FOR "paquete.Clase.método" a la base de datos.
- Utilizar los mismos llamándolos con una de las siguiente opciones:
a. Utilizando CALL "paquete.Clase.método"(arg1, arg2 ... argN). O si se creo el alias CALL MI_ALIAS (arg1, arg2 ... argN).
b. Llamandolo desde un SELECT, igualmente tanto utilizando la ubicación completa de la función o utilizando el alias.
Veamos un ejemplo. Decía que necesitaba unas funciones para manejar fechas. Así que vamos a crear un método addDate y otro dateDiff. Lo primero que debemos observar la correspondencia de datos, para saber que recibir y devolver. De acuerdo a la documentación de HSQLDB el tipo de dato DATE de HSQL se corresponde con la clase "java.sql.Date" de java. Y el tipo de dato INTEGER | INT se corresponde con el tipo int de java.
Bien el método addDate debe recibir una fecha y el número de días que se va a agregar a esa fecha y debe devolver la fecha resultado de dicha operación.
Por otra parte el método dateDiff debe recibir dos fechas y devolver un int con la diferencia de dias entre ellos.Para ello utiliza solamente la parte Date e ignora la parte Time.
He aquí el código que he creado, colocado en un paquete llamado funcion. Estoy seguro que se podría optimizar para que sea mas eficiente. Y tal vez hay alguna corrección que hacer.
Package
funcion;
import
java.util.Calendar;
import
java.util.GregorianCalendar;
import
java.sql.Date;
public
class Fecha
{
public
static Date
addDate(Date date,
int days){
Calendar
calendar =
new GregorianCalendar();
calendar.setTimeInMillis(date.getTime());
calendar.add(Calendar.DATE,
days);
return
new
Date(calendar.getTimeInMillis());
}
public
static int
dateDiff(Date date1,
Date date2){
long
timeInMillis =
date1.getTime() -
date2.getTime();
long
days =
timeInMillis /
86400000; //1000 *
60 * 60 * 24
//No
se ha considerado el posible ajuste de un segundo
//por
año (¿es aumento o disminución?, ¿es
significativo?)
return
(int)days;
}
}
Listo, creamos el archivo .jar correspondiente, por ejemplo fhsqldb.jar (es decir, funciones de HSQL), lo colocamos en una ubicación adecuada y reiniciamos la BD, incluyendo el jar en el classpath (lo sé, lo sé, esto que para quién lo usa seguido es "pan comido" es el terror de los que recién se inician, a ver si este enlace les sirve).
Ahora ya podemos utilizar los métodos de la clase Fecha desde nuestra BD. Por ejemplo, suponiendo que tuvieramos una tabla llamada factura con un campo de tipo DATE llamado FAC_FECHA (la fecha de generación) y otro llamado de tipo INT llamado FAC_PLAZO (el plazo de tiempo para que el cliente pague la factura, digamos 1 día, 7 días, 30 días, etc.) y queremos obtener todas las facturas cuya fecha de pago ha vencido, podemos hacer un select del tipo (recuerden que lo que va entre paréntesis es case sensitive):
Select * From factura Where funcion.Fecha.addDate(FAC_FECHA, FAC_PLAZO) < CURDATE()
CURDATE() es una función ya incorporada que nos devuelve la fecha actual. Pero claro, esta sentencia no se ve nada bonita, de modo que vamos a crearle un alias que se llame ADDDATE. Para ello usamos el siguiente comando:
CREATE ALIAS ADDDATE FOR "funcion.Fecha.addDate"
Esta hecho, ahora podemos utilizar una sentencia más estándar (si alguna vez piensan cambiar de BD, esto es fundamental)
Select * From factura Where AddDate(FAC_FECHA, FAC_PLAZO) < CURDATE()
Que funciona exactamente igual que la anterior. He colocado el nombre de la función mezclando mayúscula y minúscula para demostrar que no es case sensitive.
Se podría especificar en el argumento date un String con el formato 'año-mes-día', o también 'año-mes-día hora:minuto:segundo' (es decir fecha hora) y lo procesaría sin problemas. Para el argumento days recibirá un entero que este dentro de su rango de valores.
Por otra parte se puede llamar la función con el comando Call (HSQL no acepta un Select que no llame a una tabla):
Call adddate('2004-05-12', 10)
Select adddate('2004-05-12', 10) -- esta última sentencia marcará un error.
Y nos devolverá:
'2004-05-22'
Y bueno, lo mismo para la función dateDiff. Se podría usar por ejemplo para saber el número de días que tiene un paciente internado en un hospital (digamos que se obtiene la diferencia entre la fecha actual y la fecha de internamiento). Eso se lo dejo para que hagan sus pruebas.
En síntesis, se puede utilizar como cualquier otra función de la ya dispone la BD. Y la verdad es que me dan ganas de incorporar esos métodos al código fuente. Tal vez le envié un correo a alguno de los desarrolladores de HSQLDB a ver si le sirve de algo.
En el ejemplo hemos visto basicamente como crear funciones, nos faltaría saber como manejar aspectos algo mas complejos que puede tener un procedimiento almacenado. Si es que puedo, posteriormente les daré algunos alcances al respecto.
Posted at 01:59PM May 12, 2004 by Ricardo in Java | Comentarios[5]
HSQL: IDENTITY
Bueno, me he pasado un par de horas en el foro de SourceForge (del proyecto HSQL), y parece que casi todas las preguntas que tenía en mente ya las han hecho antes (casi siempre me pasa). El único detalle es estar revisando dentro de los mensajes, algo que puede ser enriquecedor, pero también puede consumir mucho tiempo.
Lo primero que les cuento es que los procedimientos almacenados en HSQL no son tales, sino que son métodos estáticos de clases Java que son llamados desde la BD. Pero eso lo voy a dejar para después (para poder poner un ejemplito y todo). Ahora, quería explicar el punto de cambiar el valor de inicio de un campo IDENTITY.
No es una característica soportada en la actual versión 1.7.1. Sin embargo, Fred Toussi, en un mensaje del 2003-04-09 (es decir, hace bastante tiempo) indicó que implementaría esta característica en la siguiente release candidate. Es decir, seguro que en la 1.7.2 _RC ya esta implementada.
La forma de funcionar sería la siguiente (la misma que se utilizará para poder cambiar otras propiedades de la BD):
SET PROPERTY <propertyname> <propertyvalue>
Por ejemplo para poner el valor de inicio a 1, se utilizaría el siguiente comando:
SET PROPERTY hsqldb.first_identity 1
Un detalle con este cambio (y el de cualquier otra propiedad). Estos valores son leídos por la Base de Datos al iniciar, por lo cual no tendría efecto hasta la próxima vez que se inicie la BD.
Como ya lo indiqué anteriormente otra forma (que funciona también con la actual 1.7.1) es insertando el primer registro e indicando un valor para el campo autonumérico en el mismo (algo que no tiene mucho sentido, creo).
Posted at 02:31AM May 05, 2004 by Ricardo in Java | Comentarios[2]
HSQLDB
Sí, estoy probando este motor de BD.
Fue Al quién me indicó de su existencia, cuando yo andaba perdido por unos oscuros caminos pensando que lamentablemente no había una alternativa para Access para algunas aplicaciones de escritorio (y hay mas de una por supuesto ;-), pero como no puedo probar todas me decidí por HSQL). Access no me convencía (a pesar de que dentro de su categoría, como BD de escritorio, la considero una de las mejores) por las siguientes razones:
- Solo funciona en Windows. De modo que mis aplicaciones iban a quedar amarradas a ese SO.
- Parece no entenderse tan bien con Java. No es que existan problemas graves entre ellos, pero el hecho de usar un puente ODBC-JDBC no me agrada (consideren que además tiene que hacerse la conversión de ODBC al motor propio de Access).
- No tengo licencias para usarlo. Y aunque el usuario final no necesita tenerlo instalado para que funcione yo si lo necesito para desarrollar.
- Para utilizar Access a través de la red hay que compartir la carpeta correspondiente con permiso de escritura. Es decir, no se puede (que yo sepa) hacer que el motor de Access sirva los datos a través de un puerto utilizando TCP/IP.
- Muchas veces tiene problemas en el trabajo con multiples usuarios simultáneos (porque todos modifican un archivo temporal que guarda no sé que información).
- Cuando no se compacta, crece y se hace tan lenta como una tortuga. Hace unas semanas he visto un programa (Visual Basic con Access) funcionando en una PIV con 128 MB de memoria y se demoraba un siglo para hacer unas consultas relativamente sencillas. La BD pesaba más o menos 100MB. Como ya sabía de este problema, lo primero que hice fue compactar la BD y se redujo a 2MB. La velocidad ... quedó como siempre debería haber estado. Bueno, eso se puede prevenir haciendo que cada cierto tiempo se compacte la BD. Y creo que HSQL tiene un comportamiento parecido en este aspecto.
Vayamos por HSQL. Esta escrito totalmente en Java, por lo que es portable. Tiene un driver JDBC que incluso se puede usar de forma embebida dentro de la aplicación. Es software libre (Licencia BSD). Se puede operar de varios modos, que se pueden agrupar en enProceso (In-process) y Cliente-Servidor(Client/Server). En el primer caso solamente puede tener una conexión abierta (dentro de la misma máquina virtual), y en el segundo (que a su vez tiene varias alternativas) sirve los datos a través de un puerto (9001 de forma predeterminada) y admite n conexiones. También necesita compactarse para optimizar su rendimiento lo que se puede hacer al cerrar la BD, utilizando Shutdown Compact (en vez del simple Shutdown).
En en mismo archivo jar vienen algunas herramientas administrativas, una de las más utiles es el DatabaseManager hecha con AWT (la versión Swing no me funcionó). Mediante la cual se pueden enviar sentencias SQL al motor para modificar la BD o recuperar registros. Pero lo mejor, se puede enchufar cualquier otra herramienta administrativa que soporte utilizar drivers JDBC, como DbVisualizer, AquaData Studio, etc. Este dato se lo debo a Martín.
Hasta el momento, estoy satisfecho de como se ha portado este motor. Es rápido. Acepta una buena cantidad de sentencias SQL estándar, y esta perfecta para varias de mis necesidades. Entre algunas cosas interesantes, se puede escribir stored procedures utilizando como lenguaje java.
Todo lo dicho no quita que no tenga dificultades que sortear (como todo en la vida). He aquí algunas de las que me encontré hasta ahora:
- Existe la posibilidad de crear varios tipos de tablas: TEMP, MEMORY, CACHED y TEXT. El tipo predeterminado (cuando se usa un simple Create Table sin especificar tipo) es el MEMORY. Algo de lo que no me había percatado al principio. En este tipo de tablas, cada vez que se inicia la base de datos, toda la información es cargada en memoria. Cuando se realiza un cambio ya sea en la estructura o en el contenido se almacena una sentencia que la representa en el archivo bdatos.script, para poder utilizarlo en la próxima vez que se vuelva a iniciar la BD (pero no para consultar los mismos durante el funcionamiento). Por supuesto que si se va a usar tablas con un número alto de registros se puede sobrepasar el límite de memoria y traerse abajo la BD. Su ventaja es que esto le da rapidez. Para mis fines presentes, prefiero las tablas tipo CACHED (o quien sabe las TEXT).
- Las BD son case sensitivity, de forma predeterminada, para los campos de texto (comparación e indexación). Hay forma de cambiar esto mediante SET IGNORECASE{TRUE | FALSE}. Sin embargo, esto no afecta las tablas creadas y datos almacenados. Cuando se activa esta opción los campos VARCHAR son creados en realidad como VARCHAR_IGNORECASE, el cual es un tipo de dato especial para que las comparaciones se hagan sin tomar en cuenta si es mayúscula o minúscula. Lo bueno es que igualmente se pueden crear campos con este tipo de datos sin cambiar la opción en toda la BD, pudiendo coexistir en una tabla datos VARCHAR y VARCHAR_IGNORECASE. Una vez con este conocimiento esto representa una ventaja, por supuesto.
- Para crear campos autonuméricos se puede utilizar IDENTITY en la definición del campo. Lo cual lo hace automaticamente de tipo INT, autoincremental y clave primaria. Sin embargo, la numeración empieza en 0. Y yo estoy acostumbrado a que se inicie en 1. Hasta ahora no he encontrado forma de modificar este valor por defecto, a no ser que sea insertando un registro y poniéndole un valor al campo (pero esto es lo que quiero evitar).
- El conjunto de funciones para el manejo de datos es limitado. Por ejemplo estaba buscando funciones para el manejo de fechas. Los típicos DATEDIFF, ADDDATE(o DATE_ADD), o alguna otra forma de sumar o restar tiempo a una fecha. Y no, creo que no funcionan. Me fuí al Foro de SourceForge y leí que se pueden implementar las funciones en Java para luego utilizarlas de manera trasparente desde las sentencias SQL (pero por supuesto, pensé, ¿cómo no se me ocurrió antes?). Así que eso es lo que voy a intentar. Pero todavía no sé como hacerlo. Estoy suponiendo que es como crear cualquier otro procedimiento almacenado en otra BD, pero no estoy seguro. Si alguién ya lo hizo que me cuente y me ahorre algo de tiempo ;-). Sino, de todas maneras espero poder pasarles luego esa información.
Posted at 03:02AM May 03, 2004 by Ricardo in Java | Comentarios[6]
SWT: capturas de pantalla
Con motivo de uno de mis mensajes anteriores Vitxo ha solicitado capturas de pantalla para mirarle la cara a SWT.
No quice responder "solo con palabras" ante esta solicitud de "cosas visibles y concretas". Así que luego de darle una maquillada para esconder cualquier información que pudiera considerarse confidencial (vaya que esta tarea no es tan fácil como parece) he aquí la primera presentación de estos engendros. En realidad había pensado poner estas capturas de pantalla luego, junto con una descripción sucinta de los aplicativos y los resultados de las pruebas que pienso realizar ... pero he aquí un caramelillo de adelanto.
Como herramienta gráfica para seleccionar la parte de la imagen que quiero mostrar he usado gimp. Es la primera vez que lo uso (mas allá de abrirlo y mirarlo sin un objetivo concreto) y me a parecido interesante (para lo que necesitaba ha sido muy fácil de usar), aunque se extraña una documentación mejor lograda. En su misma página se puede leer (en la parte de sus propios screenshots):
"Everyone Loves Screenshots!"
Así que sin más preámbulos aquí va la primera:
Esta captura no requiere mayor explicación. Solo apuntar que la imagen de la llave la tomé de algún lugar de internet y espero no estar usurpando ningún derecho de autor :S.
Esta imagen nos muestra una clase que nos permite seleccionar un elemento de una lista (que tiene como origen una BD, pero se podría cambiar la clase para aceptar otros origenes de datos).
Puede crearse la lista con un filtro (en este caso 'CAT'), pasándole este parámetro al constructor, con lo cual solo se muestran los elementos que comienzan por ese conjunto de caracteres. Mientras se va escribiendo, el elemento seleccionado va cambiando posicionándose en el primer elemento que coincida con los caracteres escritos. Se puede utilizar la tecla abajo para posicionarse en la Lista y desplazarse por el mismo.Si se desea cambiar de filtro, se coloca los caracteres y se presiona el botón "Filtrar" y si se desean ver todos los elementos se presiona el botón "Todos". Con un 'Intro' (tanto si se esta en la caja de texto como en la lista) se selecciona el elemento "activo" y se cierra la ventana (al igual que un doble click del ratón o el botón "Aceptar"); si no hay ninguno se envía un mensaje solicitando escoger un elemento. Devuelve un String con el elemento seleccionado o si se presionó el botón Cancelar un String con referencia null.
Es una de las primeras cosas que hice con Java, y me atreví a enviarlo como código útil a javaHispano. Lamentablemente, estaba plagado de errores (de los cuales he corregido dos que eran imperdonables porque simplemente hacían colapsar la clase y con ella la aplicación) y la implementación de su código es terriblemente mala (en casi todo sentido, ¡que verguenza!). Pero funciona (algún día espero poder mejorarla y escribirla decentemente) y la uso por todos lados porque es muy práctica cuando se quiere permitir que un usuario seleccione un elemento de una lista. Si alguién la quiere, que la pida, con las siguientes advertencias:
- No me responsabilizo por daños y prejuicios.
- No lo tomen como ejemplo para programar en Java, SWT ni en nada.
- Esta prohibido reírse o hacer criticas destructivas ;-).
- Esta permitido cambiar la clase, usarla, venderla o botarla a la basura (licencia BSD).
- Si alguién la reconstruye totalmente que no se olvide de los compañeros ;-).
Bien, aquí se ve la pantalla principal de la aplicación con sus respectivo menú y una barra de herramientas que responde contextualmente, según lo que se tenga seleccionado en los botones que están mas a la derecha (donde se llega a distinguir que dice Orden, otro botón sin figura, otro de clientes que está actualmente presionado y finalmente Cotiz.). Estos botones cambian lo que se muestra al modo de los tabs (pero con otra presentación).
Sobre las figuras de la barra de herramientas, lo tomé de un archivo que indicaron en un foro de javaHispano cuando alguién preguntó donde podía conseguir íconos que hicieran que su aplicación se viera muy java ;-). Por ahí, me acabo de dar cuenta que algo he cambiado y uno de ellos aparece dos veces (el botón nuevo no es el que corresponde; bueno, ya esta puesto). Las figuras de los botones están cambiadas. Veamos la pantalla de Clientes. En la parte superior se tiene una serie de cajas de texto donde se colocan los filtros para obtener la lista de clientes que se esta buscando. En este caso se a filtrado con el criterio 'j' para el nombre y se han obtenido 3 resultados ... dentro de los cuales está javaHispano ;-).
Haciendo doble click sobre un nombre (o la opción correspondiente de la barra de herramientas) se muestra una pantalla donde se puede ver mas detalles de el cliente seleccionado y si se tiene permiso de escritura se pueden editar los datos. El color amarillo como fondo en la caja de texto indica que no es editable (en vez del típico plomo). La misma idea para la lista de contactos que aparece en la tabla.
Los datos contenidos en estas ventanas los saqué de la página de javaHispano, y espero a nadie le incomode (los consideré datos públicos), y si es así que por favor me avise. Lamentablemente no tengo mucho espacio y no pude poner a toda la gente de javaHispano, de modo que una solicitud de inclusión dificilmente será atendida 0:-).
Uso de colores:
Seguro que lo han notado, no me gustan mucho las ventanas completamente plomas. En mi cerebro todavía esta almacenado el recuerdo de cuando el mundo (informático) era gris. Por alguna razón las aplicaciones utilizaban este color (si se le puede llamar así) en exceso (para mi gusto), lo que contrasta fuertemente con el variopinto ciber-mundo (las páginas web tienden a tener variedad de colores).
La explicación que se le da a este hecho es que de esta forma no se cansa la vista; tal vez sea cierto pero a costa de ponernos en un estado de monotonía casi depresiva. Los colores están relacionados con las emociones, y si todo es siempre del mismo tono y para remate gris, ¿cómo nos sentiremos?.
Parece que algunos fabricantes de software están comenzando a entender esto. Sino miren como Windows se ha vuelto mas colorín que antes, por citar un ejemplo que la mayoría pueda corroborar.
Para evitar el efecto de cansancio que mencionaba antes, trato de no alejar mucho la cantidad de los 3 colores que componen el color final. Hasta hoy ningún usuario se ha quejado de cansancio visual (o ¿tal vez no se han dado cuenta?, ¿o no me lo han dicho?). Lo cierto es que a la mayoría le gusta que exista una variedad también en este aspecto y me lo dicen (aún después de mucho tiempo -meses o años- de usar los programas).
Algunos tips:
- Una de las cosas que me generaban dificultades al comenzar (tomen en cuenta que vengo del mundo Visual Basic) era el uso de layouts. Sin embargo, Cuando una ventana es redimensionable, el uso de los mismos puede convertirse en una bendición; que satisfacción da el ver que tu aplicación se ve presentable independientemente de la resolución del monitor (antes este era un problema para mi). Sin embargo, es mas trabajo posicionar los controles con layouts que hacerlo de forma absoluta. De modo que si en alguna parte no necesitan un posicionamiento dinámico, no usen layouts (por ejemplo en los cuadros de diálogo).
- No se olviden de liberar los recursos del sistema; este tipo de recursos no es liberado automaticamente por el garbage collector. Para ello existen una serie de reglas en SWT, las mismas que pueden revisarlas en este enlace. Yo prefiero NO poner esta tarea de limpieza en el método finalize() y mas bien en un método que yo mismo llamo al terminar la clase (o el evento que se produce al cerrar el Shell). ¿Por qué? pues porque el método finalize no necesariamente se ejecuta de inmediato, y más aún tal vez no se ejecute nunca si es que mi aplicación termina antes de que el garbage collector efectúe su tarea. Pero como hacerlo, ya depende de cada quien, por supuesto.
Lo que no he usado:
- JFace. A pesar de las opiniones de Martín sobre JFace aún no he aprendido a usarlo (le había hechado el ojo desde el principio, pero no sé muy bien porque ni lo he tocado) y mas bien me he creado algunas clases propias que hacen parte de los trabajos que necesito. Pero, ya le llegará la hora (cuando termine lo que estoy haciendo).
- Drag and Drop. Por ahora no lo he necesitado.
- Miles de cosas mas (algunas de las cuales ni siquiera sé que existen; lo que no sé es como sé que ni siquiera sé que existen jejejejeje).
Bueno, como dije esto es solo un pequeño adelanto, me hubiera gustado mostrarles muchas mas cosas que tengo por ahí (detalles que aquí no se notan), pero tendría que modificar un tanto la información que se muestra. Vamos a ver si les puedo hacer posteriormente :-).
Ahh, lo olvidaba. ¿Documentación? Justamente Martín ha puesto una serie de links en su weblog. Si no lo encuentran busquen un post del día 6 de Abril de 2004, se llama "¿Cómo empiezo con SWT y RCP?". No puedo entrar a ese enlace, por eso no les he puesto la liga.
Posted at 02:43AM Apr 19, 2004 by Ricardo in Java | Comentarios[6]
¿Eso es Java?
Hoy estaba probando una aplicación que estoy desarrollando en Java con SWT para ver que tal responde en una Pentium II (también conocidas como Lentium II), con unos 128 MB de RAM. Demora un poco en cargar (aproximadamente unos 11 segundos la primera vez y de 4 a 5 las subsiguientes veces) ... pero tampoco se puede pedir mucho. Luego, funciona "normal", los cuadros de diálogo y formularios cargan al instante. Extrae y graba los datos sin problemas (y sin demoras) en la BD MySQL. Sí, estoy complacido (ya les daré mas detalles sobre algunas pruebas "caseras" que pienso realizar en varios equipos con diferente clock de reloj y memoria).
Mientras me deleito contemplando el avance de mi obra, se acercan a mirar lo que hago algunas personas (incluyendo "la dueña" de la máquina) ... parece que esta causando buena impresión (me refiero al programa ;-))... dentro de los observadores esta un joven estudiante de alguna carrera relacionada con sistemas, quién me pregunta "¿con qué lo has hecho?". La respuesta no puede ser otra: "con Java"; él "¿con Javaaaa?" (tiempo ... tiempo ... tiempo ... no sale de su asombro), "¿con Javaaaa?", vuelve a repetir (y mira con atención el programa), luego continúa "pensé que estaba hecho con Visual Basic"; yo "¿por qué?"; él "no sé, parece Visual Basic ... como el otro programa que hiciste" (se refiere a un programa que escribí hace más de un año y que efectivamente esta hecho en Visual Basic); "... se ven casi igual ..." concluye. Aún no lo puede creer ... lanza algunas frases que dan a entender algo así como "esto no puede ser Java".
Ha despertado su curiosidad y me hace muchas preguntas, una de las que parece tener mayor importancia es si se tiene un diseñador de interfaces de usuario con Java (pues dice que hacer esto con código lo confunde). Le explico que en Java no es como en VB donde no hay distinción entre el IDE y el lenguaje, sino que se dispone de muchas IDEs algunas de las cuales tienen lo que me esta preguntando, pero le advierto de la posibilidad de elegir también entre Swing y SWT; "en lo particular uso Eclipse como IDE" le comento, agregando así mismo que para Eclipse existen plugins para diferentes cosas, incluyendo algunos para manejar los widgets de SWT con el ratón. Me dice si los he utilizado y le digo que no, que todo lo hice "a mano", y que lo hice así para aprender.
Esta muy interesado y me pide que le de direcciones de internet donde buscar mas información. Claro, le he enviado una lista de sitios a su correo electrónico dentro de los cuales por supuesto esta javaHispano ;-). Si es persistente y le gusta investigar tal vez no tarde mucho en llegar hasta aquí ... si alguien les pregunta quién escribió esto ... yo no sé nada :| ... quién habrá podido dejar semejante mensaje en mi weblog ... jajajaja
Posted at 07:30PM Mar 29, 2004 by Ricardo in Java | Comentarios[3]
Oracle 9i: Java Programming
Me refiero a la Guía de Estudiante que llegó a mis manos hace poco (como lo comenté en otro post) y que ha sido elaborada por la Oracle University y tiene como fecha de edición Junio de 2003. Son dos volúmenes medio gorditos para este primer tema (no sé cuantas páginas tienen porque utiliza la numeración capítulo-hoja, dicho sea de paso no me siento tan cómodo con la misma).
Se ponen como pre-requisitos para comprender el contenido el tener experiencia previa con otro lenguaje de 3ra. generación, de preferencia un lenguaje estructurado como Pascal o C. Y como algo sugerido estar familiarizado con HTML básico y SQL.
El contenido esta presentado en una serie de cuadros tipo diapositivas a razón de casi una por hoja, donde se presenta el resumen de lo que en la parte baja de cada página puede estar explicado más detalladamente. Esta estructuración me parece interesante porque se puede leer rapidamente lo más resaltante y luego ampliar con una lectura más profunda. Y si se desea luego se regresa al resumen para organizar los conceptos.
Cada capítulo presenta inicialmente la lista de objetivos, luego desarrolla cada punto, seguido de un sumario y generalmente finaliza con unas sección de práctica.
Veamos el contenido. Se inicia desde lo más básico ¿Qué es Java? indicando que se trata de una plataforma y un lenguaje orientado a objetos, que contiene una librería de clases y usa una máquina virtual para su ejecución. Se presentan una serie de precisiones sobre conceptos necesarios para entender como funciona java, con algunas gráficos (no voy a reproducir ninguno -de muestra- porque tienen un pie de página con copyright), por ejemplo hay uno donde se ve como una aplicación java funciona sobre la java virtual machine (JVM) y esta sobre el sistema operativo; en el caso de los applets, estos corren en la JVM la cual se ejecuta en el browser y este sobre el sistema operativo.
A lo largo de los capítulos se presentan de manera bastante ordenada y sintética los conceptos de orientación a objetos, las convenciones de codificación, los tipos de dato primitivos, el control de flujo, las clases, la herencia, el uso de Strings, los Arrays y colecciones, etc. Es decir, la base conceptual y la estructura del lenguaje en sí.
En diferentes partes se muestra como encajan los productos de Oracle dentro de lo que se va explicando (no podía ser de otra manera). Entre los productos más importantes están: Oracle9i Database, Oracle9i Application Server y Oracle9i Developer Suite (Oracle9iDS). Así mismo se indica que actualmente el JDeveloper (el IDE) se puede obtener como un producto separado del Oracle9iDS. (Lo estaba olvidando, se menciona que el JDeveloper a sido re-escrito y ahora esta hecho totalmente en Java).
Puedo decir que para mi gusto esta bastante bien explicado, aunque lo cierto es que no puedo juzgar que tan didáctico sería para alguien que no tiene ningún conocimiento de Java (pero sospecho que le haría bien tener simultaneamente a la mano por lo menos otro libro o manual).
Posted at 03:38AM Feb 16, 2004 by Ricardo in Java | Comentarios[0]
Swing incrustado en SWT:II
(Comunicación entre los controles)
Posiblemente algunos habrán tomado el ejemplo mostrado en el post anterior e intentado agregar un escuchador de eventos al JButton, lo que se logra importando las clases necesarias:
import java.awt.event.*;
Y luego agregando el escuchador de eventos al control:
boton.addActionListener ... etc.
Si lo probaron con código que no accediera a ningún widgets de SWT seguramente les funcionó de maravillas, pero si intentaron modificar alguna propiedad o usar un método de un control SWT la JVM les lanzó la excepción:
org.eclipse.swt.SWTException: Invalid thread access
Y es que para poder acceder desde un control Swing a uno SWT hay que agregarle unas cuantas líneas de código que permitan que el mismo pueda ver el display. Para cerrar el Shell desde el botón, sería algo como esto:
boton.addActionListener(new ActionListener () {
public void actionPerformed (ActionEvent event) {
display.syncExec (new Runnable () {
public void run () {
shell.close();
}
});
}
});
¿Y acceder a un control Swing desde SWT? Todavía no lo he investigado (será que no lo necesito aún), pero si no hay algo que me distraiga tal vez (y solo tal vez) lo pongo en el siguiente post.
Para concluir, os dejo (ya estoy escribiendo como español) un enlace hacia un ejemplo de Veronika Irvine, donde pueden varias cosas interesantes. Acuerdense que para acceder han de estar inscritos en la lista de correo para que les den un usuario y contraseña. Y no esta de mas volver a advertir que se trata de una tecnología experimental, con varios peros que la misma Veronika Irvine menciona en su respuesta.
Posted at 02:57PM Jan 18, 2004 by Ricardo in Java | Comentarios[0]
Swing incrustado en SWT
Estaba leyendo en la página de Eclipse las características que piensan implementarse (mejor dicho que ya se están implementando) para la versión 3.0. La primera de ellas es la capacidad de incrustar controles Swing/AWT dentro de widgets SWT. Es cierto que esto ya es posible con la versión 2.0 (y posiblemente anteriores), pero solo para Windows. Pueden visitar el enlace anterior donde hay un screen shot y una liga a un snippet con código para realizar esa tarea.
Y para aquellos que quieran probar como hacer esto con la versión vigente y todavía no saben como hacerlo he aquí un pedacito de código que muestra como poner un JButton en un Shell. Eso sí, anden con cuidado, pues parece que con algunas versiones de la JRE de Sun pueden fallar algunas opciones (según estuve leyendo en la lista de correo).
import java.awt.Panel;
import javax.swing.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.internal.awt.win32.*;
public class Calendario {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
Panel p = SWT_AWT.new_Panel(shell);
JButton boton = new JButton();
boton.setText("Hola");
p.add(boton);
shell.setBounds(50, 50, 228, 244);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
}
¿Y es posible incrustar SWT dentro de Swing? Sí, pero eso requiere otro apartado (no lo he probado, ni estoy completamente seguro como es que se hace).
Posted at 02:34AM Jan 18, 2004 by Ricardo in Java | Comentarios[0]
Widgets ausentes en SWT
No es un secreto que SWT es mi sistema preferido para elaborar interfaces de usuario con java; como tampoco lo es que, por otra parte, Swing me parece la forma más flexible de hacerlo, y muy probablemente con el tiempo termine usandolo de forma predominante (eso va a depender de la velocidad usual de los equipos).
Como toda creación humana SWT no esta libre de problemas y carencias. A mi gusto personal he encontrado las siguientes (hasta ahora):
PRIMERO
La ausencia de un control tipo Date picker, que muestre un calendario visual para seleccionar las fechas.
Es cierto que en la newslists de Eclipse se puede encontrar el código de dos clases que cumplen esta función: la primera de ellas no la he podido probar porque requiere el uso de unas librerías que no conozco y que probalmente sean propias del autor (Kosta).
La segunda y cuyo autor es David Ryan se ve lo suficientemente buena para lo que busco. No será un JCalendar pero funciona casi bien (el casi lo explico a continuación). El código que puedan encontrar en el enlace anterior buscará unas imagenes que obviamente no están ahí. De modo que para que no lance una excepción hay que ponerle imagenes con los nombres correspondientes o de lo contrario cambiar las referencias. Las imagenes originales se encuentran, según información del propio autor en http://sourceforge.net/projects/eclipsecolorer (si se las bajan avisen a los compañeros). Tiene además un inconveniente, que no muestra la última línea de dias del calendario (aunque por el desplazamiento del cursor se nota que esta ahí). Habrá que hacerle una revisión en la forma de posicionar esos controles (si alguien se anima primero, estaré de acuerdo :-D).
EL SEGUNDO
La ausencia de un control Spinner para aumentar-disminuir un valor (generalmente numérico) haciendo click en la flecha-arriba o flecha-abajo. Tal vez en algunos casos se pueda reemplazar con el control Scale. Si utilizamos la opción buscar de Eclipse, encontramos el código (en C) para crear controles spinner para Windows, Motif y tal vez otros más. No, no lo he probado; sencillamente porque imagino que para que funcione habría que instalar esos controles en la máquina de cada usuario ... no sé, no me atrevo todavía, tal vez si lo hacen algo oficial del proyecto Eclipse, pueda aceptar una solución que no es puro java (bueno, como ya lo estoy aceptando con SWT).
TERCERO
La imposibilidad de extender la clase Text. No es gran cosa, pero me ahorraría mucho trabajo si es que pudiera agregarle alguna funcionalidad a este widget.
Si alguien conoce alguna forma de resolver estos inconvenientes, no me opongo a que lo comunique :-D. O, tal vez hasta ya se encuentre en las últimas versiones de SWT ... lo admito, no me he actualizado.
Nota.- Para acceder a las newslists has de registrarte, luego te envían un usuario y contraseña. Esto es para evitar los mensajes masivos.
Posted at 04:42AM Nov 27, 2003 by Ricardo in Java | Comentarios[0]
Moviendo los mensajes de Certificación
Pues eso, que ahora los mensajes referentes a certificación van a estar en su propio bloque para poder mantener el orden. Una especie de mini-refactorización ... lo sé, lo sé, una de las mayores urgencias es el cambio en la capa de presentación ... tal vez unas fotos ... algo para darle mas vida ... no sé ... a mi tampoco me gusta tal como está. Vamos a ver si el fin de semana da para algo de eso.
Posted at 03:18AM Nov 27, 2003 by Ricardo in Java | Comentarios[0]