Difference between revisions of "User talk:Gerardo GR"

From Apache OpenOffice Wiki
Jump to: navigation, search
(Mejorando la GUI en UNO AWT de la extension gdocs: new section)
(Mejorando la GUI en UNO AWT de la extension gdocs)
Line 750: Line 750:
 
== Mejorando la GUI en UNO AWT de la extension gdocs ==
 
== Mejorando la GUI en UNO AWT de la extension gdocs ==
  
La actividad que realize el dia de hoy, fue a igualar la funcionalidad que tienens las ventanas de la extension gdocs (java Swing) al equivalente. Empeze con la ventana WaitWindow, esta ventana tuvo que ser rehecha, debido a que como la tenia antes, un MessageBox, no me permitia llamarla cuando se le necesite, debido a que necesitaba de un padre que la llame, es por eso que la converti en un Dialog tal cual, el cual corrige el problema de los llamados. Tambien termine de implementar sus Listeners. La siguiente ventana con la que segui su implementación fue la de ConfigDialog, esta me llevo a rediseñar la GUI, debido a que uno de los campos (el de seleccionar el LookAndFeel) ya no estara disponible para esta version, esto se debe a que no hay tal cosa como el LookAndFeel en UNO AWT. Tambien es en esta etapa en la que los campos que requieran enmascaramiento de caracteres (campos de password) seran implementados, lo cual seguira la siguiente actividad al igual que seguir con la completación de los listeners.
+
La actividad que realize el dia de hoy, fue a igualar la funcionalidad que tienens las ventanas de la extension gdocs (java Swing) al equivalente. Empeze con la ventana WaitWindow, esta ventana tuvo que ser rehecha, debido a que como la tenia antes, un MessageBox, no me permitia llamarla cuando se le necesite, debido a que necesitaba de un padre que la llame, es por eso que la converti en un Dialog tal cual, el cual corrige el problema de los llamados. Tambien termine de implementar sus Listeners. La siguiente ventana con la que segui su implementación fue la de ConfigDialog, esta me llevo a rediseñar la GUI, debido a que uno de los campos (el de seleccionar el LookAndFeel) ya no estara disponible para esta version, esto se debe a que no hay tal cosa como el LookAndFeel en UNO AWT. Tambien es en esta etapa en la que los campos que requieran enmascaramiento de caracteres (campos de password) seran implementados, lo cual seguira la siguiente actividad al igual que seguir con la completación de los listeners.<br />
 +
Al principio en la implementación de la funcionalidad me costo un poco trabajo saber por donde empezar lo cual me llevo algo de tiempo, pero una vez establecido en que ventana me enfoque, resulta mas agil el avanze.

Revision as of 03:10, 29 September 2011

Mi primer post en esta simulación de bitacora.

Primeros pasos

La primer actividad que estoy realizando como practicante del proyecto OpenOffice es conseguir OpenOffice y las herramientas necesarias para desarrollar extensiones (en la plataforma de desarrollo eclipse).

Instalando las herramientas

Ya he instalado exitosamente openoffice, de hecho cree un script para instalarlo en slackware y lo subi en una pagina que se dedica a distribuir esos scripts. Tambien he instalado el SDK de openoffice. Por ultimo termine de instalar el plug-in de eclipse para desarrollar aplicaciones con UNO para openoffice. Para instalar este plug-in segui esta guia, la recomiendo es util para llevar acabo esta tarea.
Despues de haber realizado la tarea de preparar el entorno de desarrollo (SDK,plug-in, etc), me preparo para correr algun ejemplo, el que he realizado con exito fue el del link mencionado anteriormente. El unico inconveniente que tuve, fue que al añadir una libreria externa, y correr la aplicación en openoffice a traves de un macro, me produjo la exepción de que no se encuentra la clase de la libreria añadida. Al finalizar el dia, me dedique a leer la guía de desarrolladores.

Conociendo la API de OpenOffice

El dia de hoy (01 de septiembre del 2011), lei la documentación acerca de la API de OpenOffice. Lo que aprendi es que utiliza un lenguaje llamado UNO que funciona como una interfaz entre los lenguajes de programación, entre ellos c++, basic y java. Por lo mismo que UNO funciona como interfaz, este tiene muchas interfaces que permiten el manejo de los objetos de openoffice.
Al mismo tiempo que iba leiendo la documentación, corri los programas de ejemplo y los analize. Uno de los ejemplos que corri, fue el siguiente, con este programa de ejemplo, tambien aprendi a como configurar el IDE eclipse para utilizar el SDK de openoffice y a configurar el build.xml (ant) para compilar diferentes programas, le hice unas pequeñas modificaciones para poder tener un script mas flexible. El cual quedo de la siguiente manera:

<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." default="all" name="FirstLoadComponent">
 
	<!-- The following build script works with a standard installation of OpenOffice 3.0.1
	     and OpenOffice SDK 3.0.1 as described in section >Linux RPM-based Installation< 
	     of the document found at http://download.openoffice.org/common/instructions.html. -->
 
	<!-- This script is tested with the Eclipse IDE and stand-alone, without any IDE support. -->
 
	<!-- Paths based on the standard installation of OOo 3.0.1 and OOo SDK 3.0.1 on unix -->
	<property name="OFFICE_ROOT" value="/opt/openoffice.org" />
	<property name="OFFICE_HOME" value="${OFFICE_ROOT}/basis3.3" />
	<property name="OO_SDK_HOME" value="${OFFICE_HOME}/sdk" />
	<property name="OO_URE_HOME" value="${OFFICE_ROOT}/ure" />
 
	<target name="init">
		<property name="OUT_DIR" value="${basedir}/build/Example/" />
		<!-- For eclipse we need to set the output folder to this path -->
		<property name="BIN_DIR" value="${basedir}/bin/" />
 
		<!-- This variables help to have a more flexible build.xml.
			 APP_CLASS: name of the class.
			 OUT_JAR: name of the generated jar file.
			 PKG_NAME: name of the package tree we have in Eclipse -->
		<property name="APP_CLASS" value="FirstLoadComponent" />
		<property name="OUT_JAR" value="${APP_CLASS}.jar" />
		<property name="PKG_NAME" value="Example" />
	</target>
 
	<path id="office.class.path">
		<filelist dir="${OFFICE_HOME}/program/classes" files="unoil.jar" />
		<filelist dir="${OO_URE_HOME}/share/java" files="jurt.jar,ridl.jar,juh.jar" />
	</path>
 
	<fileset id="bootstrap.glue.code" dir="${OO_SDK_HOME}/classes">
		<patternset>
			<include name="com/sun/star/lib/loader/*.class" />
		</patternset>
	</fileset>
 
	<!-- Since the Eclipse IDE has an incremental compiler build in we do not need
	     to run the >compile< target in this case -->
	<target name="compile" depends="init" unless="eclipse.running">
		<mkdir dir="${BIN_DIR}" />
		<javac debug="true" deprecation="true" destdir="${BIN_DIR}" srcdir=".">
			<classpath refid="office.class.path" />
		</javac>
	</target>
 
	<target name="jar" depends="init,compile">
		<mkdir dir="${OUT_DIR}" />
		<jar basedir="${BIN_DIR}" compress="true" jarfile="${OUT_DIR}/${OUT_JAR}">
			<exclude name="**/*.java" />
			<exclude name="*.jar" />
			<fileset refid="bootstrap.glue.code" />
			<manifest>
				<attribute name="Main-Class" value="com.sun.star.lib.loader.Loader" />
				<section name="com/sun/star/lib/loader/Loader.class">
					<attribute name="Application-Class" value="${PKG_NAME}.${APP_CLASS}" />
				</section>
			</manifest>
		</jar>
	</target>
 
	<target name="all" description="Build everything." depends="init,compile,jar">
		<echo message="Application built. ${APP_CLASS}!" />
	</target>
 
	<target name="run" description="Try running it." depends="all">
		<java jar="${OUT_DIR}/${OUT_JAR}" failonerror="true" fork="true">
		</java>
	</target>
 
	<target name="cleanbin" description="Clean all binaries." unless="eclipse.running">
		<delete>
			<fileset dir="${BIN_DIR}">
				<include name="**/*.class" />
			</fileset>
		</delete>
	</target>
 
	<target name="cleanall" description="Clean all build products." depends="init,cleanbin">
		<delete file="${OUT_DIR}/${OUT_JAR}" />
	</target>
 
</project>

Archivos de propiedades de las extensiones

Le llamo archivos de propiedades de extensiones aquellos archivos xml que describen las propiedades de la extension, como son el nombre de la extension, la liga de donde se descargara una version actualizada, etc. Toda esta información le servira a la gestor de extensiones para poder realizar cierta funcionalidad, como el despligue de la licencia, o la actialización de la extension. Estos archivos son realativamente sencillos de entender y considero que para poder poner en practica este nuevo conocimiento lo mejor es empezar a leer bien codigos de ejemplo. El haber leido esa información me permitio entender mejor como se manejan las extensiones y que tipo de archivos son necesarios. Ahora me dispongo a analizar codigo de extensiones existentes para seguir con mi avance en las practicas.

Creando interfaces graficas con UNO (parte 1)

He aprendido que UNO proporciona interfaces para el despliegue de interfaces graficas apartir de una libreria parecida a AWT de java. Esta libreria AWT de UNO nos permite manipular cada objeto grafico cambiando sus propiedades, agregando eventos, etc. Para poder instanciar algun elemento grafico que creamos, es necesario crearlo apartir de un contexto, que por lo general es de alguna instancia de algun programa de openoffice, si no existiese alguna instancia de openoffice en ejecución, se puede crear una y trabajar en ella.
Es importante destacar, que no es necesario utilizar esta libreria de UNO, se puede utilizar la libreria AWT de java, o se puede utilizar una combinaciń de ambas, lo importante de hacer uso de la de UNO, es que nos permitira la independencia del lenguaje de programación, y asi comunicar varios lenguajes de programación, de ser necesario. Template:Insert template

Creando interfaces graficas con UNO (parte 2)

Lo interesante de utilizar la libreria AWT que proporciona UNO, es que esta se incorpora de manera nativa a OpenOffice, lo que permite gestionar información de los documentos o elementos en su interior de mejor manera. Mucho del trabajo de las GUIs es bastante sencillo, se utilizan una serie de interfaces, como la de XComponentContext que nos permite obtener la instancia de OpenOffice que se encuentra en ejecución, para al final terminar con un objeto grafico que deseemos instanciar o utilizar.
Para poder realizar mejor las GUIs de las extensiones, he optado por utilizar el IDE netbeans, debido a que tiene un soporte mas completo para el desarrollo de extensiones (en comparación a eclipse), el cual simplifica mucho del trabajo necesario.

Creando interfaces graficas con UNO (parte 3)

Uno de los archivos mas importantes para las GUIs de UNO es el Addons.xcu, pues es el que describe cuales son los componentes de una extension. Entre los campos mas importantes estan de este archivo estan:

  • Tipo de componente (boton, campo de edición, combobox, etc)
  • Nombre del componente
  • Comando con el que se relaciona
  • y hasta un notificador del cambio de estado.

Lo importante de estos archivos no es aprenderse totalmente la sintaxis, sino saber para que sirve cada uno de estos campos y saber (en caso de que el IDE no lo proporcione), cual cambiar para que se lleve acabo algun cambio en la presentación de la extension.

Luego de haber discutido con Alexandro (mi asesor de practicas profesionales) el codigo de gdocs, entendi que el uso de la libreria AWT de java debe ser usada en la menor medida posible, y esto es lógico debido a que nos limitaria al lenguaje de programación java, iendo asi en contra de la filosofia de UNO, que es la de proporcionar una serie de interfaces independientes del lenguaje que nos permiten interactuar con el programa OpenOffice. Asi que de esta manera me he propuesto replantear la manera de crear una GUI apartir de la AWT de UNO.

Lectura de codigo de ejemplo

Hasta el momento, he terminado de entender el codigo de la extension gdocs. Al tratar de entender por completo el codigo, me he tardado mas tiempo de lo esperado, sin embargo el haber leido este codigo me permitio entender mejor la logica que se maneja en el desarrollo de extensiones. Tambien me percate que este codigo tiene una gran deficiencia, utiliza la libreria AWT de java, y no la de UNO, esto es un problema porque que la GUI se vuelve dependiente del lenguaje en que se programo y tambien genera un mayor gasto en recursos. Entonces mi siguiente actividad, despues de haber terminado de entender el codigo, es realizarle alguna modificación, que en este caso sera migrar la GUI de java a la GUI de UNO.
En las previas entradas de esta bitacora hable del desarrollo de la GUI en UNO, hasta ejecute una serie de programas de ejemplo que vienen en los tutoriales, lo cual me dio una muy buena idea de como utilzarla, pero ahora el reto sera utilizarla por mi mismo manipulando los diferentes componentes para que realizen lo que se desea.

Ordenando el area de trabajo para las modificaciones a la extension gdocs

La actividad que realize por el momento con la extension gdocs, fue establecer el area de trabajo en el IDE para poder compilar y realizar el despligue de la extension en OpenOffice.
Empeze a realizar pruebas con los codigos de ejemplo que vienen en el wiki del desarrollo de GUI con UNO.

Jugando con la GUI que proporciona UNO

Actividades:

  • Crear un dialogo, configurar, y desplegar un dialogo.
  • Agregarle XEventListeners.
  • Agregarle al dialogo controles como: botones y campos de texto.

En base al conocimiento adquirido apartir de estas actividades realize unas clases que me permiten manipular de mejor manera los componentes de la GUI, un poco mas al estilo de Swing, pero sin tanta complejidad, solamente para realizar el trabajo. Tengo pensado que con estas clases, se pueda facilitar el trabajo del cambio de la GUI de la extension gdocs.

GUI de gdocs convertida a GUI de UNO

Los componentes de la GUI de la extensión gdocs que ya "traduje" a componentes de GUI de UNO son:

  • WaitWindow
  • UploadDialog

Me di cuenta que en realidad como mi tarea no es concentrarme en el desarrollo de una libreria para facilitar el trabajo del desarrollo de GUI en UNO, entonces dedicare completamente a terminar la conversion de la GUI de esta extension, obviamente utilizando almenos la "sublibreria" con la que cuento para poder facilitarme el trabajo, pero siempre teniendo en cuenta cual es mi objetivo.

Probando mi trabajo anterior y buscando un GUI Builder para UNO de OpenOffice.org

El dia de hoy, me dedique a probar la GUI que ya habia terminado, el frame UploadDialog, el cual a primera vista parece terminado, la funcionalidad de los actionlistener funciona sin problemas, no hay incongruencias en el renderizado de la imagen, etc. Sin embargo me hace falta realizar mas pruebas con mas ventanas, para determinar la viabilidad del uso de mi sublibreria.
Una actividad importante que realize, fue el buscar un GUI Builder orientado a la tecnologia de UNO, desgraciadamente, no existe como tal un proyecto asi, pero mientras buscaba esta herramienta encontre que habia una propuesta del SOD 2008, para una herramienta como la que me hace falta. Luego al continuar con mi busqueda encontre que hay un TODO list de esta propuesta, es por esto que le envie un correo al encargado de dicho proyecto para averiguar cual es el estado actual del proyecto. Por ahora lo que me queda es esperar la respuesta, y seguir con mi desarrollo habitual (la conversion de la GUI de gdocs que se encuentra desarrollada en SWING a una GUI hecha en UNO).

3 Nuevas ventanas creadas

Estas 3 nuevas ventanas que cree, estan completamente hechas en UNO, estas podrian ser las ventanas que replazaran a las creadas en java swing de la extension gdocs. A continuación mostrare unas impresiones de pantalla de las ventanas de gdocs en comparación a las que cree.


NOTA: los nombres de las ventanas son en base a los que aparecen en el codigo fuente.
La primer ventana que mostrare es la que se llama UploadDialog.
UploadDialog.jpg
Y esta es el equivalente creado en UNO
UploadDialogUNO.jpg

Esta siguiente ventana se llama Uploading
Uploading.jpg
He aqui su equivalente
UploadingUNO.jpg
Por lo que se ve en el equivalente de la ventana Uploading, la "ProgressBar" no aparece, he hecho varios intentos para hacer aparecer la "ProgressBar" de UNO sin algun exito, probablemente sea un error en la implementación del servicio UnoControlProgressBarModel o la integración de este control al Dialog. A pesar de esto utilize un equivalente que sirve para el proposito, mostrar el progreso.

La ultima ventana de la que he creado su equivalente es la ServersManager
ServersManager.jpg
Su equivalente en UNO es esta
ServersManagerUNO.jpg

El equivalente de ServersManager en UNO utiliza un campo de texto en vez de un JList (de swing), todavia no he encontrado el equivalente de ese componente de swing en UNO.
Ahora mostrare el codigo que utilize para crear esta GUI, solamente mostrare el codigo de las clases mas significativas como los ancestros comunes, y 2 ejemplos de las implementaciones, como la creación del frame y los controles como un boton y un campo de texto.
La Clase SimpleDialog

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
 
package util;
 
/* Omitire los imports
 */
 
/**
 *
 * @author gerhard
 */
public class SimpleDialog {
 
    protected XComponentContext xComponentContext = null;
    protected XMultiComponentFactory xMCF = null;
 
    // contenedores de los controles del dialogo
    protected XNameContainer xNameContainer = null;
    protected XControlContainer xControlContainer = null;
 
    protected XMultiServiceFactory xMSF = null;
 
    // la ventana, representada por un contorl
    protected XControl xControl = null;
 
    protected XTopWindow xTopWindow = null;
    protected XWindowPeer xWindowPeer = null;
 
    // Constructor de la clase
    public SimpleDialog(XComponentContext xComponentContext, XMultiComponentFactory xMCF,String[] properties, Object[] values) throws Exception{
        // inicilizamos los parametros princiaples.
        this.initilize(xComponentContext, xMCF);
        // Establecemos las propiedades del dialogo, como el tamaño de la ventana
        // el nombre de la ventana, etc.
        this.setProperties(properties,values);
    }
 
    private void initilize(XComponentContext xComponentContext,XMultiComponentFactory xMCF) throws Exception{
        this.xComponentContext = xComponentContext;
        this.xMCF = xMCF;
        Object dialogModel = this.xMCF.createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel", this.xComponentContext);
        this.xMSF = (XMultiServiceFactory) UnoRuntime.queryInterface(XMultiServiceFactory.class, dialogModel);
        this.xNameContainer = (XNameContainer) UnoRuntime.queryInterface(XNameContainer.class, dialogModel);
        Object unoDialog = this.xMCF.createInstanceWithContext("com.sun.star.awt.UnoControlDialog", this.xComponentContext);
        this.xControl = (XControl) UnoRuntime.queryInterface(XControl.class, unoDialog);
        this.xControlContainer = (XControlContainer) UnoRuntime.queryInterface(XControlContainer.class, unoDialog);
        this.xTopWindow = (XTopWindow) UnoRuntime.queryInterface(XTopWindow.class, xControlContainer);
        XControlModel xControlModel = (XControlModel) UnoRuntime.queryInterface(XControlModel.class, dialogModel);
        this.xControl.setModel(xControlModel);        
    }
 
    private void setProperties(String[] properties, Object[] values){
        try{
            // establecemos las propiedades de la ventna
            XMultiPropertySet xMultiPropertySet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, this.xNameContainer);
            xMultiPropertySet.setPropertyValues(properties, values);
        } catch (com.sun.star.uno.Exception ex) {
            ex.printStackTrace(System.out);
        }
    }
 
    public XComponentContext getxComponentContext() {
        return xComponentContext;
    }
 
    public void setxComponentContext(XComponentContext xComponentContext) {
        this.xComponentContext = xComponentContext;
    }
 
    public XControlContainer getxControlContainer() {
        return xControlContainer;
    }
 
    public void setxControlContainer(XControlContainer xControlContainer) {
        this.xControlContainer = xControlContainer;
    }
 
    public XMultiServiceFactory getxMSF() {
        return xMSF;
    }
 
    public void setxMSF(XMultiServiceFactory xMSF) {
        this.xMSF = xMSF;
    }
 
    public XMultiComponentFactory getxMCF() {
        return xMCF;
    }
 
    public void setxMCF(XMultiComponentFactory xMCF) {
        this.xMCF = xMCF;
    }
 
    public XNameContainer getxNameContainer() {
        return xNameContainer;
    }
 
    public void setxNameContainer(XNameContainer xNameContainer) {
        this.xNameContainer = xNameContainer;
    }
 
    public XWindowPeer getxWindowPeer() {
        return xWindowPeer;
    }
 
    public void setxWindowPeer(XWindowPeer xWindowPeer) {
        this.xWindowPeer = xWindowPeer;
    }
 
    public short execute() throws com.sun.star.script.BasicErrorException, Exception{
        // creamos una ventana
        XWindow xWindow = (XWindow) UnoRuntime.queryInterface(XWindow.class, this.xControlContainer);
        xWindow.setVisible(false);
        Object oToolkit = this.xMCF.createInstanceWithContext("com.sun.star.awt.Toolkit", this.xComponentContext);
        XToolkit xToolkit = (XToolkit) UnoRuntime.queryInterface(XToolkit.class, oToolkit);
        // obtenemos una ventana de la instancia de OpenOffice
        XWindowPeer xWindowParentPeer = xToolkit.getDesktopWindow();
        this.xControl.createPeer(xToolkit, xWindowParentPeer);
        this.xWindowPeer = this.xControl.getPeer();
        // creamos el dialog.
        XDialog xDialog = (XDialog) UnoRuntime.queryInterface(XDialog.class, this.xControl);
        XComponent xDialogComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, this.xControl);
        // mostramos el dialog.
        short nReturnValue = xDialog.execute();
        // liberamos los recursos que utilizo el dialog.
        xDialogComponent.dispose();
        return nReturnValue;
    }
 
    // metodo para crear nombres unicos a los controles (ej. botones, campos de texto, etc).
    public String createUniqueName(String name) {
      boolean elementExists = true;
      int i = 0;
      String baseName = name;
      while (elementExists) {
          i += 1;
          name = baseName + Integer.toString(i);
          elementExists = this.xNameContainer.hasByName(name);
      }
      return name;
    }
 
}



La clase AbstractControl

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
 
package util;
 
/* Omitire nuevamente los imports
 */
 
/**
 * Representación abstracta del algun componente grafico
 * @author gerhard
 */
public abstract class AbstractControl {
 
    // nombre unico identificador del control creado.
    protected String id = "";
 
    // representa el elemento grafico del control creado.
    protected Object control = null;
 
    /**
     * @param parent, quien contiene al control
     * @param interfaceRoute, ruta al servicio que implementa
     * @param controlName
     * @param properties
     * @param values
     */
    public AbstractControl(SimpleDialog parent, String serviceRoute, String controlName,String[] properties, Object[] values){
        try{
            // creamos el nombre unico.
            this.id = parent.createUniqueName(controlName);
            // creamos el modelo del servicio serviceRoute
            Object model = (parent.getxMSF()).createInstance(serviceRoute);
            XPropertySet props = (XPropertySet)UnoRuntime.queryInterface(XPropertySet.class, model);
            // establecemos el nombre al control
            props.setPropertyValue("Name",this.id);
            // asignamos las propiedades al control, como el tamaño etiqueta, etc.
            XMultiPropertySet xMPS = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, model);
            xMPS.setPropertyValues(properties,values);
            // obtenemos el objeto que representa el componente grafico del control.
            (parent.getxNameContainer()).insertByName(this.id, model);
        }catch (com.sun.star.uno.Exception ex){
            ex.printStackTrace(System.out);
        }
    }
 
}



La clase OoButton

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
 
package util;
 
/* Omitire los imports
 */
 
/**
 * Heredero de la clase abstracta AbstractControl, representa un boton.
 * @author gerhard
 */
public class OoButton extends AbstractControl{
 
    /**
     * Constructor del boton.
     * @param parent
     * @param properties
     * @param values
     */
    public OoButton(SimpleDialog parent, String[] properties, Object[] values){
        super(parent,"com.sun.star.awt.UnoControlButtonModel","ButtonCommand",properties, values);
        // obtnemos el control grafico del dialogo y lo guardamos en el objeto
        // control.
        XControl xControl = parent.getxControlContainer().getControl(this.id);
        this.control = (XButton) UnoRuntime.queryInterface(XButton.class, xControl);
    }
 
    /**
     * Añadimos el nuevo actionListener.
     * @param xActionListener
     */
    public void addActionListener(XActionListener xActionListener) {
        ((XButton)this.control).addActionListener(xActionListener);
    }
 
}



La clase OoTextField

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
 
package util;
 
/* Omitire los imports
 */
 
/**
 * Heredero de la clase abstracta AbstractControl, representa un campo de texto.
 * @author gerhard
 */
public class OoTextField extends AbstractControl{
 
    /**
     * Constructor del campo de texto.
     * @param parent
     * @param properties
     * @param values
     */
    public OoTextField(SimpleDialog parent, String[] properties, Object[] values){
        super(parent,"com.sun.star.awt.UnoControlEditModel","TextField", properties, values);
        // obtnemos el control grafico del dialogo y lo guardamos en el objeto
        // control.
        XControl xTextControl = parent.getxControlContainer().getControl(this.id);
        this.control = (XTextComponent) UnoRuntime.queryInterface(XTextComponent.class, xTextControl);
    }
 
    /**
     * @return el String que tiene este TextField
     */
    public String getText(){
        return ((XTextComponent)this.control).getText();
    }
 
    /**
     * NOTA:Falta Implementar las demas funciones basicas de un Textfield.
     */
}

1 ventana y media mas traducida a GUI de UNO (de la extension gdocs)

Las siguientes ventanas fueron convertidas a la GUI de UNO. Al igual que en mi entrada anterior de la bitacora, mostrare el antes de la conversion y el despues.

LoginPanel.jpg
NOTA: Esto es en realidad un JPanel (no un JFrame o JDialog) de java SWING, pero pienso utilizarla por herencia la ventana, para tener un efecto parecido al de incorporar un panel a una ventana.
LoginPanelUNO.jpg
Este es su equivalente en UNO

ConfigDialog.jpg
Esta es de las ventanas que mas me a costado trabajo implementar debido a su gran tamaño y a la gran cantidad de componentes graficos con los que cuenta. Pienso que es mejor rehacer la sección about y en vez de utilizar un Label por cada linea, utilizare un TextArea que sea ReadOnly y escribir todo el contenido en el, en vez de pelearme con las posiciones de los Labels.
ConfigDialogUNO.jpg
Esto es lo que llevo de la traducción de esta ventana, todavia falta refinar la interacción con los radio buttons, e implementar los botones faltantes y la sección about.

Problemas con la implementación de la GUI en UNO

Como la extension gdocs utiliza el componente grafico JPanel para reutilzar una sección grafica, esto facilita mucho la implementación de las ventanas, pero UNO AWT no existe tal concepto, entonces lo que pienso hacer en dichos casos (al menos por el momento), es presentar primero la ventana que se utiliza del JPanel (en el caso de gdocs el JPanel LoginPanel), y luego mostrar la ventana que necesita de ese panel.
Otra de las actividades que realize, fue mejorar la logica de las ventanas, y añadir algunas funcionalidades mas a los controles. Por ejemplo para el dialogo, añadi un nuevo metodo llamado endExecute() que me permite cerrar la ventana cuando se le llame. Tambien le incorpore como nuevo atributo a la clase SimpleDialog un XDialog, el cual me permite llevar acabo la acción de endExecute.
No he subido la imagen de la nueva ventana que he creado, debido a que no la he terminado en su totalidad, me gustaria tener terminada la ventana, o almenos llegar a un punto en el que considere aceptable, para poder subir la imagen.

Implementación del control Grid de UNO

--Gerardo GR 09:10, 23 September 2011 (UTC)

Este nuevo control llamado
XGridControl
es el componente Visual que representa una tabla (o grid en ingles) en UNO AWT. Una de las tareas que realize el dia de hoy, fue la de implementar este componente a una de las ventanas que les estoy haciendo la conversion (de java Swing a UNO AWT). Para poder llevar acabo esta implementación. Primero tuve que crear una nueva clase OoGridColumn, la cual representa una columna dentro del Grid. A continuación mostrare el codigo de dicha clase


/**
 *
 * @author gerhard
 */
public class OoGridColumn {
 
    /* NOTA: Probablemente esten sobrando estos atributos */
    private XComponentContext xComponentContext;
    private XMultiComponentFactory xMCF;
 
    private XGridColumn xGridColumn;
 
    public OoGridColumn(XComponentContext xComponentContext,XMultiComponentFactory xMCF){
        this.xComponentContext = xComponentContext;
        this.xMCF = xMCF;
        try {
            Object obj = xMCF.createInstanceWithContext("com.sun.star.awt.grid.GridColumn", xComponentContext);
            this.xGridColumn = (XGridColumn) UnoRuntime.queryInterface(XGridColumn.class, obj);
        } catch (Exception ex) {
            Logger.getLogger(OoGridColumn.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
 
    public void setTitle(String title){
        this.xGridColumn.setTitle(title);
    }
 
    public void setColumnWidth(int columnWidth){
        this.xGridColumn.setColumnWidth(columnWidth);
    }
 
    public void setHorizontalAlign(HorizontalAlignment horizontalAlignment){
        this.xGridColumn.setHorizontalAlign(horizontalAlignment);
    }
 
    public void setResizeable(boolean resizable){
        this.xGridColumn.setResizeable(resizable);
    }
 
    public XGridColumn getxGridColumn() {
        return xGridColumn;
    }
 
    /* NOTA: Falta implementar algunos metodos */
 
}


El constructor solamente crea este objeto apartir del contexto en el que se encuentra y el xMultiComponentFactory dado. Basicamente los metodos que contiene, son solamente reimplementaciones de los metodos de la clase XGridColumn. Utilizare este punto para señalar, que estas reimplementaciones en todo el codigo anterior visto en esta bitacora, es utilizado/creado para simplificar el mandejo de controles y encapsular las secciones mas complicadas de AWT UNO.
La siguiente clase que cree fue la de OoGridColumnModel, la que me permite agrupar las columnas y tener un modelo apartir de ellas.

/**
 *
 * @author gerhard
 */
public class OoGridColumnModel {
 
    /* NOTA: Probablemente esten sobrando estos atributos */
    private XComponentContext xComponentContext;
    private XMultiComponentFactory xMCF;
 
    private XGridColumnModel xGridColumnModel;
 
    public OoGridColumnModel(XComponentContext xComponentContext,XMultiComponentFactory xMCF){
        try {
            this.xComponentContext = xComponentContext;
            this.xMCF = xMCF;
            Object columnModel = this.xMCF.createInstanceWithContext("com.sun.star.awt.grid.DefaultGridColumnModel", this.xComponentContext);
            this.xGridColumnModel = (XGridColumnModel) UnoRuntime.queryInterface(XGridColumnModel.class, columnModel);
        } catch (Exception ex) {
            Logger.getLogger(OoGridColumnModel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
 
    public void addColumn(OoGridColumn ooGridColumn){
        this.xGridColumnModel.addColumn(ooGridColumn.getxGridColumn());
    }
 
    public XGridColumnModel getxGridColumnModel() {
        return xGridColumnModel;
    }
 
}
Este codigo es aun mas sencillo que el de la clase anterior. El constructor lleva acabo una acción parecida al de la clase anterior, que es implmentar el servicio propio de la objeto que representa esta clase, solo que aplicado a esta clase. El metodo importante que tiene esta clase es el de
addColumn
que permite añadir nuevas columnas al modelo actual.


Ahora para poder mostrar datos introducidos o generados dentro de esta tabla, es necesario un modelo de datos, especificamente un XGridDataModel, el cual contiene los valores para cada renglon nuevo. Ahora mostrare el codigo correspondiente

/**
 *
 * @author gerhard
 */
public class OoGridDataModel {
 
    /* NOTA: Probablemente esten sobrando estos atributos */
    private XComponentContext xComponentContext;
    private XMultiComponentFactory xMCF;
 
    XGridDataModel xGridDataModel;
 
    public OoGridDataModel(XComponentContext xComponentContext, XMultiComponentFactory xMCF){
        try {
            this.xComponentContext = xComponentContext;
            this.xMCF = xMCF;
            Object dataModel = this.xMCF.createInstanceWithContext("com.sun.star.awt.grid.DefaultGridDataModel", this.xComponentContext);
            this.xGridDataModel = (XGridDataModel) UnoRuntime.queryInterface(XGridDataModel.class, dataModel);
        } catch (Exception ex) {
            Logger.getLogger(OoGridDataModel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
 
    public void addRow(String rowNumber,Object[] objects){
        this.xGridDataModel.addRow(rowNumber, objects);
    }
 
    public XGridDataModel getxGridDataModel() {
        return xGridDataModel;
    }
 
}


Esta neva clase se parece mucho a la clase anterior, practicamente son las mismas operaciones (obviamente considerando que el constructor utiliza otro servicio,etc), ahora en vez de añadir columnas, para este modelo, se añaden filas (metodo
addRow
), lo interesante aqui es que los elementos de cada fila puden ser diferentes uno de cada otro, es por eso que el parametro para agregar una fila utiliza
Object
como sus elementos. El parametro
rowNumber
nos sirve para señalar donde se insertara la nueva fila.


Por ultimo la clase que importa (desde el punto de vista grafico), es la de OoGrid, la cual sirve de encapsulamiento de la clase XGridControl. Esta clase, al igual que todos los componentes graficos que he descrito en esta bitacora, hereda de la clase
AbstractControl
la que realiza muchas de tareas de inicialización de un objeto grafico, permite ocultarlas y presentar una manera mas sencilla de crear objetos graficos. A continuación mostrare el codigo (que en realidad no es muy largo).


/**
 *
 * @author gerhard
 */
public class OoGrid extends AbstractControl{
 
    public OoGrid(SimpleDialog parent, String[] properties, Object[] values){
        super(parent,"com.sun.star.awt.grid.UnoControlGridModel","Grid",properties,values);
        XControl xControl = parent.getxControlContainer().getControl(this.id);
        this.control = (XGridControl) UnoRuntime.queryInterface(XGridControl.class, xControl);
    }
 
}


Como se ve en el codigo, es muy sencillo, solo crea el objeto con las propiedades especificadas dentro del Dialog SimpleDialog parent.
Al utilizar esta nueva serie de clases logre crear un grid completo y funcional. Sin embargo aun tengo un error (pero no tengo certeza de que lo sea), no se muestra el titulo de las columnas. Seguire mejorando este control grafico debido a que es uno muy util.

Todas las ventanas de la extension gdocs traducidas a UNO AWT

--Gerardo GR 07:04, 24 September 2011 (UTC)
El dia de hoy he terminado de realizar la conversion de la ultima ventana de la extension de gdocs. En la siguiente entrada de mi bitacora mostrare las nuevas ventanas convertidas (igual que entradas anteriores de esta bitacora).
Habiendo terminado la conversion de las ventanas de la extension, me dispongo a mejorar la libreria de clases que tengo para facilitar la creación de GUIs con UNO, y empezar a añadir la funcionalidad a las nuevas ventanas de la extension de gdocs (las equivalentes en UNO).

Otra actividad que desarrolle el dia de hoy fue la de crear una nueva clase para desplegar imagenes, sigue la misma logica que las clases que he creado antes, o sea las herederas de la clase
AbstractControl
. Lo primero para poder desplegar una imagen, es tener un objeto grafico, esto lo logro a traves de una clase mas llamada
OoGraphic
, que contiene una imagen. Esta clase luego se le pasa como uno de los parametros de inicialización a la clase que representa un control de la imagen dentro de un dialog. A esta clase le llamo OoImageControl.

Resumen de actividades de la semana

--Gerardo GR 18:04, 24 September 2011 (UTC)
Esta entrada es un resumen de las actividades que realize en la semana.
La primer actividad que conclui, fue la de terminar de converitir las ventanas que les faltaban algunos detalles, las ventanas son las siguientes:

  • ServersManager, la ventana que mostre en la entrada anterior del a bitacora, mostraba un campo de texto, en vez de una lista de elementos (el cuadro grande blanco).
  • El equivalente en UNO de la ventana LoginPanel , la mandare a llamar desde la ventana que la necesite, no utilizare herencia (como habia dicho en una entrada pasada). Esta ventana todavia tiene el detalle que el campo donde se introduce la contraseña de la cuenta google docs, no enmascara los caracteres introducidos.
  • La ventana ConfigDialog, esta terminada, le introduje los campos faltantes, pero realize un cambio en la estructura de la ventana, en vez de tener un campo dentro de la ventana que muestre el acerca de (about, en ingles), introduje un boton que lo muestra en un MessageBox.
  • La ventana UploadDialog utiliza el LoginPanel descrito anteriormente, la manera de utilizarlo en esta equivalencia en UNO AWT, sera:
  1. Llamar a LoginPanel
  2. Introducir los recursos necesarios
  3. Esconder la ventana LoginPanel
  4. Utilizar los recursos del LoginPanel
  • La ventana ImportDialog fue terminada de ser convertida a UNO AWT. Esta al igual que la de UploadDialog, utiliza el LoginPanel, por lo mismo se llevara acabo el mismo metodo para obtener los recursos necesarios de LoginPanel. Esta ventana de ImportDialog, tiene aun un error, y es con respecto al despligue de los datos dentro de la tabla. Ahora presentare las ventanas, la original y su equivalente en UNO AWT.


Original
ImportDialog.jpg
Equivalente en UNO AWT
ImportDialogUNO.jpg

  • La ventana WaitWindow, es simplemente una implemtación de un MessageBox, esta fue de las mas sencillas de implementar, no tiene ningun error (al menos no encontrado). Ahora mostrare el original y su equivalente.


Original
WaitWindow.jpg
Equivalente en UNO AWT
WaitWindowUNO.jpg

  • La ultima ventana convertida es la CaptchaWindow, esta solamente muestra una imagen ReCaptcha (la que genera una imagen que contiene un par de palabras), un campo de texto donde se introduce la palabra, y un par de botones, Cancel y Ok. Practicamente esta es un MessageBox, pero debido a que no es tan flexible la implementación que tengo de MessageBox, lo manejare como un Dialog de UNO. A continuación, la ventana Original y el equivalente en UNO AWT.


Originial
CaptchaWindow.jpg
Equivalente en UNO AWT
CaptchaWindowUNO.jpg

Ahora la siguiente actividad para completar la conversion de las ventanas, es incluir toda la funcionalidad necesaria para la extension gdocs, por ejemplo agregar los Listeners.

Incorporando las ventanas a la extension gdocs

--Gerardo GR 02:15, 28 September 2011 (UTC)
Luego de haber terminado la conversion de la GUI de gdocs (al menos la parte de presentación), el siguiente paso es dotarla de la funcionalidad correspondiente. Para lograr esto, la manera en que me aproximare a implementar la funcionalidad en las ventanas, sera la de incluir los listeners en los controles apropiados, y cuando se requiera alguna clase que no tenga (las que realizan la funcionalidad), ir agregandolas, asi al menos desde mi punto de vista, no me abrumare con todas las clases y podre ir realizando pruebas poco a poco hasta llegar a la meta deseada.
Durante la realización de la actividad antes mencionada, me he encontrado con un error en la conversion a UNO AWT, mañana seguire explorando este problema y tratarea de encontrar una solución.

Mejorando la GUI en UNO AWT de la extension gdocs

La actividad que realize el dia de hoy, fue a igualar la funcionalidad que tienens las ventanas de la extension gdocs (java Swing) al equivalente. Empeze con la ventana WaitWindow, esta ventana tuvo que ser rehecha, debido a que como la tenia antes, un MessageBox, no me permitia llamarla cuando se le necesite, debido a que necesitaba de un padre que la llame, es por eso que la converti en un Dialog tal cual, el cual corrige el problema de los llamados. Tambien termine de implementar sus Listeners. La siguiente ventana con la que segui su implementación fue la de ConfigDialog, esta me llevo a rediseñar la GUI, debido a que uno de los campos (el de seleccionar el LookAndFeel) ya no estara disponible para esta version, esto se debe a que no hay tal cosa como el LookAndFeel en UNO AWT. Tambien es en esta etapa en la que los campos que requieran enmascaramiento de caracteres (campos de password) seran implementados, lo cual seguira la siguiente actividad al igual que seguir con la completación de los listeners.
Al principio en la implementación de la funcionalidad me costo un poco trabajo saber por donde empezar lo cual me llevo algo de tiempo, pero una vez establecido en que ventana me enfoque, resulta mas agil el avanze.

Personal tools