Noticias Weblogs Foros Wiki Código

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Sponsors

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin

Fetishcode...Thinking in objects

Oracle JDeveloper 11g Handbook

Octubre 30th, 2009 - [Enlace local]

A

» Leer más, comentarios, etc...

Fetishcode...Thinking in objects

Manejando el WebLogic integrado de JDeveloper.

Octubre 30th, 2009 - [Enlace local]

A

» Leer más, comentarios, etc...

Ingenieria de Software / Software Engineering

Project y Project Server 2010

Octubre 30th, 2009 - [Enlace local]

En definitiva el brinco que se esta dando de versión 2007 a versión 2010 es grandioso, señalo 4 grandes características:

y muchas mas

Link de Referencia 1

Link de Referencia 2

» Leer más, comentarios, etc...

Arragonán

Cierra la puerta

Octubre 30th, 2009 - [Enlace local]

By dream sister :)

» Leer más, comentarios, etc...

Variable not found

Variable not found en Facebook

Octubre 29th, 2009 - [Enlace local]

Antes se solía decir que si no estabas en Internet, no existías; ahora que todo el mundo está en Internet, parece ser que si no estás en las redes sociales no existes. Cosas de la evolución, supongo ;-)

Y aunque no soy muy amigo de este tipo de afirmaciones, por si acaso, en un auténtico alarde de socialización, he creado el sitio Variable not found en Facebook, que pongo a vuestra disposición para mantenernos en contacto de una forma algo más bidireccional de lo acostumbrado:

Variable not found en Facebook

Espero que nos veamos también por allí. Y sobre todo, que incrementemos el triste número de fans que tiene hasta el momento… :-DDD

Publicado en: Variable not found.



» Leer más, comentarios, etc...

Variable not found

Modifica el portapapeles de tus visitantes con ZeroClipboard

Octubre 28th, 2009 - [Enlace local]

Si estás creando herramientas webs que generan código o texto para que tus visitantes lo copien y peguen en otras aplicaciones, ZeroClipboard puede facilitar su utilización, al permitir introducir el contenido que deseemos en el portapapeles de los usuarios.

image Hace tiempo ya comenté una forma de acceder transparentemente al portapapeles de los visitantes utilizando el objeto window.clipboardData, pero esta posibilidad desapareció, al menos en su versión silenciosa, conforme los navegadores fueron tomándose más en serio los temas de seguridad. A día de hoy, si intentamos utilizar estas funciones desde Explorer, aparece un cuadro de diálogo de confirmación algo molesto, para alertar al usuario de que el script de una página está intentando acceder a dicha información.

ZeroClipboard es una pequeña librería javascript que utiliza una película flash para acceder al portapapeles en modo “escritura”, es decir, para introducir en él un valor generado desde un script como respuesta a una acción del usuario como la pulsación de un botón o enlace. Podéis verlo en acción en esta demo online.

El siguiente código muestra cómo podemos utilizarlo. Creamos un <textarea> cuyo evento onchange aprovechamos para ir almacenando el contenido que pasará al portapapeles cuando el usuario pulse el enlace (btnCopiar) al que hemos vinculado este comportamiento:

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<title>Prueba de ZeroClipboard</title>

<script type="text/javascript" src="ZeroClipboard.js"></script>

</head>

<body>

<textarea id="texto" rows="10" cols="10"

onchange
="clip.setText(this.value);"></textarea>

<br />

<a id="btnCopiar" href="#">Copiar</a>

</body>

<script type="text/javascript">

clip
= new ZeroClipboard.Client();

clip.glue(
'btnCopiar');

</script>

</html>

Si lo probáis, podréis ver que en ningún momento se alerta al usuario de que su portapapeles va a ser modificado, quedando muy limpio y profesional. :-)

Publicado en: Variable not found.



» Leer más, comentarios, etc...

MonoCaffe

Xbox Live Bridge

Octubre 28th, 2009 - [Enlace local]

El siguiente es un sencillo script para crear un bridge y poder conectar una Xbox utilizando la wifi de un portátil. Si tienes la WiFi de la Xbox esto no hace falta.



Lo que hace es crear un bridge utilizando IPTables que enruta el tráfico entre las dos interfaces. Solo hay que cambiar en el script el nombre de las interfaces de red.



Descargad

» Leer más, comentarios, etc...

MonoCaffe

Monocaffe Connections Manager 0.3

Octubre 28th, 2009 - [Enlace local]

He terminado la versión 0.3 de MCM. Si tenemos "dialog" instalado, al ejecutar sin ningún argumento, nos mostrará un menú con los servidores y con pulsar ENTER sobre alguno, abrirá la conexión. También he cambiado el fichero .mcm donde se guardan los datos de las conexiones para utilizar XML y eliminar un pequeño bug que había. También he añadido conexiones FTP.



Podéis descargarlo desde aqui



This software is designed to ease the management of connections to several types of servers. Since I couldn't find any solution to handle all types of connections from a console, mcm was born. The idea is to avoid having to maintain a separate spreadsheet or wiki page with all the servers I usually connect to and keep that monster open during my work sessions.

There are other solutions, but each handled either ssh only connections, or graphical connections (like vnc). Also, this graphical connections managers were designed to have a GUI and a single command from the console is what I wanted.

My main objective is to provide a fast and reliable mean to store the information of this connections and be able to reach them fast and easily.



Click here to download version 0.3



Screenshot!



» Leer más, comentarios, etc...

Picando Código

Disponible SeaMonkey 2.0

Octubre 28th, 2009 - [Enlace local]

SeaMonkey

SeaMonkey

Siguiendo con las noticias de navegadores web, se anunció la disponibilidad de SeaMonkey 2.0. El proyecto SeaMonkey es la continuación de lo que fue la Suite de aplicaciones Mozilla, y basado en el mismo código fuente. Un navegador más de la familia Mozilla, y que mantiene esa esencia que nos recuerda a épocas más sencillas…

Esta versión trae muchos cambios respecto a la anterior, algunas ya fueron comentadas tras probar SeaMonkey 2.0 Alfa 3. Listo a continuación algunas nuevas características:

SeaMonkey 2.0

SeaMonkey 2.0

Pueden descargar SeaMonkey para sistemas Windows, Mac OS y GNU/Linux (en arquitectura de 32 bits). Como tengo Debian en arquitectura AMD 64, descargué el tarball con el código fuente y pude compilarlo sin mayores complicaciones. Una vez extraído el tarball, desde la consola ejecuté en el directorio extraído el siguiente comando:

./configure –enable-application=suite

No tuve problemas de dependencias. Probablemente gracias a que había compilado GNU IceCat recientemente, pero pueden sacar las dependencias por los errores que salten en el configure. Después de esto, ejecuté el comando make. Esto demora un rato… recuerden que estamos compilando todo una suite de aplicaciones, así que sean pacientes. Terminado make, con permisos de administrador ejecuté make install, y SeaMonkey se instaló en /usr/local/lib/seamonkey-2.0.

SeaMonkey 2.0

SeaMonkey 2.0

Actualmente tengo instalados los siguientes navegadores en mi computadora:
Iceweasel, IceCat, Arora, Google Chrome, Chromium, SeaMonkey, Midori, Opera y Konqueror. Nada de fanático… ¿Ustedes qué navegadores tienen en sus PCs?

» Leer más, comentarios, etc...

Picando Código

Repositorios de GNU IceCat para Ubuntu, Debian y gNewSense

Octubre 28th, 2009 - [Enlace local]

GNU IceCat

GNU IceCat

Giuseppe Scrivano, desarrollador principal de GNU IceCat, publicó en Identi.ca un enlace al repositorio de Launchpad: GNUzilla Icecat para Ubuntu. GNU IceCat es una versión de Mozilla Firefox distribuída por el proyecto GNU. Se desarrolla a la par de Firefox, con la única diferencia de ser totalmente libre, y agregar algunas características de seguridad al navegador.

En el repositorio pueden encontrar los paquetes oficiales de IceCat para Ubuntu en las arquitecturas i386, AMD64 y LPIA (nueva arquitectura de Ubuntu Mobile). Seguramente haya que agradecer este repositorio a la comunidad de gNewSense, la distribución totalmente libre basada en Ubuntu.

Vengo usando IceCat en Debian AMD 64 desde hace un tiempo. No había encontrado paquetes .deb hasta ahora, por lo que compilaba cada nueva versión de IceCat a mano. Si bien esto resulta divertido, una de las principales ventajas de usar Debian, es justamente el administrador de paquetes de software del sistema. Al instalar software mediante los repositorios, nos aseguramos de tenerlo actualizado sin más complicación que usar apt-get, y no andamos resolviendo dependencias a mano.

Bien, si queremos agregar estos repositorios de IceCat en nuestro sistema Debian y derivados, debemos editar el archivo /etc/apt/sources.list y agregar las siguientes líneas:

deb http://ppa.launchpad.net/gnuzilla-team/ppa/ubuntu VERSION_DE_UBUNTU main
deb-src http://ppa.launchpad.net/gnuzilla-team/ppa/ubuntu VERSION_DE_UBUNTU main

Hay paquetes para las versiones: Karmic Koala, Jaunty Jackalope, Intrepid Ibex y Hardy Heron de Ubuntu. En Debian Squeeze usé los paquetes de Karmic Koala, y se instaló de lo más bien sin dependencias del sistema.

Si deciden confiar en el PPA, deben autentificarlo con su clave:

1024R/08A255AF

Lo pueden hacer con el siguiente comando:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 12345678

Tras un apt-get update, ya pueden instalar IceCat con un simple apt-get install icecat. Además, el sistema actualizará IceCat automáticamente cuando hayan nuevas versiones en el repositorio.

» Leer más, comentarios, etc...

Picando Código

Montevideo Valley 2 – 2MVDValley

Octubre 27th, 2009 - [Enlace local]

Copio y pego descaradamente del blog de elQuique. Como avisa en los comentarios, en su post van a encontrar más información y fotos del lugar.

Montevideo Valley 2 ya tiene agenda confirmada y abrió el registro gratuito de participantes.

La cita es el próximo 12 de Noviembre, a las 19 horas, en el Balmoral Plaza Hotel.

MVDValley es una organización sin fines de lucro que surge con el objetivo de sinergizar la comunidad de emprendedores IT en Uruguay. Abriendo así un espacio de emprendedores a emprendedores.

Con el objetivo de estimular el networking y la actualización profesional, nació en noviembre de 2008 el primer encuentro MVDValley. Ahora hemos concretado la segunda edición en busca de conectar a todos los protagonistas de la web y las nuevas tecnologías en Uruguay, de conversar sobre temas novedosos, presentar empresas y productos. Esperamos recibirte a ti y a más de 100 invitados entre diseñadores, desarrolladores web, empresarios y emprendedores.

En el Balmoral, debes ir a la Sala Torres García

Recuerda agendarte el evento, donde te esperamos desde las 19hs, y estimamos la finalización del Networking a las 23:30hs

Si no conoces la ubicación, toma en cuenta la Av 18 de Julio, y la Plaza Cagancha

Balmoral Plaza Hotel

Balmoral Plaza Hotel

Agenda Montevideo Valley:

19:00 :: Acreditación

19:45 :: Bienvenida

20:00 :: PedidosYa.com | experiencia emprendedora

20:40 :: Microsoft | presentación de WebSiteSpark

21:20 :: Juan Pablo Sueiro| Social Media

22:30 :: Networking

23:30 :: Finalización

No pierdas tu lugar, haz tu registro gratis a Montevideo valley ahora!

Más información en MontevideoValley.com.uy

Fuente: Montevideo Valley 2 – 2MVD

» Leer más, comentarios, etc...

Variable not found

jqGrid: Grids espectaculares para ASP.NET MVC, paso a paso

Octubre 26th, 2009 - [Enlace local]

Dicen las malas lenguas ;-) que durante una reunión del equipo de diseño de ASP.NET MVC alguien dijo: “necesitaremos un control tipo Repeater”, refiriéndose a algún tipo de mecanismo para mostrar datos tabulados de forma sencilla. Y la respuesta del jefe técnico fue, “ya lo tenemos: se llama bucle foreach”.

Anécdotas aparte, es cierto que en ASP.NET MVC 1.0 no existe otro mecanismo que el bucle de toda la vida para mostrar datos en tablas, la típica rejilla con información sobre elementos de una colección tan habitual en nuestras aplicaciones. La máxima ayuda que tenemos “de serie” es el andamiaje generado por Visual Studio a la hora de generar una vista sobre una enumeración de elementos, que es válida únicamente en escenarios muy sencillos.

Y aquí es donde entra jQuery Grid Plugin (jqGrid para los amigos), un plugin para jQuery que se integra perfectamente con ASP.NET MVC y que permite simplificar enormemente el desarrollo  de vistas de tipo grid ofreciendo al mismo tiempo unas funcionalidades espectaculares: paginación, carga de datos de forma asíncrona vía Ajax, ordenación y redimensionado de columnas, edición de celdas, interfaz multi-idioma basado en temas, y un larguísimo etcétera.

En este post vamos a implementar un grid simple de consulta de datos utilizando jqGrid 3.5 y ASP.NET MVC 1.0, paso a paso. Además, al final del post encontraréis un enlace para descargar el proyecto de demostración para Visual Studio 2008 Express.

1. Descargamos jqGrid

Descarga de jqGridLo primero, como siempre, es descargar los componentes necesarios. Para hacernos con jqGrid, es necesario visitar la página de descargas del proyecto, en la que podemos encontrar un selector que nos permitirá elegir los módulos asociados a las funcionalidades que vayamos a utilizar.

En nuestro caso, dado que vamos a implementar un escenario muy simple, seleccionaremos únicamente el módulo “Grid base” y pulsamos el botón download situado en el pie de la tabla.

La descarga es un archivo .zip bastante ligerito cuyo contenido utilizamos así:

Archivos del proyecto 2. Descargamos un tema visual

jqGrid utiliza los temas visuales de jQuery UI para componer el interfaz, por lo que es necesario descargar alguno de los disponibles o bien crear uno personalizado con la herramienta on-line disponible en su página. Para nuestro ejemplo, vamos a utilizar el tema “Cupertino”.

Como en el caso anterior, seleccionamos los componentes a obtener (en principio, basta con UI Core a no ser que vayáis a utilizar esta librería para otras cosas), el tema, y pulsamos el botón download. Descargaremos un archivo .zip en cuyo  interior encontramos, dentro de la carpeta “css”, una subcarpeta con el nombre del tema elegido y que copiamos a la carpeta “content” del proyecto MVC.

La imagen anterior muestra la distribución de los archivos descritos hasta el momento en las distintas carpetas en las que hay que colocarlos.

3. Incluimos los componentes en el proyecto ASP.NET MVC

Tras crear el proyecto ASP.NET MVC, vamos a incluirle ahora las referencias a librerías y archivos necesarios para poder utilizar jqGrid.

Básicamente, tendremos que incluir en las páginas donde vayamos a utilizarlo referencias a jQuery, jqGrid, el archivo de localización, la hoja de estilos utilizada por jqGrid, y el tema que estemos empleando. Lo más fácil es hacerlo a nivel de página maestra, por ejemplo así:

<head runat="server">
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
    <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
 
    <link href="../../Content/ui.jqgrid.css" rel="stylesheet" type="text/css" />
    <link href="../../Content/cupertino/jquery-ui-1.7.2.custom.css" 
          rel="stylesheet" type="text/css" />
    <script src="../../Scripts/jquery-1.3.2.min.js" type="text/javascript"></script>
    <script src="../../Scripts/grid.locale-sp.js" type="text/javascript"></script>
    <script src="../../Scripts/jquery.jqGrid.min.js" type="text/javascript"></script>
</head>

Es importante incluir todos los archivos y en el orden correcto, de lo contrario el plugin no funcionará correctamente.

4. El modelo

En lugar de utilizar una base de datos, vamos a crear una simulación en memoria de un almacén de datos personales basado en la siguiente entidad:

public class Amigo
{
    public int Id { get; set; }
    public string Nombre { get; set; }
    public string Apellidos { get; set; }
    public DateTime FechaDeNacimiento { get; set; }
    public string Email { get; set; }
}

La lógica de negocio está implementada en la clase GestorDeAmigos, que incluye, además del constructor que carga los datos iniciales en el almacén (una colección de tipo List<Amigo> , los siguientes métodos:

public IEnumerable<Amigo> ObtenerAmigos(int pagina, int elementosPorPagina, 
                                        Func<Amigo, IComparable> orden, 
                                        Ordenacion ordenacion)
{
    IEnumerable<Amigo> datos;
    if (ordenacion==Ordenacion.Ascendente)
        datos = datosAmigos.OrderBy(orden);
    else
        datos = datosAmigos.OrderByDescending(orden);
 
    return datos.Skip((pagina - 1) * elementosPorPagina).Take(elementosPorPagina);
}
 
public int ContarAmigos()
{
    return datosAmigos.Count;
}

Del código anterior, sólo comentar los parámetros del método ObtenerAmigos:

Así, a continuación puede verse un ejemplo de lo simple que quedaría una llamada a este método, flexible pero con tipado fuerte:

var amigos = gestorDeAmigos.ObtenerAmigos(
                   1,                       // Página actual
                   25,                      // Registros por página
                   amigo=>amigo.Apellidos,  // Expresión de ordenación
                   Ordenacion.Ascendente    // Orden
             );

5. El controlador

Una de las principales ventajas que ofrece jqGrid es que la carga de los datos la realiza mediante peticiones Ajax. En la práctica, esto significa que irá lanzando llamadas a una acción de nuestro controlador para solicitarle la información conforme vaya necesitando datos, por ejemplo, durante la carga inicial de la página o cuando el usuario utiliza las herramientas de paginación, enviándole los siguientes parámetros:

El retorno de este método de acción debe ser un objeto serializado en JSON (aunque también permite XML) y ha de ajustarse a un formato especificado en la documentación, que es el que jqGrid espera recibir, algo como:

{ 
  total: "xxx", 
  page: "yyy", 
  records: "zzz",
  rows : [
    {id:"1", cell:["cell11", "cell12", "cell13"]},
    {id:"2", cell:["cell21", "cell22", "cell23"]},
      ...
  ]
}

El método de obtención de datos,  nuestra acción, seguirá normalmente el patrón recogido en el código mostrado a continuación. Si os fijáis, lo único que estamos haciendo es reproducir fielmente esta estructura anterior en un objeto anónimo, de forma que  al transformarlo en JSON (gracias al retorno de tipo JsonResult) se genere justo lo que necesitamos:

public ActionResult ObtenerDatosGrid(string sidx, string sord, int page, int rows)
{
    var datos = [...]          // Obtener datos del modelo
    var totalRegistros = [...] // Contar todos los registros
 
    int totalPages = (int)Math.Ceiling((decimal)totalRegistros / (decimal)rows);
 
    var data = new
    {
        total = totalPages,        // Total de páginas
        page = page,               // Página actual
        records = totalRegistros,  // Total de registros (obtenido del modelo)
        rows = from a in datos     // Datos de filas
               select new {
                   id = a.Id,                // ID único de la fila
                   cell = new string[] {     // Array de celdas de la fila
                       a.Apellidos,                             // Primera columna,            
                       a.Nombre,                                // Segunda columna,
                       a.FechaDeNacimiento.ToShortDateString(), // Tercera columna,
                       a.Email                                  // Cuarta columna  
                   }
               }
    };
    return Json(data);
}

Nuestro ejemplo se ajusta totalmente al patrón anterior, aunque incluiremos código extra para tener en cuenta las ordenaciones indicadas por los parámetros sidx y sord en la invocación al modelo. Observad cómo construimos las expresiones de ordenación:

public ActionResult ObtenerDatosGrid(string sidx, string sord, int page, int rows)
{
    // Establecemos la función de ordenación dependiendo del valor del 
    // parámetro "sidx", que es el campo de orden actual
    Func<Amigo, IComparable> funcOrden =
        sidx == "Apellidos" ? a => a.Apellidos :
        sidx == "FechaDeNacimiento" ? a => a.FechaDeNacimiento :
        sidx == "Email" ? a => a.Email :
        (Func<Amigo, IComparable>)(a => a.Id);
 
    // Establecemos si se trata de orden ascendente o descendente, en
    // función del parámetro "sord", que puede valer "asc" o "desc"
    Ordenacion ordenacion = sord == "asc" ? Ordenacion.Ascendente : Ordenacion.Descendente;
 
    // Usamos el modelo para obtener los datos
    var datos = gestorDeAmigos.ObtenerAmigos(page, rows, funcOrden, ordenacion);
    int totalRegistros = gestorDeAmigos.ContarAmigos();
    ... 
}

6. La vista

En la vista debemos crear un elemento contenedor, concretamente una tabla XHTML con un identificador único que después usaremos para indicarle al plugin dónde tiene que actuar su magia. Si además, como bastante habitual, pensamos incluir herramientas de paginación, tendremos que incluir también un contenedor para la misma:

<table id="list"></table>
<div id="pager"></div>    

El siguiente paso es inicializar jqGrid cuando se termine de cargar la página, para lo que crearemos un código javascript como el mostrado a continuación, en el que se invoca la función de activación del plugin sobre la tabla cuyo ID se indica en el selector (“#list“), y especificando el comportamiento deseado en los parámetros que le siguen:

script type="text/javascript">
    jQuery(document).ready(function() {
        jQuery("#list").jqGrid({
            url: '<%= Url.Action("ObtenerDatosGrid") %>',
            datatype: 'json',
            mtype: 'GET',
            colNames: ['Apellidos', 'Nombre', 'Fecha Nac.', 'Email'],
            colModel: [
              { index: 'Apellidos', width: 150, align: 'left' },
              { index: 'Nombre', width: 150, align: 'left', sortable: false },
              { index: 'FechaDeNacimiento', width: 80, align: 'center' },
              { index: "Email", width: 120, align: 'left'}],
            pager: jQuery('#pager'),
            rowNum: 20,
            rowList: [20, 50, 100],
            sortname: 'Apellidos',
            sortorder: 'asc',
            viewrecords: true,
            imgpath: '/content/cupertino/images',
            caption: 'Agenda personal',
            height: 400,
            width: 900,
            onSelectRow: function(id) {
                alert("Pulsado Id: " + id);
            }
        });
    }); 
</script>    

Revisamos rápidamente el significado de los distintos parámetros:

Y… ¡Voilá!

Demo de jqGrid en acción¡Hasta aquí hemos llegado! Hemos visto cómo utilizar el magnífico jqGrid en un escenario simple, paso a paso, comenzando por la descarga de los componentes, preparando el proyecto para poder utilizarlos y, finalmente, implementando el modelo, el controlador, y la vista.

Pero jqGrid no es sólo eso, ni mucho menos. No hemos visto más que la punta del iceberg: el plugin permite realizar búsquedas, edición, anidación de grids, árboles, escenarios maestro-detalle… en fin, una maravilla.

jqGrid se distribuye bajo licencia dual GPL y MIT, y puede ser utilizado tanto en proyectos comerciales como libres. Dispone de una documentación bastante razonable, y muchos ejemplos para que podamos apreciar sus virtudes.

Descargar proyecto de demostración:

Publicado en: Variable not found.



» Leer más, comentarios, etc...

Ingenieria de Software / Software Engineering

VISIO 2010, BPMN y Sharepoint WF´s

Octubre 26th, 2009 - [Enlace local]

Ya trabajando con Office 2010 me encuentro que en Visio entre otras novedades importantes están los Shapes para Business Process Management Notation y Shapes para el diseño de WorkFlows en Sharepoint.

Visio 2010

» Leer más, comentarios, etc...

Najaraba.com: Software libre, metodologías ágiles y más.

Primer Agile Open Spain: Fabuloso #agileopenspain2009!

Octubre 25th, 2009 - [Enlace local]

Pues finalmente llegó el Agile Open Space, y pasó rapidisimo de lo interesante que resultó.Después de unas semanas de ajetreo con la organización, finalmente validamos nuestras expectativas. Afluencia masiva de los inscritos, y muchísimo nivel en las charlas organizadas el sábado.El viernes, tras los últimos detalles de preparación del evento, empezó a llegar la gente hacia las 18:00, y a las 18:

» Leer más, comentarios, etc...

4 bits blog

Internacionalización en Java usando UTF-8

Octubre 23rd, 2009 - [Enlace local]

Una de las bondades de Java es que trae un montón de clases que hacen de todo, incluso internacionalización, es decir, poder traducir nuestra aplicación para que se muestre en el idioma adecuado para el usuario.

Si alguna vez habéis necesitado internacionalizar en Java, os habréis encontrado con la clase ResourceBundle, esta clase permite la traducción a partir de un archivo tipo properties (que se basa en líneas campo = valor).

Lo malo es que Java trata estos archivos properties utilizando la codificación ISO-8859-1, de modo que si utilizas un archivo properties guardado en UTF-8 algunos símbolos (por ejemplo: la eñe) se mostrarán de forma incorrecta. Para solucionar este problema, se debe usar el siguiente truco:

import java.io.UnsupportedEncodingException;
import java.util.ResourceBundle;

public class UTFi18n {

    // Messages es el nombre del archivo que contiene los mensajes traducidos
    private ResourceBundle messages =  ResourceBundle.getBundle ("Messages");

    public static String getMessage (String message) {

        String value = messages.getString (message);
        String ret;

        try {
            // Hack to manage properties files using UTF-8
            ret = new String (value.getBytes ("ISO-8859-1"), "UTF-8");

        } catch (UnsupportedEncodingException encEx) {
            ret = value;
        }

        return ret;
    }
}

Basado en Quick and Dirty Hack for UTF-8 Support in ResourceBundle de Thoughts About.

» Leer más, comentarios, etc...

Picando Código

Me compré termo, mate y bombilla

Octubre 22nd, 2009 - [Enlace local]

Si bien los que siguen este blog sabrán que soy adicto al café, últimamente vengo tomando cada vez más mate. En algún momento me decidí, y este fin de semana completé el kit de termo, mate y bombilla.

No es muy uruguayo de mi parte, recién con 24 años, tengo mi primer mate, termo y bombilla:

Nuevo termo, mate y bombilla

Nuevo termo, mate y bombilla

El domingo pasado lo compramos en la feria de Maldonado, y lo dejé curando con Whisky y yerba mate. Recién hoy lo estrené y saqué esta foto :P

Yerba mate

Yerba mate

Las propiedades de la yerba mate, hacen que la infusión sea bastante similar en algunas características con el café. Y su consumo produce efectos estimulantes similares también. De Wikipedia:

Composición química y propiedades

Cafeína
El mate contiene xantinas, que son alcaloides como son la cafeína, teofilina, y teobromina, estimulantes bien conocidos y hallados en café y en chocolate. El contenido de cafeína varia entre 0,2% a 2% de peso seco (comparado con el 0,3–9% para las hojas de té, 2,5-7,5% en guarana, y más de 3,2% para café).

Estereoisómeros
Sin embargo, la cafeína no es quiral, y no tiene estereoisómeros, y la “mateína” es un sinónimo oficial de la cafeína en las Bases de Datos de Química.

Los estudios sobre el mate, aunque muy limitados, han mostrado evidencia preliminar que el cocktail de xantinas del mate es diferente de otras especies conteniendo cafeína más significativamente en sus efectos en los tejidos musculares, como los opuestos a aquellos en el sistema nervioso central, que son similares a los de otros estimulantes naturales. Las tres xantinas presentes en el mate han mostrado tener efecto relajante en los tejidos musculares lisos, y efectos estimulantes miocardicos.

Esta bebida es bastante popular en Brasil, Argentina, Paraguay y Uruguay, e incluso hace un tiempo descubrí que venden mate en ThinkGeek.Parte de la tradición del “tomar mate”, es personalizar el termo con pegotines (generalmente de partidos políticos, cuadros de fútbol, etc.). A falta de un sticker mejor, le pegué el de la campaña Bad Vista que si bien ya se dió por terminada, el pegotín está bueno.

Así que ahora, además de drogarme con cafeína me drogo con mateína también.

» Leer más, comentarios, etc...

MonoCaffe

Monocaffe Connections Manager 0.2

Octubre 22nd, 2009 - [Enlace local]

En un par de horas y ya lanzo la versión 0.2, esto es desarrollo ágil. Gracias a bob_f en el canal de #python en FreeNode he mejorado la presentación de las listas. Además de ello he arreglado un fallo con el RDP y bueno, me he acordado que Dropbox permite publicar cosas. Así que aquí os dejo la última versión.



Descargar Monocaffe Connections Manager 0.2



Unas capturas



» Leer más, comentarios, etc...

Ingenieria de Software / Software Engineering

Requirements Management Maturity RMM

Octubre 22nd, 2009 - [Enlace local]

Me ha parecido excelente el siguiente post de Pablo Fernando Sánchez en el cual se habla de RMM, artículos como este muestran lo importante que es la Gestión de Requerimientos y lo fatal que puede ser hacer un gestión débil de requerimientos. Debemos de entender en la industria de software lo vital que es esta fase para el éxito de los proyectos de software pero también creo que se debe concientizar a los clientes del tema por que si bien se subutiliza la gestión de requerimientos en las empresas proveedoras los clientes también ponen su grano de arena para orillar el proyecto a una mala gestión mas sin embargo es mas labor de la empresa de software el guiar la implementación.

» Leer más, comentarios, etc...

MonoCaffe

Monocaffe Connections Manager 0.1

Octubre 22nd, 2009 - [Enlace local]

Llevaba algún tiempo con esta idea rondandome la cabeza. Odio tener que abrir una hoja de cálculo o un página en una Wiki cada vez que necesito recordar los datos para conectarme a cierta máquina. Dado que todo esto lo hago desde una consola, otras soluciones que de todas formas no me convencían, funcionan sólo sobre el entorno gráfico (p.e. PuTTy).

Así que, utilizando Python he creado una pequeña aplicación para mantener una lista con todos los servidores a los que me conecto y almacenar nombre, contraseña, conexión, etc. Está listo para funcionar sobre Ubuntu, pero es fácil de modificar para otras distribuciones en caso de ser necesario. Quizás algún día lo añadan a los repositorios de Debian.

Para el futuro me gustaría añadir una interfaz ncurses, GTK y Qt, sólo por hobbie.

Para instalarla:

  1. $tar -xvzf monocaffe_connections_manager-0.1.tar.gz
  2. $cd mcm
  3. $chmod 766 mcm
Si queréis instalarla como es debido:

  1. $tar -xvzf monocaffe_connections_manager-0.1.tar.gz
  2. $sudo mv mcm /usr/share
  3. $sudo chown -R root.root /usr/share/mcm
  4. $sudo chmod 777 /usr/share/mcm/mcm

  5. $cd /usr/bin/
  6. $sudo ln -s /usr/share/mcm/mcm mcm
Supongo que tocara hacer un MakeFile para esto o incluso un .deb

Para descargar

O pulsando aquí

Espero le encontréis utilidad.

El enlace de RapidShare es temporal, por lo que si veo que mucha gente se lo descarga (dejadme un comentario aquí si no funciona y lo arreglo)

» Leer más, comentarios, etc...

MadeInFlex

Oferta Laboral – Codeoscopic

Octubre 22nd, 2009 - [Enlace local]

Descripción de la empresa

Codeoscopic es la empresa española lider en servicios y productos creados entorno a la tecnología Adobe Flex. Ofrecemos un expertise tecnológico en nuevas tecnologías RIA basadas en Adobe Flex, Flash, AIR y Java. Tenemos nuestra propia tecnología Flex/JEE llamada RIAlity que sirve de plataforma a todos nuestros productos. Nos dedicamos a ofrecer servicios de valor añadido basados en nuestros altos conocimientos en la tecnología. También somos creadores de productos de diferente calado (actualmente 7 productos), como son Avant, GeoStratum, Direct Writer, etc...

Si estás deseando formar parte de una compañía que se dedica al 100% a estas tecnologías, esta es tu oportunidad de ofrecer tu candidatura. Podrás formar parte de una empresa donde lo más importante son las personas que la componen.

Descripción de la plaza

Buscamos perfiles a todos los niveles: Especialistas Flex, Java, Jefes de Proyecto, Analistas Programadores, Programadores, Becarios.

Nuestra empresa está especializada al 100% en Adobe Flex y JEE. El tipo de trabajo que desarrollamos puede variar de productos internos desarrollados sobre nuestra propia plataforma RIAlity, hasta servicios y consultoría sobre Adobe Flex y Java. Los candidatos podrán participar en productos y servicios RIA dependiendo de las necesidades de la empresa.

Requisitos y conocimientos

Somos una empresa focalizada en Flex y Java, por lo que todos los puestos requieren especializarse en estas tecnologías. Dependiendo del puesto serán necesarios unos conocimientos u otros y metodologías de desarrollo de proyectos RIA.

Localidad y tipo de contrato

Buscamos perfiles en nuestras oficinas de Madrid y Barcelona. Contratos Indefinidos.

Salario bruto

Depende del puesto y valía del candidato.

Contacto

rrhh@codeoscopic.com

» Leer más, comentarios, etc...

avemundi, blog de un micro-isv » Desarrollo de software

hippoedit por 15$

Octubre 21st, 2009 - [Enlace local]

El próximo 22 de Octubre, es decir mañana, se puede comprar Hippoedit por 15$. Para mi Hippoedit es el mejor editor ligero para Windows, con unas características avanzadas de edición que pocos editores soportan y con el interfaz más cuidado de todos los editores que conozco. La compra se debe hacer desde esta página.

» Leer más, comentarios, etc...

Arragonán

Great developers - not programming languages - build great products

Octubre 20th, 2009 - [Enlace local]

Hacía tiempo mucho que me rondaba por la cabeza escribir algo de la “guerra” de los lenguajes de programación(y frameworks por extensión), un flame típico en blogs, foros, listas de correo, eventos, cafés, cervezas… y Abel Muiño (@amuino) me lo puso ayer en bandeja con esta cita extraída del post The Best Programming Language for a Lean Startup.

A mi ha llegado un punto en que me resulta gracioso, dependiendo de la experiencia de cada programador, se oyen opiniones que no tienen nada que ver unas con otras. Cuando al final, que un producto sea mejor o peor(al menos a nivel de programación), depende más de la capacidad del programador y su experiencia con el lenguaje que utilice, y no del lenguaje en sí.

Algunas opiniones/tópicos que he visto repetirse muuuchas veces:

Java es “enterprisey”.
Rails no escala.
Para aplicaciones empresariales serias, hay que utilizar Java.
Javascript es sucio.
Si no tiene tipado estático, es para aplicaciones de juguete.
-Pon aquí un lenguaje- es lento.
-Pon aquí un lenguaje- es una mierda XD.

O el clásico:

Cobol está muerto

Y para que no se diga, tampoco estoy libre de pecado, yo pienso que PHP lo pone demasiado fácil para empezar a escribir código spaghetti XD

» Leer más, comentarios, etc...

Variable not found

Ilities

Octubre 19th, 2009 - [Enlace local]

El listo Los “ilities”, cuya traducción a nuestro idioma podría ser algo así como “ilidades”, son atributos que definen aspectos no funcionales y normalmente asociados con requisitos técnicos y cualidades de un sistema o componente software. El nombre viene del sufijo –ilidad, que, como podréis ver a continuación, es común a la práctica totalidad de ellos.

He encontrado en la Wikipedia una interesante (aunque no exhaustiva) relación ilidades, que podemos utilizar a la hora de intentar transmitir las características de un sistema… o simplemente para aparentar ser auténticos expertos en una reunión de trabajo ;-)

  1. Accesibilidad, es decir, el hecho ser accesible a muchas personas, con independencia de sus características, dispositivos utilizados, etc.
  2. Reportabilidad, capacidad para monitorizar y registrar las acciones del usuario.
  3. Exactitud, grado de distancia desde los resultados ofrecidos por un sistema a los valores entendidos como reales.
  4. Adaptabilidad, facilidad que presenta un software para ser adaptado a necesidades concretas.
  5. Administrabilidad, indica la capacidad de un sistema o componente para ser administrado y gestionado.
  6. Asequibilidad, que indica que, atendiendo a su coste, el sistema puede ser adquirido o conseguido por los clientes.
  7. Auditabilidad, transparencia frente a sistemas de auditoría.
  8. Disponibilidad, grado en el que un sistema está disponible, operativo y funcional.
  9. Credibilidad, que es considerado subjetiva y objetivamente como una fuente de información fiable.
  10. Conformidad con estándares, grado de cercanía a las prácticas o técnicas aceptadas como estándares.
  11. Compatibilidad, que funciona en un escenario determinado, o permite sustituir otros sistemas equivalentes.
  12. Componibilidad, capacidad para combinar el software con otros elementos para componer sistemas no previstos inicialmente.
  13. Configurabilidad, esto es, que dispone de mecanismos que permiten configurar algunos aspectos de su comportamiento.
  14. Corrección, que indica que el software actúa conforme a sus especificaciones.
  15. Personalizabilidad, capacidad de un sistema para ser personalizado a las preferencias de sus usuarios.
  16. Degradabilidad, capacidad para mantener las funcionalidades básicas en condiciones adversas.
  17. Demostrabilidad, aplicable a aquellos sistemas cuyo funcionamiento puede ser demostrado.
  18. Dependabilidad, que define la probabilidad de que el sistema complete su misión, dado que estaba disponible en el comienzo de la misma.
  19. Desplegabilidad, capacidad de un software para ser desplegado en un escenario.
  20. Distribuibilidad, capacidad o facilidad de un componente o sistema para ser distribuido.
  21. Durabilidad, mantenimiento de las funciones con el paso del tiempo.
  22. Efectividad, o capacidad para lograr el efecto deseado.
  23. Eficiencia, capacidad para lograr el efecto deseado con el menor consumo posible de recursos.
  24. Evolucionabilidad, grado de facilidad con la que es posible hacer evolucionar un sistema para adaptarse a nuevas condiciones.
  25. Extensibilidad, capacidad de un software para ser ampliado con nuevas funciones sin modificar su estructura básica.
  26. Fidelidad, que ofrece precisión y confianza en la representación de la realidad.
  27. Flexibilidad, que puede adaptarse con facilidad a cambios en el entorno.
  28. Instalabilidad, facilidad para ser instalado en un entorno  determinado.
  29. Integridad, capacidad para evitar y sobreponerse a errores en la información que maneja.
  30. Intercambiabilidad, que indica que un componente puede ser sustituido por otro sin modificar aquellos que lo utilizan.
  31. Interoperabilidad, capacidad que tiene un sistema para intercambiar información con otro.
  32. Aprendibilidad, es decir, la capacidad que presenta un software para enseñar su propio manejo al usuario.
  33. Mantenibilidad, o facilidad con la que se puede corregir, modificar o ampliar un software.
  34. Gestionabilidad, facilidad para gestionar la complejidad de un sistema.
  35. Movilidad, posibilidad que tiene un sistema de funcionar en distintas ubicaciones geográficas.
  36. Modularidad, grado en el que un software está internamente dividido en bloques independientes.
  37. Nomadicidad, capacidad de un sistema para adaptarse de forma transparente a una situación de desconexión por cambio de ubicación-
  38. Operabilidad, capacidad de un software para funcionar y cumplir su misión.
  39. Portabilidad, la facilidad con la que un software puede ser transferido a otro entorno software o hardware.
  40. Precisión, nivel de detalle con el que un sistema es capaz de manejar información.
  41. Predictibilidad, grado de certeza del comportamiento del sistema ante un escenario determinado.
  42. Recuperabilidad, capacidad de un sistema de restablecer un nivel apropiado de servicio y recuperar sus datos en caso de producirse fallos.
  43. Fiabilidad, es la habilidad de un software para realizar sus funciones de forma correcta bajo unas condiciones determinadas.
  44. Repetibilidad, es la capacidad de generar el mismo resultado si no cambian las condiciones.
  45. Reproducibilidad, es el grado de precisión que se obtiene al intentar reproducir un comportamiento del sistema.
  46. Responsividad, velocidad con la que un sistema realiza una tarea, por ejemplo responder a la entrada del usuario.
  47. Reusabilidad, facilidad con la que un componente o sistema puede ser reutilizado para añadir funcionalidades o características en un nuevo sistema.
  48. Robustez, capacidad para continuar la operación aún en el caso de producirse errores inesperados.
  49. Seguridad, capacidad de un software para conseguir niveles aceptables de daños a personas, negocios, software, propiedades o entorno.
  50. Escalabilidad, facilidad con la que un sistema puede ser adaptado para satisfacer necesidades mayores de carga de trabajo.
  51. Uniformidad, grado de presentación como una estructura consistente, aunque el sistema incluya diversas tecnologías.
  52. Soportabilidad, que hace referencia a la habilidad del soporte técnico para dar soporte a los productos.
  53. Asegurabilidad, capacidad para asegurar distintos niveles de un sistema.
  54. Simplicidad, o ausencia de complicaciones y dificultades.
  55. Estabilidad, capacidad de un software para funcionar períodos del tiempo sin parar o funcionar incorrectamente.
  56. Comprobabilidad, el grado en el que un componente soporta la realización de pruebas para validar su corrección.
  57. Oportunidad, es decir, el hecho de estar disponible en el momento en el que debe estarlo.
  58. Ubicuidad, capacidad de un software para estar presente en todas partes, en cualquier momento.
  59. Comprensibilidad, facilidad con la que un software puede ser comprendido a los distintos niveles.
  60. Usabilidad, facilidad con la que un usuario puede utilizar un sistema software para conseguir un objetivo. 

Los términos originales estaban en inglés y algunos no eran fácilmente traducibles, así que en más de una ocasión he tenido que echar mano de la creatividad y patear a la RAE y todos sus integrantes ;-D

Publicado en: Variable not found.



» Leer más, comentarios, etc...

carlosrovira.com

Visor de Fotos Flex con Picasa (II)

Octubre 19th, 2009 - [Enlace local]

En la anterior entrada resolvimos la todo lo concerniente a la recogida de datos de un álbum alojado en Picasa. En este post veremos una forma de resolver la parte visual del visor de fotos de la cabecera de este blog.

headerphotos

El planteamiento principal a la hora de pensar técnicamente este visor simple de fotos era como hacerlo de forma que la memoria se mantuviera estable y no tuviéramos problemas si manteníamos la ejecución durante largo tiempo, teniendo en cuenta que estamos todo el rato cargando imágenes que se quedan en el fondo del visor y que van a ir siendo tapadas en parte por las nuevas fotos.

La forma óptima es usar solo dos objetos. Un control Image de Flex que es el que irá cargando cada foto, y un Bitmap que será sobre el que iremos copiando los pixeles de cada imagen una vez terminen el recorrido de su animación (este componente puede ser un UIComponent). Una vez desarrollado este concepto, vemos que el profiler se mantiene constante como era de esperar en cuanto a la memoria consumida.

visorfotos_profiler

En cuanto a la programación llevada a cabo. Los dos objetos que intervienen son el control Imagen y un UIComponent que servirá de “lienzo” para ir copiando las fotos e ir manteniendo el uso de memoria:



A continuación un poco de código de inicialización para entender que variables hay implicadas:

// --- Definición de variables y código de inicialización
// --- Bitmap sobre el que copiaremos las imagenes
private var collage:Bitmap;
// --- Array de datos descargado de PIcasa (ver post anterior)
private var fotos_arr:Array;

// --- Inicialización del canvas (UIComponent) sobre el que pintaremos las imagenes
canvas.width = width;
canvas.height = height;
collage = new Bitmap(new BitmapData(width, height, true, 0x000000));
canvas.addChild(collage);

Luego tenemos un método que se encarga de “lanzar una foto” como podemos ver a continuación:

public function throwOnePhoto():void {
        //-- Sacamos la imagen que lanzaremos del array de fotos de picasa al azar
	var tmp:Object = fotos_arr.splice(Math.random()*fotos_arr.length,1).pop();

	// --- hacemos los calculos iniciales (rotacion,escala,...) para dicha imagen
	angle = range*Math.random()-range/2;
	finalAngle = -angle+Math.random()*20;
	rot.angleTo = finalAngle;
	img.scaleX = img.scaleY = 2;
	img.alpha = 0;
        // --- sacamos la url de los datos de picasa y añadimos el parametro imgmax. Esto último es *crucial* para evitar errores de carga en algunos navegadores (como siempre IE da sus problemillas). Otro pequeño truco indispensable para que funcione este servicio de Picasa correctamente.
	img.source = tmp.media.content.url + "?imgmax=800";
	img.width = tmp.media.content.width;
	img.height = tmp.media.content.height;
	img.x = Math.random()*(width - img.width);
	img.y = Math.random()*(height - img.height);
	img.rotation = angle;

        // --- dibujamos en la imagen un fondo blanco y proyectamos una sombra para darle aspecto de foto a la imagen
	img.graphics.clear();
	img.graphics.beginFill(0xffffff);
	img.graphics.drawRect(-5, -5, img.width+10, img.height+10);
	img.graphics.endFill();
	img.filters = [new DropShadowFilter(1, 90, 0, .75, blur, blur, 2, 2)];
}

Cada vez que queramos lanzar una foto, llamaremos al método anterior.

En cuanto al efecto utilizado cuando “lanzamos la foto”, se trata de una combinación de efectos ejecutados en paralelo:


	
		
		
		
	

En este caso, el truco está en el uso de los parámetros startDelay y duration para hacer la combinación de timelines que buscamos. Otro parámetro clave en la nueva arquitectura de efectos de Flex 4 es autoCenterTransform, cuyo cometido es hacer que los efectos Move, Scale y Rotate actúen al unisono mediante un proxy que hace que el valor solo cambie una vez como resultado de todos los cambios de efectos sobre el objeto (de esta forma se evitan los parpadeos o “brincos” inesperados de los objetos animados.

Finalmente y una vez que el efecto a terminado, tenemos que ejecutar la parte más delicada del proceso. La copia del estado visual de la imagen en nuestro lienzo para poder reutilizar el componente Image nuevamente y evitar el uso innecesario de memoria, como comentamos anteriormente. Para ello llamamos al método copyImage cuando el efecto a terminado su ejecución:

//cuando termina el effecto
private function copyImage(event:EffectEvent):void {
	drawOntoBitmapData(img,collage.bitmapData);

	if(fotos_arr.length > 0)
		throwOnePhoto();
}

El método drawOntoBitmapData se encarga de dibujar el objeto Image sobre el Bitmap. En el conseguimos los limites de la imagen mediante getBounds (teniendo en cuenta que hemos aplicado un filtro de sombra). Y tenemos que tener igualmente en cuenta la rotación y la traslación aplicada para hacer la copia final en nuestro lienzo. Aquí se trata de darle un poco de uso a nuestros conocimientos matemáticos ;) .

private function drawOntoBitmapData(source : IBitmapDrawable, target : BitmapData) : void {
	var bounds : Rectangle = DisplayObject(source).getBounds(DisplayObject(source));
	var bitmapData : BitmapData = new BitmapData(bounds.width+blur*2, bounds.height+blur*2, true, 0x00000000);
	var mangle:Number = finalAngle*Math.PI/180;
	var sinVal:Number = Math.sin(mangle);
	var cosVal:Number = Math.cos(mangle);

	var m1:Matrix= new Matrix(1, 0, 0, 1, -bounds.x+blur, -bounds.y+blur);
	bitmapData.draw(source, m1, null, null, null, true);

	var m2:Matrix= new Matrix(1, 0, 0, 1, bounds.x - blur, bounds.y - blur);
	m2.translate(img.x*cosVal+img.y*sinVal, img.y*cosVal-img.x*sinVal);
	m2.rotate(mangle);
	target.draw(bitmapData, m2, null, null, null, true);
}

Y ya está. El efecto visual está terminado y listo para usar en nuestro blog :) .

Espero que os haya parecido interesante. El siguiente paso es empezar a jugar con lo conseguido y experimentar con las nuevas cosas que ofrece Flex 4…¿qué tal si aplicamos ahora un efecto Rotate3D?

;)

» Leer más, comentarios, etc...

4 bits blog

Los problemas de la clase JSObject

Octubre 19th, 2009 - [Enlace local]

Como los applets se ejecutan dentro de una página web, se creó un mecanismo (llamado LiveConnect) para comunicarse con el navegador mediante JavaScript, es decir, poder ejecutar JavaScript desde el applet.

Este mecanismo ofrece una clase llamada JSObject que permite realizar la comunicación del applet a JavaScript, esta clase se localiza en el paquete netscape.javascript.

Lo malo es que esta clase tiene varios problemas y fallos relacionados que no vienen documentados en ningún sitio, sólo en algunas páginas de gente que ha conseguido averiguarlos por su cuenta.

JSObject no es thread safe

El caso es que en los ejemplos de la página de Sun dedicada a la clase JSObject, se puede ver un ejemplo de su uso:

import netscape.javascript.*;
import java.applet.*;
import java.awt.*;

class MyApplet extends Applet {
    public void init() {
        JSObject win = JSObject.getWindow (this);
        JSObject doc = (JSObject) win.getMember ("document");
        JSObject loc = (JSObject) doc.getMember ("location");

        String s = (String) loc.getMember ("href");  // document.location.href
        win.call ("f", null);   // Call f() in HTML page
    }
}

Bien, pues éste uso no es correcto, ya que esta clase no es thread safe y en las versiones más recientes del complemento de Java para los navegadores, puede que la máquina virtual de Java ejecute varios hilos y el uso de esta clase acabe fallando. Para arreglarlo, sólo se debe hacer lo siguiente:

synchronized (JSObject.class) {
    win = JSObject.getWindow (applet);
}

Básicamente, se trata de encapsular el uso de la clase JSObject en un bloque synchronized para evitar fallos por cualquier causa relacionada con hilos.

JSObject.getMember () no funciona en Firefox sobre Mac OS X

Otro problema que tiene esta clase es que en la versión de Firefox para Mac OS X, el método getMember no funciona bien y siempre devuelve null, lo que obliga a usar un trozo de código algo feo. Por ejemplo, para obtener el userAgent del navegador:

synchronized (JSObject.class) {
    win = JSObject.getWindow (applet);
}
JSObject nav = win.getMember ("navigator");
String userAgent = (String) nav.getMember ("userAgent");

Utilizando el método getMember.

synchronized (JSObject.class) {
    win = JSObject.getWindow (applet);
}
String userAgent = (String) win.eval ("navigator.userAgent");

Un apaño, utilizando el método eval.

Basado en los posts sobre JSObject de Svetlin Nakov

» Leer más, comentarios, etc...