Archivo para abril, 2009

Diálogo “de detalles” JFace

Posted in CUSL3-coolImaging, Uncategorized on abril 28, 2009 by odracirnumira

Desde hace unas semanas, y sólo por curiosidad, decidimos buscar una clase de tipo Dialog del JFace o del SWT que implementara el clásico diálogo que:

  • Muestra un icono.
  • Muestra un mensaje principal.
  • Muestra un botón de “detalles”. Si dicho botón es pulsado, se expande una región, debajo del diálogo, que muestra un texto predefinible por el usuario. Esta región viene a ser un “área de detalles” donde al usuario se le puede especificar un mensaje más explicativo que el mero mensaje principal del diálogo. Si el botón de “detalles” se vuelve a pulsar, este área de detalles es colapsada.

Eclipse muestra este tipo de diálogos en múltiples ocasiones. Así por ejemplo, cuando se está ejecutando una tera de larga duración, se muestra un diálogo como el siguiente:

Diálogo de detalles colapsado

Cuando se pulsa el botón “Details >>”, el diálogo se expande, mostrando el área de detalles en cuestión:

Diálogo de detalles expandido

Por desgracia, tras diversas búsquedas, no pudimos dar con un código fuente que lo implementara. Con el deseo de ayudar a aquellos que, como nosotros, no encontraron este tipo de diálogo implementado, hemos decidido crear una clase propia que lo implemente.

Actualmente esta clase permite definir un área de detalles que está formada sólo por texto no editable. Esto, por supuesto, es una limitación, pero también es cierto que es trivial abstraer esta clase para que, en el área de detalles, se pueda mostrar cualquier tipo de contenido. Por falta de tiempo, sólo hemos implementado la clase que define un diálogo con un área de detalles de tipo textual. Esta clase, además, permite definir el tipo de icono mostrado en el diálogo. La clase, DialogoDetalles, puede ser accedida desde este link. Su aspecto es el que se muestra  a continuación:

Diálogo de detalles

El código fuente de la clase es el siguiente:


import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IconAndMessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;

import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

/**
 * <p>
 * La clase DialogoDetalles representa un diálogo emergente que muestra un
 * icono, un mensaje, y un área de detalles donde se puede mostrar texto plano.
 * <p>
 * Está clase está pensada para mostrar al usuario el clásico diálogo en el que
 * puede pulsar un botón de "detalles" para así visualizar un informe detallado
 * del mensaje transmitido por el diálogo.
 * <p>
 * Este diálogo consta de dos botones, uno de "cerrar" y otro de "detalles". El
 * botón de detalles permite hacer visible u ocultar el área de detalles del
 * diálogo. El icono visualizado en el diálogo también puede ser especificado
 * por el usuario.
 * 
 * @author L.A González Jaime
 * @author R.J Palma Durán
 */
public class DialogoDetalles extends IconAndMessageDialog{
	/*
	 * Tipo de icono a usar. Es una de las constantes ERROR,
	 * WARNING,INFORMATIO,QUESTION.
	 */
	protected int tipoIcono;
	/*
	 * Detalles del diálogo. Este texto es el mostrado en el área de detalles.
	 */
	protected String detalles;
	/*
	 * Área de texto donde se muestran los detalles.
	 */
	protected Text textoDetalles;
	/*
	 * Booleano que indica si el área de texto de los detalles (textoDetalles)
	 * está creada o no. La visualización y el ocultamiento del área de detalles
	 * se gestiona creando y destrullendo el textoDetalles. Este flag nos indica
	 * si, en efecto, el textoDetalles está o no creado.
	 */
	protected boolean textoDetallesCreado = false;
	/**
	 * Constante que indica que el icono visualizado en el diálogo es de error.
	 */
	public static final int ERROR = 0;
	/**
	 * Constante que indica que el icono visualizado en el diálogo es de
	 * advertencia.
	 */
	public static final int WARNING = 1;
	/**
	 * Constante que indica que el icono visualizado en el diálogo es de
	 * información.
	 */
	public static final int INFORMATION = 2;
	/**
	 * Constante que indica que el icono visualizado en el diálogo es de
	 * pregunta.
	 */
	public static final int QUESTION = 3;
	/*
	 * Botón que permite mostrar y ocultar los detalles del diálogo.
	 */
	protected Button botonDetalles;
	/*
	 * Título del diálogo.
	 */
	protected String titulo;

	/**
	 * Cosntruye un DialogoDetalles. El estilo del diálogo creado (el estilo de
	 * la shell) es
	 * <code>SWT.CLOSE | SWT.RESIZE | SWT.MAX | SWT.MODELESS</code>.
	 * 
	 * @param titulo título del diálogo.
	 * @param mensaje mensaje principal mostrado en el diálogo.
	 * @param detalles texto que se muestra en el área de detalles.
	 * @param tipoIcono tipo de icono a mostrar en el diálogo. Puede ser alguna de las constantes
	 * <code>DialogoDetalles.ERROR</code>, <code>DialogoDetalles.WARNING</code>, <code>DialogoDetalles.INFORMATION</code>
	 * , <code>DialogoDetalles.QUESTION</code>.
	 * @param parentShell la Shell padre de este diálogo. Si es null, se creará una shell de alto nivel.
	 */
	public DialogoDetalles(String titulo, String mensaje, String detalles, int tipoIcono, Shell parentShell){
		this(titulo,mensaje,detalles,tipoIcono,parentShell,SWT.CLOSE | SWT.RESIZE | SWT.MAX | SWT.MODELESS);
	}

	/**
	 * Cosntruye un DialogoDetalles. Permite crear el estilo (estilo de la Shell) del
	 * diálogo creado.
	 * 
	 * @param titulo título del diálogo.
	 * @param mensaje mensaje principal mostrado en el diálogo.
	 * @param detalles texto que se muestra en el área de detalles.
	 * @param tipoIcono tipo de icono a mostrar en el diálogo. Puede ser alguna de las constantes
	 * <code>DialogoDetalles.ERROR</code>, <code>DialogoDetalles.WARNING</code>, <code>DialogoDetalles.INFORMATION</code>
	 * , <code>DialogoDetalles.QUESTION</code>.
	 * @param parentShell la Shell padre de este diálogo. Si es null, se creará una shell de alto nivel.
	 * @param estiloShell el estilo de la Shell del diálogo.
	 */
	public DialogoDetalles(String titulo, String mensaje, String detalles, int tipoIcono, Shell parentShell,
			int estiloShell){
		super(parentShell);
		if(mensaje == null){
			throw new IllegalArgumentException("The input message cannot be null");
		}
		this.message = mensaje;
		if(tipoIcono < 0 || tipoIcono > 3){
			throw new IllegalArgumentException("Invalid image type");
		}
		if(detalles == null){
			throw new IllegalArgumentException("Details cannot be null");
		}
		if(titulo == null){
			throw new IllegalArgumentException("Title cannot be null");
		}
		this.detalles = detalles;
		this.tipoIcono = tipoIcono;
		this.titulo = titulo;
		this.setBlockOnOpen(false);
		this.setShellStyle(estiloShell);
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	protected Control createDialogArea(Composite parent){
		return createMessageArea(parent);
	}

	/*
	 * (non-Javadoc)
	 * @see
	 * org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse
	 * .swt.widgets.Composite)
	 */
	protected void createButtonsForButtonBar(Composite parent){
		createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, true);
		this.botonDetalles = createButton(parent, IDialogConstants.DETAILS_ID, IDialogConstants.SHOW_DETAILS_LABEL,
				false);
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
	 */
	protected void buttonPressed(int buttonId){
		if(buttonId == IDialogConstants.DETAILS_ID){
			/*
			 * Si se ha pulsado el botón de "detalles", se debe mostrar u ocultar el área de
			 * detalles, dependiendo de que estuviera o no oculta. Además, tras ocultar el
			 * área o visualizarla, se debe redimensionar el diálogo, para que así se ajuste
			 * al nuevo tamaño provocado por la aparición o desaparición del área de detalles.
			 */
			Point dimensionAnteriorDialogo = getShell().getSize();
			if(this.textoDetallesCreado){
				/*
				 * Si el área de texto está actualmente siendo mostrada, la eliminamos. Además,
				 * cambiamos la etiqueta del botón de "mostrar detalles".
				 */
				this.botonDetalles.setText(IDialogConstants.SHOW_DETAILS_LABEL);
				this.textoDetalles.dispose();
			}
			else{
				/*
				 * Si el área de texto actualmente no está siendo visualizada, la mostramos. Para
				 * ello, iniciamos a this.textoDetalles. Además, debemos cambiar la etiqueta
				 * del botón de "mostrar detalles". 
				 */
				this.botonDetalles.setText(IDialogConstants.HIDE_DETAILS_LABEL);
				this.textoDetalles = new Text((Composite)getContents(), SWT.BORDER | SWT.READ_ONLY | SWT.MULTI
						| SWT.WRAP | SWT.H_SCROLL | SWT.V_SCROLL);
				this.textoDetalles.setText(this.detalles);
				GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
				this.textoDetalles.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
				data.horizontalSpan = 2;
				this.textoDetalles.setLayoutData(data);
			}
			getContents().getShell().layout();
			this.textoDetallesCreado = !this.textoDetallesCreado;
			
			/*
			 * Se redimensiona el diálogo.
			 */
			Point dimensionNuevaDialogo = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
			int altoPantalla = Display.getCurrent().getClientArea().height;
			getShell().setSize(new Point(dimensionAnteriorDialogo.x, Math.min(dimensionNuevaDialogo.y, altoPantalla)));
		}
		else{
			/*
			 * Si se pulsa el botón de "cerrar", cerramos la ventana.
			 */
			close();
		}
		setReturnCode(buttonId);
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.IconAndMessageDialog#getImage()
	 */
	protected Image getImage(){
		switch(this.tipoIcono){
			case ERROR:
				return getErrorImage();
			case WARNING:
				return getWarningImage();
			case INFORMATION:
				return getInfoImage();
			case QUESTION:
				return getQuestionImage();
			default:
				throw new RuntimeException("Invalid image type");
		}
	}

	/*
	 * (non-Javadoc)
	 * @see
	 * org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets
	 * .Shell)
	 */
	protected void configureShell(Shell shell){
		super.configureShell(shell);
		// Título del diálogo
		shell.setText(this.titulo);
	}
}

Cool Imaging Project ampliando Horizontes

Posted in CUSL3-coolImaging on abril 27, 2009 by luisette

Hoy hemos recibido dos buenas noticias. Por un lado, se ha publicado el artículo que escribimos para Linux Magazine; y por otro, estamos tramitando la colaboración del Servicio de Traducción Universitario (STU) de la Universidad de Granada con Cool Imaging Project para la traducción de la aplicación a varios idiomas.

Si todo sale bien, daremos nuestra aplicación a conocer en las jornadas de traductores del próximo 15 de Mayo.

Finalistas del CUSL granadino

Posted in CUSL3-coolImaging on abril 17, 2009 by odracirnumira

Ayer por la mañana tuvo lugar la final del Concurso Universitario de Software Libre (CUSL) granadino, en la facultad de informática y telecomunicaciones de la Universidad de Granada.

Los resultados ya han sido publicados en la página oficial del concurso. Para nosotros, los resultados han sido bastante positivos. Teniendo en cuenta que en un concurso así se compite con otros tantos proyectos que han requerido un gran esfuerzo y trabajo por parte de sus autores, el haber quedado finalistas  (segundos) es, sin duda, una gran noticia para nosotros.

Queremos dar nuestro agradecimiento a todas las personas que, de un modo u otro, han colaborado con nuestro proyecto, incluyendo a:

  • Joaquín Fernández Valdivia, director del proyecto, y que siempre nos ha apoyado en todo lo que hemos hecho.
  • José Francisco Mantas, creador del logo de Cool Imaging.
  • María Civantos Hueso, creadora de algunos iconos de la aplicación así como evaluadora contínua del proyecto.
  • Raúl Jiménez Ortega, evaluador continuo del proyecto.
  • David Castellanos Serrano, que nos dió unas muy útiles referencias acerca de Eclipse, y que nos mostró que, en el mundo de este entorno de desarrollo, no estábamos solos.

A todos ellos, gracias.

También queremos dar la enhorabuena al ganador, Fabian, que, por desgracia, no pudo asistir a la final y presentarnos su proyecto. Por suerte, algunos de nosotros sí pudimos verlo en la presentación del proyecto, allá en marzo.

Enviamos también un saludo a todos los participantes del concurso, que, sin duda, han llevado a cabo una importante labor contribuyendo al desarrollo del software libre.

Procesamiento de paquetes de imágenes

Posted in CUSL3-coolImaging on abril 15, 2009 by odracirnumira

Tomando la sugerencia que jbelon hizo en una entrada anterior, hemos implementado un nuevo menú que permite llevar a cabo procesmiento de paquetes de imágenes.

La idea es que el usuario pueda definir paquetes de imágenes y cadenas de operaciones.

Un paquete de imágenes no es más que un conjunto de imágenes especificado por el usuario: el usuario puede, fácilmente, crear paquetes de imágenes.

Crear un paquete de imágenes es trivial, y se puede hacer a través de la vista Paquetes de Imagenes. Esta vista ofrece funcionalidad adicional para poder insertar cualesquiera imágenes en uno o varios paquetes de imágenes.

Creando un paquete de imágenes

Una cadena de operaciones es una serie ordenada de operaciones de tratamiento de imágenes. Por ejemplo, el usuario puede crear una cadena de operaciones formada por una rotación, seguida de un filtrado gaussiano y seguida de una exponenciación.

Definir una cadena de operaciones se bien sencillo: basta crear una cadena en la vista de Cadenas de Operaciones.

Creando una cadena de operaciones

Creada la cadena de operaciones, toda operación puede insertarse en ella, lo cual puede hacerse directamente sobre el panel de cada operación.

Definiendo una cadena de operaciones

Definida la cadena de operaciones, el usuario puede seleccionar un paquete o paquetes de imágenes a los que aplicarla, todo ello en la vista Cadenas de Operaciones. Dicha vista permite, finalmente, lanzar un diálogo de configuración de la ejecución de las cadenas de operaciones, y, posteriormente, ejecutarlas.

Configurando la ejecución de cadenas de operaciones

Nueva versión de los ejecutables (con manual de ayuda y plugins de operaciones)

Posted in CUSL3-coolImaging on abril 8, 2009 by luisette

Hola a tod@s,

Pues simplemente decir que hemos generado unos nuevos ejecutables de la aplicación (versión 1.0.1).

Estos incluyen dos grandes diferencias (además de nuevas operaciones para la caracterización):

  • Parte del manual de ayuda (aunque esperamos tener terminado lo principal en un par de días)
  • Extensión mediantes plugins.

¿Que quiere decir extensión mediante plugins? Pues que ahora nuestra aplicación la tenemos dividida en componentes (plugins). En concreto cuatro (por ahora):

  • com.coolimagingproject.coolimaging (la aplicación principal)
  • com.coolimagingproject.colorOperations (Operaciones para cambio de espacios de color)
  • com.coolimagingproject.basicImageProcessingOperations (Operaciones basicas de tratamiento de imágenes)
  • com.coolimagingproject.help (manual de ayuda)

Estos componentes se encuentran en la carpeta plugins dentro de la carpeta coolimaging.

¿Que ventaja aporta esto? Pues una vez terminada la aplicación principal podemos implementar nuevas operaciones sin tener que tocar la aplicación principal. Incluso mejor, un usuario con conocimientos de programación puede añadir nuevas operaciones sin saber nada de nuestra aplicación. U otras, como que cuando terminemos el manual de ayuda solo habrá que sustituir el plugin com.coolimagingproject.help por el nuevo que generemos, sin tener que volver a generar todo el ejecutable.

Para poder descargarlos aquí.

Adquirido dominio coolimagingproject.com

Posted in CUSL3-coolImaging on abril 2, 2009 by luisette

Pues ya tenemos el dominio coolimagingproject.com, ahora empezaremos a subir material y a elaborar una página donde tener todo lo relacionado con el proyecto.