Cómo personalizar aplicaciones desktop utilizando Java Synth

Java Synth es un componente dentro del conjunto de herramientas de Swing, que se caracteriza por brindar una interfaz configurable y más agradable como experiencia para al usuario ya que permite personalizar el look and feel estándar de Java por uno creado mediante Synth.

 Synth está disponible a partir de la versión J2SE 5.0  y posee la cualidad de configurarse a través de un archivo xml, en el cual se definen los estilos que va a contener los elementos que conforman la aplicación.

Ejemplo de configuración de xml:

<pre><!—Aqui le aplicamos el estilo creado a un textfiled -->

Una vez creado el archivo xml que contiene los estilos de Synth, debemos cargarlo al contexto de la aplicación a través del método load de la clase SynthLookAndFeel, como se demuestra a continuación.

SynthLookAndFeel lookAndFeel = new SynthLookAndFeel();

lookAndFeel.load(new File("synthExample.xml").toURL());

UIManager.setLookAndFeel(lookAndFeel);

Algo que debemos tener en cuenta es que Synth no proporciona un estilo por defecto, y los componentes que no se encuentren definidos en nuestro archivo xml, synth no le aplica ningún estilo.  De todas formas se puede tener una parte de la aplicación con un estilo por defecto y otra con un estilo configurable mediante Synth. Esto se debe a que Synth permite asignarle un estilo en particular a un componente mediante su nombre pero a la vez también permite asignarle un estilo a un conjunto de componentes del mismo tipo a través de herencia de estilos (similar a como lo aplicaríamos en CSS). La manera de aplicar un estilo en herencia a través de Synth es creando un estilo y asociándolo al nombre de la clase que identifica al elemento. Por ejemplo, podemos tener un estilo para un elemento, combo box en particular o tener un estilo generalizado para todos los combo box de la aplicación. Ejemplo:

<!—Estilo de un combo box -->
<!—Aquí le aplicamos el estilo creado a todos los combo box de la aplicación, por herencia de estilos-->

Ventajas y desventajas de Synth

Una ventaja que propone Synth al igual que CSS es que a través de la herencia de estilos, como dijimos anteriormente, uno puede definir un estilo y aplicarlo a todos los componentes de la aplicación, de esta manera nos permite ahorrar código. Otra ventaja de los estilos creados mediante Synth, es que los estilos se comportan igual en distintas plataformas.

Hablando de puntos negativos que pudimos percibir, podemos decir que no hay demasiada documentación o experiencias de uso en la web, además de la proporcionada por Oracle en su página referido a Java Synth.

Otro desventaja puede ser que si solamente se trabaja con un solo archivo xml de configuración, este mismo puede crecer exponencialmente, contribuyendo a que se torne poco comprensible e inmantenible.


Creando widgets reusables en AngularJs

¿Qué es una directiva? Las directivas de Angular son componentes muy poderosos. Tienen la capacidad de controlar cómo se renderiza la página en muchas maneras diferentes, muchos de los tags y atributos que vienen incluidos con Angular son directivas. Una de las maneras en que podemos usarlas es creando widgets HTML. Éstos van a tener un propósito específico y también debemos intentar que sean los más independientes posibles para que de esta forma, con tan solo consumir algunos parámetros logramos tener un componente independiente, testeable y reusable.

¿Cómo se escribe y cómo se usa una directiva?


app.directive('domManipulation', function () {

return {

link: function ($scope, element, attrs) {

element.bind('click', function () {

element.html('Click detected!');

});

element.bind('mouseenter', function () {

element.css('background-color', 'orange');

});

element.bind('mouseleave', function () {

element.css('background-color', 'white');

});

}

};

});

Por medio de “directive” le definimos una directiva a nuestra aplicación. Directive soporta la siguiente lista de opciones:

-Restrict: determina si la directiva se puede usar por medio de un elemento “E”, un atributo “A”, una clase de CSS “C” o como comentario “M”.

-Scope: utilizar el scope padre o utilizar un nuevo scope.

-Template: define el contenido que tendrá como salida la directiva, puede ser HTML, expresiones u otra directiva.

-TemplateUrl: ubicación al template HTML.

-Controller: para definir un controller que estaría asociado a la directiva.

-Link: función utilizada para las manipulaciones de DOM y que tiene acceso a un scope a diferencia de compile.

-Replace: si queremos o no reemplazar el HTML que invoca nuestra directiva.

En el ejemplo anterior por medio de “link” estamos haciendo que el DOM cambie.

¿Cómo usamos la directiva?

</pre>
<div>Click! aca!</div>
<pre>

Eso es todo cuando el mouse pase por nuestro tag, nuestro componente actuará como lo definimos en la directiva. Para más detalles sobre las directivas se puede consultar la documentación oficial de Angular. Widgets reusables Ya vimos cómo es una directiva, las opciones que soporta y cómo usarla pero ahora veamos un ejemplo un poco más útil de lo que significa un widget reusable: Un ejemplo puede ser un form, ya que es algo que utilizamos muy seguido en una aplicación web y suele llevar a mucha repetición de código. Ahora, ¿qué tal si tuviéramos un widget que sea reutilizable, testeable y que sea simple?, de esta manera usando una única porción de HMTL podríamos resolver todos los forms de la aplicación.


mainModule.directive('myFormDirective', function () {

return {

restrict: 'EC',

templateUrl: '/someUrlToTemplate/form.html',

scope: {

formItems: '='

}

};

});

En este caso tenemos nuestra directiva definida con un sub scope (isolated scope), esto es importante para lograr que el widget sea independiente y no esté acoplado a nada, algo clave para lograr la reutilización. Definimos la variable “formItems” con el símbolo “=”, para lograr el bindeo, la cual creará un array de elementos. Estos serán nuestros campos definidos, que definiremos donde sea que lo utilicemos. El template de la directiva será:

</pre>
<div>
<div><input type="text" data-ng-model="formItem.content" />

<input type="number" data-ng-model="formItem.content" />

<input type="checkbox" data-ng-model="formItem.content" />
<select class="formItem.selectedClass" data-ng-model="formItem.content"></select></div>
<div></div>
</div>
<pre>

Como pueden ver iteramos por los elementos de “formItems” y dependiendo cada caso rederizamos. Por último para utilizar esta directiva solo tenemos que hacer lo siguiente:

</pre>
<div class="”my-form-directive”"></div>
<pre>

En este caso someController es nuestro controlador, cuyo scope contiene los elementos y esos elementos tendrán un formato como cualquier array JSON.


var elements = [{type: ‘text’, selectedClass: ‘someClass’, content: {}}];

En conclusión, en cada controller solo definimos los elementos que queremos tener en nuestro form y con una sola línea de HTML estaremos generando el form y reutilizando el único template. Esto hace que sea fácil de testear y en caso de que lo modifiquemos será igual en todos lados.

Esten atentos, proximamente estaremos mostrando cómo podemos testear estos widgets reusables.


Lenguaje ATL (Atlas Transformation Language)

La transformación desde un modelo a otro es un aspecto importante en el desarrollo de software orientado a modelos y ATL, un lenguaje de programación para realizar transformaciones entre modelos impulsado por Eclipse, brinda una serie de herramientas para estas transformaciones.

 Para llevar a cabo transformaciones con ATL, los desarrolladores tienen que mezclar la programación imperativa con la programación declarativa, ya que ATL es un híbrido entre estas dos programaciones. La programación declarativa pretende describir el problema al cual se quiere dar solución declarando un conjunto de condiciones, proposiciones o afirmaciones, y a través de mecanismos internos llegar a las instrucciones necesarias para dar la solución del problema. A diferencia de la programación declarativa, la programación imperativa brinda una serie de instrucciones o pasos que indican al computador cómo debe realizar una tarea.

 Un programa de transformación ATL se compone de reglas que definen cómo el modelo de elementos fuente se empareja para crear e inicializar los elementos de los modelos destino. Además de las transformaciones de modelos básicos, ATL define un modelo adicional que permite especificar las peticiones en los modelos.

 ATL ofrece a los desarrolladores la posibilidad de diseñar mediante tres tipos de unidades diferentes. Módulo ATL, consulta ATL y Biblioteca ATL; cualquiera de estas unidades se define en su propio archivo ATL. Los archivos ATL se caracterizan por tener la extensión .atl.

Families to Persons es un ejemplo básico de ATL algo así como un “Hola mundo”. Consiste en transformar cada uno de los miembros de una familia a persona.

Para este ejemplo el archivo .atl contiene lo siguiente:

</pre>
module Familia2Personas; --Nombre del archivo o modulo

create OUT : Persona from IN : Familias; --Metamodelo de salida (out) y de entrada(in)
<h5>

Este es el encabezado del documento donde se define el nombre y los metamodelos de entrada y salida. Los caracteres “–“ Sirven para poner los comentarios, son equivalentes a “//” en java.


helper context Familias!Miembro def: Apellido : String =

if not self.Padre.oclIsUndefined() then

self.Padre.Apellido

else

if not self.Madre.oclIsUndefined() then

self.Madre.Apellido

else

if not self.Hijos.oclIsUndefined() then

self.Hijos.Apellido

else

self.Hijas.Apellido

endif

endif

endif;</pre>
<h5></h5>
<pre>
helper context Familias!Miembro def: esMujer() : Boolean =

  if not self.Madre.oclIsUndefined() then

        true

  else

        if not self.Hijas.oclIsUndefined() then

              true

        else

              false

        endif

  endif;</pre>
<h5>

Estos son los helpers que se necesitan para realizar las transformaciones. Los helpers se componen de la palabra helper, seguido de context,  que puede ser opcional y es donde se define el contexto del helper,  def:, es acá donde se le da el nombre al helper, este nombre debe ser único ya que a través de este se realiza el llamado a los helpers. Después del el nombre del helper se debe especificar el tipo del helper, String, Boolean, etc. Y por último el cuerpo del helper. Los anteriores helpers sirven para identificar el Apellido de un miembro y saber si es mujer u hombre.


rule Miembro2Hombre {

from

s : Familias!Miembro (not s.esMujer())

to

t : Persona!Hombre (

Nombre_Completo <- s.Nombre + ' ' + s.Apellido

)

}</pre>
<h5></h5>
<pre>
rule Miembro2Mujer {

  from

        s : Familias!Miembro (s.esMujer())

  to

        t : Persona!Mujer (

              Nombre_Completo <- s.Nombre + ' ' + s.Apellido

        )

}</pre>
<h5>

Por último se encuentran las reglas de transformación, estas están compuestas por la palabra rule seguida del nombre de la regla. El cuerpo de toda regla se conforma por cuatro partes, dos de las cuales son opcionales. La primera parte se conoce como el origen de la transformación se denota con la palabra from y es acá donde se declara la variable del metamodelo origen, en nuestro primer ejemplo se define la variable “s” como un objeto de tipo Familias!Miembro y con los paréntesis del frente se determina cuando se debe hacer esta transformación, para este caso la primera transformación se debe realizar siempre y cuando el objeto “s” no sea mujer.

 La segunda parte del Helper se conoce como el sitio de declaración de variables locales, se denota con la palabra using, esta sección es opcional y es donde se declaran e inicializan las variables que se van a utilizar para poder llevar acabo la transformación. En este caso de uso no se requiere de una sección using, para llevar acabo las transformaciones.

La tercera parte se conoce como el destino de la transformación y se denota con la palabra to. Acá es donde se define el objeto destino de la transformación y dentro de los paréntesis se asigna valor a cada uno de los componentes del objeto destino. En las reglas de transformación ejemplo se puede ver como al componente Nombre_Completo se le asigna el valor del nombre de “s” más un espacio y el apellido de “s”.

La cuarta y última parte se conoce como el bloque imperativo de la transformación. En este parte es permite establecer instrucciones de tipo imperativo que serán ejecutadas una vez que el modelo destino sea inicializado. Esta sección se denota con la palabra do e igual que la sección using es opcional.


Introducción a AutoHotKey: primeros pasos

Todos nos encontramos con problemas recurrentes que, por más burdos que sean, consumen nuestro tiempo. Muchos eligen repetir las tareas agobiantes una y otra vez, otros deciden crear su propia solución. Quizás nos encontramos con un problema particular a nuestro deber que nunca nadie ha tenido, y nos toca ser los primeros en resolverlo. Por suerte, contamos con innumerables herramientas que nos permiten simplificar situaciones cotidianas y ahorrar tiempo y esfuerzo. Hoy me gustaría contarles un poco acerca de AutoHotKey, una herramienta que no se destaca por su poder, sino por su versatilidad y flexibilidad, y que puede ser aprovechada por cualquier usuario ya sea novato o experto en el área de informática.

¿Qué es AutoHotKey?

AutoHotKey es un lenguaje de scripting y macros que permite automatizar de manera sencilla y en poco código tareas repetitivas (y no tan repetitivas), además nos permite crear ventanas, formularios personalizados, enviar clicks y eventos, etc. La belleza de AutoHotKey recae en que cada usuario de Windows sea capaz de detectar sus experiencias diarias (¡buenas o malas!) y plantearse una solución adecuada y personal.

¿Cómo funciona?

Luego de descargar AHK, hacemos click derecho en el escritorio, y seleccionamos

Nuevo­> AHK Script.

La sintaxis es extremadamente sencilla, solo hay que aprender como AHK interpreta nuestro teclado, algunas de las hotkeys más comunes son Alt (!) , Windows (#), Shift (+), etc.

Ejemplos prácticos y sus respectivos scripts:

Ver ipconfig sin abrir CMD manualmente (en este caso el bind es windows + I) :


#i::run, %comspec% /k ipconfig /all, , max

Escribir expresiones lambda de manera más cómoda e intuitiva:


!Right:: Send {=}{>}

!Left:: Send {<}{=}

De esta manera, al presionar Alt + derecha/izquierda obtenemos la expresión lambda deseada. Si bien Visual Studio, Eclipse y otros IDEs tienen funcionalidades similares (snippets), estas son propias del IDE y no se comparten entre diferentes entornos. Con AHK, tenemos la ventaja de poder poner un “estándar” en nuestra manera de escribir o programar. Sobra decir, los scripts se habilitan/inhabilitan con un click.

También podemos reemplazar acrónimos o términos que usamos a diario, o crear nuestros propios con el siguiente formato ‘ ::x:: y ‘ donde ‘x’ es el atajo e ‘y’ es la expansión que deseamos, por ejemplo:


::bdt:: Buenos días a todos!

Consigue escribir “Buenos días a todos” si escribimos btd seguido de un espacio o coma:

Como es de esperarse, la complejidad del script aumenta proporcionalmente al problema que queremos resolver. ¡Me gustaría que comenten una situación recurrente y una posible solución en AHK!