jueves, 30 de octubre de 2014

Uso de comillas angulares en Word


En la notación UML, los estereotipos se definen con su nombre entre comillas angulares (o francesas, o latinas, o guillemets): «Estereotipo».

Como estas comillas no aparecen en los teclados, es habitual utilizar dos signos de mayor o menor para sustituirlas (<< y >>), pero sí que podemos escribirlas mediante la combinación de teclas alt + 174 y alt + 175, respectivamente.
Si tenemos un documento Word en el que hemos utilizado << y >>, y queremos reemplazarlos por los caracteres « y », podemos tener problemas con las opciones de autocorrección. Lo habitual si usamos la opción reemplazar, es que Word utilice las comillas tipográficas o inglesas. Para evitar este comportamiento, podemos acceder a las opciones de Word (Archivo - Opciones, en Word 2010), al apartado Revisión, y abrir el cuadro de configuración Opciones de Autocorrección. En las pestañas Autoformato y Autoformato mientras escribe, se debe desmarcar la opción Comillas rectas como comillas tipográficas.
De esta forma, si usamos la opción de reemplazar con los caracteres « y », Word los respetará.

jueves, 13 de marzo de 2014

ArtifactTransferException: Failure to transfer

Al crear un proyecto con Maven en Eclipse, me encontré que el pom.xml marcaba montones de errores del tipo:

ArtifactTransferException: Failure to transfer...

La solución al problema la encontré rápidamente en stackoverflow. Basta con eliminar todos los ficheros con extensión lastUpdated del repositorio maven, y actualizar el proyecto. Lo primero lo puedes hacer con los comandos:

cd %userprofile%\.m2\repository
for /r %i in (*.lastUpdated) do del %i

Y luego basta con ir a Eclipse y, sobre el proyecto, seleccionar Maven - Update project, y aceptar el diálogo.

jueves, 27 de febrero de 2014

Escribiendo un log

Podemos añadir un fichero de log a nuestra aplicación Java muy fácilmente utilizando la clase Logger.

1
2
3
4
5
FileHandler fh = new FileHandler("Log.log");
Logger logger = Logger.getLogger("TestLog");
logger.addHandler(fh);
SimpleFormatter formatter = new SimpleFormatter();
fh.setFormatter(formatter); 

Con este código creamos el Logger, y podemos añadir mensajes con la sentencia:

1
logger.info("Mensaje de log");

Este tipo de mensajes incluye información sobre la fecha, clase y método en que se está escribiendo el log. En general esta información es muy útil, pero si quieres escribir un log con muchas entradas, y vas a tener que procesarlas, puede que prefieras que no aparezca. Si es así, puedes crear tu propio formateador extendiendo de la clase Formatter.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class MySimpleFormatter extends Formatter 
{   
    public MySimpleFormatter() { 
        super(); 
    }

    @Override 
    public String format(final LogRecord record) 
    {
        return record.getMessage();
    }   
}

Basta con cambiar el SimpleFormatter estándar por el nuestro, y ya tendremos los mensajes a nuestro gusto.

Por supuesto, podemos modificar el método format para configurar la información del log como queramos.

miércoles, 10 de julio de 2013

Referencia a la clase contenedora en una clase anónima

Al programar interfaces gráficas, es muy habitual el uso de clases anónimas para definir el listener de algún componente.

JButton button = new JButton("OK");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
   System.out.println("Ok!");
}});      
 
Tampoco es raro que desde la clase anónima, queramos acceder a algún elemento de la clase contenedora. En ese caso, podemos vernos tentados de usar this; pero, obviamente, si estamos dentro de la clase anónima, this hará referencia a la instancia de esa clase, no a la de la contenedora.

En este caso podemos usar como alternativa ClaseContenedor.this, quedando algo así.

public class ClaseContenedora extends JPanel{
   int value = 0;

   public ClaseContenedora() {
      ...

      JButton button = new JButton("OK");
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e)
         {
            ClaseContenedora.this.value++;
         }});    

      ...
   } 
}

domingo, 7 de julio de 2013

Un único Toast en Android

Los Toasts de Android son una opción muy socorrida cuando se quieren mostrar mensajes al usuario sin molestar demasiado. Por ejemplo, cada vez que el usuario modifica una opción de la aplicación.

Los Toast se pueden crear mediante la llamada:

Toast.makeText(context, context.getString(id), Toast.LENGTH_SHORT)

El último parámetro indica el tiempo durante el que el Toast será visible en pantalla, y generalmente se usan las contastes LENGTH_SHORT y LENGTH_LONG de la propia clase Toast para darle valor.

Hasta aquí todo muy bien, pero un problema habitual se produce cuando se quieren mostrar varios Toast de forma consecutiva. En ese caso el sistema encola los Toast, y cada uno se va mostrando cuando desaparece el anterior. Esto implica que, seguramente, el usuario esté viendo en pantalla un mensaje correspondiente a una acción que no es la última que ha realizado.

Ante esto, yo prefiero la opción de que cada nuevo Toast se presente inmediatamente en pantalla, haciendo desaparecer al anterior. Así, adaptamos la información mostrada al ritmo al que el usuario utiliza la aplicación.

Viendo el API de la clase Toast, parece que la opción más lógica para conseguir esto es utilizar el método cancel. Pero la verdad es que por lo que lo he podido probar, no siempre da el resultado esperado.

Así que la solución que me he planteado es hacer una especie de Singleton sobre los Toast. La idea es que sólo exista un Toast en mi aplicación; así, cada vez que tengo que mostrar un mensaje, en lugar de crear una nueva instancia, que acabaría encolada si había otras anteriores, cojo mi única instancia, le cambio el texto, y la vuelvo a mostrar.

El resultado es una clase tal que así.

public class Toasts {

private static Toast myToast = null;

public static void showToast(Context context, int id) {
if (myToast != null) {
myToast.setText(context.getString(id));
} else {
myToast = Toast.makeText(context, context.getString(id),
Toast.LENGTH_SHORT);
}
myToast.show();
}
}

Esta clase puedo usarla de forma sencilla desde cualquier actividad de mi aplicación, simplificando además la  llamada al necesitar sólo el contexto y el texto.

Toasts.showToast(this, R.string.text);

Una posible mejora sería crear un segundo método que permitiese especificar también la duración del Toast, pero eso ya depende de las necesidades de cada uno.