martes 24 de mayo de 2011

Instalar Pràctic2 en Ubuntu

La Junta Qualificadora de Coneixements de Valencià (JQCV) es el organismo dependiente de la Conselleria de Educación de la Generalitat Valenciana responsable de efectuar las pruebas de conocimientos de valenciano.

Entre el material que la JQCV proporciona en su página web para el estudio del valenciano, se encuentra el Pràctic2, que es un programa de autoaprendizaje mediante tests que simulan las pruebas de certificación.


Por desgracia, sólo hay disponible una versión para Windows. Por suerte, siguiendo unos pocos pasos podremos hacerlo funcionar en Ubuntu:

1. Si no tenemos instalado Wine, hay instalarlo, mediante cualquier método: Synaptic Package Manager, Ubuntu Software Center, o escribiendo en la línea de comandos:

apt-get install wine1.3

2. Descargar de la página web de la JQCV el programa Pràctic2, y descomprimir el fichero practic2.zip.

3. Ejecutar el fichero extraido "instal.exe"

4. Si no lo tenemos ya instalado, instalar winetricks, bien desde su página web, bien desde el Synaptic Package Manager, o escribiendo en la línea de comandos:

apt-get install winetricks

5. Ejecutar en un terminal "winetricks mdac28" y tras finalizar la descarga, seguid los pasos en pantalla.

6. Ejecutar en un terminal "winetricks jet40" y tras finalizar la descarga, seguid los pasos en pantalla.

Tras finalizar estos pasos, el programa funcionará perfectamente. Podemos ejecutarlo sencillamente haciendo doble click en el icono que se habrá creado en el escritorio (si hemos elegido esa opción), o mediante el menú Applications --> Wine.

¡Mucha suerte con el estudio!


Posible problema 1. Si se intenta ejecutar el programa inmediatamente después de la instalación, dará el siguiente error:

Error creating object. Please verify that the Microsoft Data Access Components 2.1 (or later) have been properly installed

La aplicación arranca, pero no puede acceder a sus datos internos, por lo que nada funcionará. Salimos de la aplicación.

Ejecutando el programa desde una terminal, probablemente veamos un mensaje como:

fixme:ole:CoResumeClassObjects stub
fixme:win:LockWindowUpdate (0x1009a), partial stub!
fixme:win:LockWindowUpdate ((nil)), partial stub!
err:ole:CoGetClassObject class {00000514-0000-0010-8000-00aa006d2ea4} not registered
err:ole:create_server class {00000514-0000-0010-8000-00aa006d2ea4} not registered
err:ole:CoGetClassObject no class object {00000514-0000-0010-8000-00aa006d2ea4} could be created for context 0x5

En este caso, tenemos que ejecutar "winetricks mdac28" para instalar la librería correspondiente.

Posible problema 2. Si se intenta ejecutar con las MDAC instaladas, pero sin las JET, dará el siguiente error:

Provider cannot be found. It may not be properly installed.

Ejecutando el programa desde una terminal, probablemente veamos un mensaje como:

fixme:ole:CoResumeClassObjects stub
fixme:win:LockWindowUpdate (0x1009a), partial stub!
fixme:win:LockWindowUpdate ((nil)), partial stub!
err:ole:CoGetClassObject class {6c736db1-bd94-11d0-8a23-00aa00b58e10} not registered
err:ole:CoGetClassObject no class object {6c736db1-bd94-11d0-8a23-00aa00b58e10} could be created for context 0x1

En este caso, tenemos que ejecutar "winetricks jet40" para instalar la librería correspondiente.

martes 17 de mayo de 2011

Descargar páginas creadas con Google Sites

Para descargar al disco duro páginas creadas con Google Sites, se puede utilizar una herramienta llamada Google Sites Liberation.

Se trata de una herramienta desarrollada en Java, que se puede ejecutar en cualquier ordenador, independientemente del Sistema Operativo que tenga instalado, con tan sólo hacer doble click sobre el fichero .jar descargado.

Encontramos un ejemplo de utilización en la siguiente captura de pantalla:


Los principales parámetros a cambiar son:

- Webspace: url de la página a descargar. Ej: Para la página http://sites.google.com/site/siteadescargar/ se pone en esta casilla "siteadescargar".
- Username / password: cuenta de Google.
- Target directory: Ubicación en el disco duro de los ficheros a exportar o importar

Una vez introducidos los datos, pulsamos en "Export", y descargará la web a nuestro disco duro. La opción "Import" puede servirnos para restaurar copias de seguridad.

También es compatible gon Google Apps, introduciendo los parámetros correspondientes.

jueves 17 de marzo de 2011

Organizar automáticamente el correo

¿Quieres darle tu dirección de correo a un grupo de gente, pero quieres tener automáticamente organizado el correo de esa gente?

Si usas Hotmail o GMail, y tienes una dirección del tipo "direccion@gmail.com" puedes dar tu dirección como "direccion+grupo1@gmail.com" (usuario signo-más sufijo @gmail.com)

Los correos que se envien a "direccion+grupo1@gmail.com" llegarán en tu cuenta de "direccion@gmail.com", donde puedes crear un filtro para que automáticamente se almacenen en una carpeta o se les asigne una etiqueta.

Por ejemplo, un profesor que tenga la cuenta "profegarcia@hotmail.com" puede dar a sus alumnos las direcciones "profegarcia+mate4eso2011@hotmail.com" y "profegarcia+mate2bach2011@hotmail.com", sin necesidad de crear cuentas nuevas para cada grupo.

miércoles 16 de marzo de 2011

Firefox: Enlaces mailto usando webmail (GMail, Yahoo, Hotmail...)

Si queremos que desde Firefox los enlaces que apuntan a direcciones del correo, del estilo de "mailto:direccion@servidor.com", se abra nuestro programa o cliente de webmail favorito, sólo hemos de seguir los siguientes pasos:

Vamos a Edición --> Preferencias --> Aplicaciones. Allí buscamos la línea donde dice "mailto" y cambiamos su valor a nuestro cliente de correo instalado, o nuestro proveedor de correo webmail:

Para que Hotmail aparezca seleccionable, habrá antes que haber seguido los siguientes:

1. Poner en la barra de direcciones del navegador "about:config" y buscar la línea "gecko.handlerService.allowRegisterFromDifferentHost". Cambiar el valor a "true":

2. Pegar en el navegador la siguiente línea:

javascript:window.navigator.registerProtocolHandler("mailto","http://hotmail.msn.com/secure/start?action=compose&to=%s","Hotmail")

Aparecerá una barra en la que pulsaremos en el botón "Añadir Aplicación".

3. De nuevo, poner en la barra de direcciones del navegador "about:config" y buscar la línea "gecko.handlerService.allowRegisterFromDifferentHost". Cambiar el valor a "false", como estaba al principio.

Y ya nos aparecerá Hotmail en la lista de proveedores en el menú Edición --> Preferencias --> Aplicaciones.

jueves 27 de agosto de 2009

Compartir fotos fácilmente con Picasa

Lo normal cuando se va con un grupo de amigos y se hace fotos es que luego todo el mundo quiere tener las fotos de todos, ya que son un bonito recuerdo.

Para compartir fotos hay varios métodos.

Algunas alternativas para compartir imágenes

 

Facebook

Facebook no es nada recomendable para compartir imágenes, ya que hace que las imágenes pierdan resolución (se ven más pequeñas y con menor calidad que las originales).

Además, para descargar estas fotos hay que hacerlo una a una, o utilizar algún programa del estilo del FacePAD.

Flickr

Es la página más utilizada por los profesionales de la fotografía. Sin embargo, el servicio gratuito tiene muchas limitaciones, con lo que no es muy usable para compartir imágenes.

Se pueden descargar todas las fotos de un álbum usando el programa flickrdown.

Picasa

El servicio gratuito de Picasa sólo tiene un límite, y es que sólo hay disponible 1 GB de espacio. Se puede comprar más, pero el servicio gratuito es ya muy usable.

Por esto y por lo completa y sencilla que es la aplicación Picasa, este es el método que recomiendo. Vamos a verlo en detalle.

Descargando imágenes alojadas en Picasa

Si nos han pasado la dirección de un album de fotos alojado en Picasa (http://picasaweb.google.com), hay un método muy sencillo para bajar todas esas fotos con un solo click.

Tenemos que descargar el programa gratuito Picasa e instalarlo en nuestro ordenador.

Una vez lo tengamos instalado, entramos en la página web del álbum de fotos, y pinchamos en "Descargar --> Descargar a Picasa". En la imagen aparece en inglés, pero el programa también está en español.

Se abrirá el programa Picasa, y nos aparecerá una ventanita donde tenemos que seleccionar "descargar". Entonces él solo se bajará todas las fotos del álbum.

Ahora ya tenemos todas las fotos del álbum en nuestro disco duro, pero... dónde???

En la aplicación Picasa, buscamos el álbum que hemos descargado. Pinchamos con el botón derecho del ratón y seleccionamos "localizar en disco", y se abrirá una ventana del explorador, con la carpeta que contiene las fotos descargadas.

Ahora ya podemos mover esa carpeta a donde queramos.

Compartiendo imágenes con Picasa

Para compartir imágenes con Picasa, lo primero que hay que hacer es registrarse gratuitamente en la web. Si ya tenemos un usuario de gmail, éste nos valdrá, ya que Picasa es de Google.

Tras instalar la aplicación, buscará las imágenes que tengamos en los directorios más normales, como "Mis Imágenes". Tardará un ratito, pero al final termina.

Si tenemos las fotos en otro sitio, también se pueden añadir manualmente esa ubicación. Para ello vamos al menú Archivo-->Añadir Carpeta a Picasa.

Allí buscamos la carpeta donde tenemos guardadas las fotos, y una vez seleccionada pulsamos el botón que hay a la derecha que pone "Escanear Siempre", con el icono de un ojo. Pulsamos "OK", y tardará un ratito mientras localiza las fotos que hay en esa carpeta.

La primera vez que vayamos a compartir imágenes, es recomendable configurar la calidad por defecto de las imágenes a subir en el menú de opciones, para que sólo haga falta elegirlo una vez. Para ello vamos al menú Herramientas-->Opciones.

En la pestaña álbumes web seleccionamos como tamaño por defecto "tamaño original", y pulsamos "OK".

Ahora, para compartir una serie de fotos, es tan fácil como seleccionarlas y pulsar el botón "Upload" (abajo a la izquierda, con el icono de la flecha verde hacia arriba).

Nos aparece una ventana donde nos deja elegir el nombre del álbum al que queremos que se suban las fotos, o podemos pulsar en "Nuevo" para crear un nuevo álbum.

Finalmente, una vez todos nuestros contactos hayan descargado las fotos (yo suelo dejar una semana de tiempo, o hasta que mis contactos me hayan confirmado que se han descargado las fotos), tendremos que borrar el álbum online para liberar espacio (recordad que en el servicio gratuito sólo tenemos 1 GB).

Para ello entramos en la página web de Picasaweb, entramos en el álbum que queremos borrar, y seleccionamos Edición-->Borrar Álbum.

Y ya está!! :)

Suena como un montón de pasos, pero una vez hecho un par de veces veréis lo cómodo y rápido que es.

Si tenéis alguna duda sobre alguno de los pasos, o alguna sugerencia sobre cómo hacer algo mejor, u otro método que conozcáis, podéis usar los comentarios. Gracias!

miércoles 30 de julio de 2008

Aplicaciones Java (VI): Salida de consola

A veces es conveniente poder escribir trazas para saber lo que está haciendo nuestro programa en cada momento, por ejemplo:

10:24:25 - Descargando fichero "342314.png"
10:24:29 - Descargando fichero "342315.png"
10:24:40 - Descargando fichero "342316.png"
...

En aplicaciones de consola (las que ejecutamos por línea de comandos), crear trazas de este tipo es trivial:

System.out.println("Fichero descargado");

Sin embargo, en aplicaciones gráficas no veremos el intérprete de comandos, y por tanto no podremos acceder a la salida de consola.

Una opción es escribir en un fichero de log, para lo que podemos utilizar una librería del estilo de log4j. Sin embargo, un fichero de log es más problemático para aplicaciones que queremos ejecutar desde la web, sin instalar nada, y no está integrado en el interfaz de la aplicación, sino que hay que acceder a él por separado.

Vamos a crear una clase que nos permitirá, con el mismo código, escribr trazas en stdout, o en un componente de tipo JTextArea.

Esta clase tendrá el modificador final, de modo que no será necesario instanciarla. De este modo, desde cualquier punto de nuestro programa, podremos ejecutar:

Console.println("Fichero descargado");

Que como vemos es muy sencillo y limpio.

En nuestra aplicación únicamente tendremos que crear el JTextArea y asignarlo al objeto Console.

JTextArea consoleOutput = new JTextArea(20, 40);
consoleOutput.setEditable(false);
Console.useJTextComponent(consoleOutput);

Si no reasignamos la salida de la consola a un JTextArea, la salida por defecto será stdout.

Esta es la implementación de la clase Console:

package org.dreamcoder.SwingSample;

import javax.swing.text.PlainDocument;
import javax.swing.text.JTextComponent;
import java.io.PrintStream;

public final class Console
{
 private static final long  serialVersionUID = 3;
 
 private static JTextComponent textField;
 private static PrintStream    stream = System.out; // by default we will output to stdout

    private Console()
    {
        throw new AssertionError("I am a static class. Don't instantiate me.");
    }
    
 public static void useJTextComponent(JTextComponent newTextArea)
 {
  textField = newTextArea;
 }

 public static void usePrintStream(PrintStream newStream)
 {
  stream = newStream;
 }

 public static void println(String str)
 {
        if (textField != null)
        {
            PlainDocument doc = (PlainDocument)textField.getDocument();
            
            try {
                doc.insertString(doc.getLength(), str+"\n", null);
            } catch (javax.swing.text.BadLocationException e) {}

            textField.setCaretPosition(doc.getLength());
        }
        else
        {
            stream.println(str);
        }
    }
}

Vemos en la implementación del método println que puede funcionar de 2 modos: con un stream (como System.out o un fichero, y con un componente que contenga texto). Para este último modo, obtenemos el documento (PlainDocument) correspondiente al componente, y trabajaremos con este documento. El documento es la parte del componente que contiene los datos, independientemente de la representación gráfica.

A partir de esta clase, si nuestra aplicación lo requiere podemos crear una variación que nos permita instanciar diferentes objetos de esta clase, cada uno escribiendo en un JTextArea o PrintStream diferente. Por ejemplo, podríamos tener 2 consolas distintas basadas en un JTextArea, y una tercera salida que escriba en stdout o en un fichero, socket, etc.

Material

El código fuente mostrando el uso de estos componentes se puede descargar bajo licencia GPLv3:
Download

Ejecutar ejemplo, como applet o como Java Web Start (recomendado):
Start Applet Launch via Java Web Start

jueves 24 de julio de 2008

Aplicaciones Java (V): Creación de una interfaz multiidioma

Supongamos que queremos implementar la interfaz de nuestro programa de modo que se pueda elegir el idioma. La opción que presentamos a continuación nos va a permitir implementar este cambio de idioma sin tener que hardcodear cada una de las posibles combinaciones de componentes e idiomas en el código.

La clave la tenemos en utilizar un objeto del tipo Properties. Ésta es una clase de Java que nos permitirá, por medio de su método getProperty, acceder a un fichero de texto que contiene pares propiedad - valor. El nombre de la propiedad y su valor pueden estar separados por dos puntos ":", igual "=", espacios " ", tabuladores, o una combinación de varios de estos símbolos. Veamos a continuación el fichero languages.cfg utilizado en el ejemplo. Utilizaremos este fichero desde un objeto Properties.

languages.ES.Menu.Tools:        Herramientas
languages.ES.Menu.Language:     Idioma
languages.ES.Menu.Help:         Ayuda
languages.ES.Menu.About:        Acerca de
languages.ES.Label.label:       Etiqueta
languages.ES.Button.boton:      Botón
languages.ES.Table.tabla.0:     primera columna
languages.ES.Table.tabla.1:     segunda columna
languages.ES.Table.tabla.2:     tercera columna

languages.EN.Menu.Tools:        Tools
languages.EN.Menu.Language:     Language
languages.EN.Menu.Help:         Help
languages.EN.Menu.About:        About
languages.EN.Label.label:       Label
languages.EN.Button.boton:      Button
languages.EN.Table.tabla.0:     first column
languages.EN.Table.tabla.1:     second column
languages.EN.Table.tabla.2:     third column

Observamos que para cada componente, hemos definido una propiedad para cada idioma, que sólo cambia en el segundo token (ES/EN). Esto nos permitirá implementar una función para traducir la interfaz, tal que le pasemos el idioma, y buscaremos automáticamente el conjunto de propiedades correspondientes al idioma seleccionado.

En primer lugar cargaremos el fichero con las traducciones en el objeto Properties. Intentaremos leer el fichero del filesystem (mediante FileReader), y si no encontramos el fichero, intentaremos leerlo desde dentro del fichero jar (Class.getResourceAsStream).

A continuación leeremos la propiedad correspondiente getProperty("languages."+language+"."+tipo_compomente+"."+nombre_componente), y cambiaremos ese texto en el componente correspondiente.

private void translateInterface(String language)
{
    // read the properties file that will contain the strings for every language
    
    if (languagescfg == null)
    {
        languagescfg = new Properties();

        try {
            // We will try to open the file from a resource, in case it is embedded in a jar file
            InputStream is = this.getClass().getClassLoader().getResourceAsStream("languages.cfg");
            
            if (is != null)
                languagescfg.load(new InputStreamReader(is));
            else languagescfg.load(new FileReader("languages.cfg"));
        } catch (FileNotFoundException e)
        {        
            System.err.println("File or resource \"languages.cfg\" not found");
        } catch (IOException e)
        {
            System.err.println("Error while reading file \"languages.cfg\"");
        }
    }

    // menus
    toolsmenu.setText(languagescfg.getProperty("languages."+language+".Menu.Tools"));
    languagemenu.setText(languagescfg.getProperty("languages."+language+".Menu.Language"));
    helpmenu.setText(languagescfg.getProperty("languages."+language+".Menu.Help"));
    aboutitem.setText(languagescfg.getProperty("languages."+language+".Menu.About"));
    
    // labels
    label.setText(languagescfg.getProperty("languages."+language+".Label.label"));
            
    // buttons
    boton.setText(languagescfg.getProperty("languages."+language+".Button.boton"));
    
    // Headers de tablas
    tabla.getColumnModel().getColumn(0).setHeaderValue(languagescfg.getProperty("languages."+language+".Table.tabla.0"));
    tabla.getColumnModel().getColumn(1).setHeaderValue(languagescfg.getProperty("languages."+language+".Table.tabla.1"));
    tabla.getColumnModel().getColumn(2).setHeaderValue(languagescfg.getProperty("languages."+language+".Table.tabla.2"));
}

Finalmente sólo queda llamar al método translateInterface, tanto al final de la función que genera el interfaz (para asignar inicialmente los valores por defecto), como en la escucha de los eventos que saltarán cuando el usuario seleccione el idioma correspondiente desde el menú Herramientas->Idioma.

public void generaInterfaz()
{
    // creamos los componentes deseados
    // ...
    
    // Translations of the interface
    
    translateInterface("ES");
}

public void actionPerformed(ActionEvent event)
{
    Object source = event.getSource();
    if (source.getClass().getName().equals("javax.swing.JRadioButtonMenuItem"))
    {
        if (source == languageitemES)
        {
            translateInterface("ES");
        }
        else if (source == languageitemEN)
        {
            translateInterface("EN");
        }
    }
}

Material

El código fuente mostrando el uso de estos componentes se puede descargar bajo licencia GPLv3:
Download

Ejecutar ejemplo, como applet o como Java Web Start (recomendado):
Start Applet Launch via Java Web Start