====== Documentación y distribución de aplicaciones ====== Cuando nuestra aplicación está creada aún nos falta la parte más importante: poder distribuirla al público. Para ellos debemos incorporar con nuestra aplicación una documentación para facilitar su uso; {{:bloque5:software-distribution.jpeg?direct&200 |}} no somos solo nosotros quienes vamos a usar la aplicación. Además necesitaremos medios para su distribución e instalación. En este bloque nos centramos en estos aspectos. ===== JavaDoc. Documentación de clases ===== Javadoc es una utilidad incluida en el Kit de Desarrollo de Java (JDK) para la generación de documentación de APIs en formato HTML a partir de código fuente Java. La aplicación ''javadoc'' se encuentra en la carpeta bin del directorio del JDK de Java, junto a otros programas como ''java'', ''javac'', ''jar'', etc. Javadoc es el estándar para documentar clases de Java. La mayoría de los IDEs para Java utilizan javadoc para generar de forma automática documentación de clases. ==== Documentar las clases ===== Veamos en primer lugar qué se debe incluir al documentar una clase: * Nombre de la clase, descripción general, número de versión, nombre de autores. * Documentación de cada constructor o método (especialmente los públicos) incluyendo: * nombre del constructor o método, descripción general, tipo de retorno, nombres y tipos de parámetros si los hay, descripción de parámetros (si los hay), descripción del valor que devuelve. * Las variables de instancia o de clase no se suelen documentar a nivel de javadoc. Solo las constantes públicas, si hubiera. **Es muy útil fijarse en el formato que tiene la documentación de métodos y constructores ya existentes en la API de Java**. Basta con situar el cursor del ratón encima de algún método o constructor. ==== Aspectos a tener en cuenta ==== * La documentación para javadoc ha de incluirse entre símbolos de comentario que han de empezar con una barra y doble asterisco, y terminar con un asterisco y barra simple. /** * Esto es un comentario para javadoc */ * La ubicación del comentario le define a javadoc qué representa el comentario: * si está incluido justo antes de la declaración de clase se considerará un comentario de clase, * si está incluido justo antes de la signatura de un constructor o método se considerará un comentario de ese constructor o método. * lo mismo en caso de una constante de clase. * Para alimentar javadoc se usan ciertas palabras reservadas (tags) precedidas por el carácter "@", dentro de los símbolos de comentario javadoc. Si no existe al menos una línea que comience con @ no se reconocerá el comentario para la documentación de la clase. ==== Documentar métodos ==== Si nos fijamos en la API de Java de alguna clase, p.e [[https://docs.oracle.com/javase/8/docs/api/java/lang/String.html|String ]] podemos tener una idea de cómo y qué se debe documentar. Aquí vemos la documentación del método //charAt()// de la clase //String//: /** * Returns the {@code char} value at the * specified index. An index ranges from {@code 0} to * {@code length() - 1}. The first {@code char} value of the sequence * is at index {@code 0}, the next at index {@code 1}, * and so on, as for array indexing. * *

If the {@code char} value specified by the index is a * surrogate, the surrogate * value is returned. * * @param index the index of the {@code char} value. * @return the {@code char} value at the specified index of this string. * The first {@code char} value is at index {@code 0}. * @exception IndexOutOfBoundsException if the {@code index} * argument is negative or not less than the length of this * string. */ public char charAt(int index) { if ((index < 0) || (index >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return value[index]; } Como vemos se indica una descripción del funcionamiento del método, qué representa cada parámetro, qué se espera devolver y si lanza alguna excepcion. A continuación se muestra como aparece en los documentos Javadoc generados: {{ :bloque5:string-javadoc.png?800 |}} Y aquí como se ve cuando accedo a la documentación del método en Eclipse: {{ :bloque5:javadoc-eclipse.png?800 |}} Como se ha indicado anteriormente, en la documentación de un método se debe indicar: * Descripción de la funcionalidad del método * Descripción de la finalidad de los parámetros * Descripción de la finalidad del valor de retorno * Excepciones, si es que lanza alguna ==== Tags o Etiquetas ==== * **Documentación de clases e interfaces** En el comentario de cada clase o interface se debe explicar para que sirve esa clase o interface. Deben usarse al menos las etiquetas: * ''@author'' * ''@version'' * ''@since'' * **Documentación de constructores y métodos** En el comentario de cada método/constructor se debe explicar para que sirve. Deben usarse al menos las etiquetas: * ''@param'': una por argumento de entrada, indicando el tipo, y su funcionalidad * ''@return'': indicando el tipo y su funcionalidad, si el método no es void * ''@exception ó @throws'': una por tipo de Exception que se puede lanzar, solo si se lanzan (@exception y @throws se pueden usar indistintamente). ==== Generar JavaDoc en IntelliJ ==== La documentación JavaDoc la podemos almacenar en la ruta que queramos. Puede ser buena idea crear un directorio dentro de nuestro proyecto e indicar que se exporte en esa ubicación. En el menú //Tools// pulsamos sobre la opción "//Generate JavaDoc..//" y se nos abre el siguiente dialogo: {{ :bloque5:javadoc-intellij.png?direct&300 |}} - Ítem de lista ordenada Indicamos que queremos generar la documentación de todo el proyecto - Indicamos la ruta donde queremos que se genere - Podemos indicar también qué miembros de la clase se tendrán en cuenta para generar el javadoc. Lo habitual es generar la documentación de la API pública. Pero desde el punto de vista del desarrollador, puede ser interesante mostrar la documentación de todos los miembros de la clase, independientemente de su visibilidad. Entonces podemos subir el //slider// a **private**, ya que es la visibilidad más restrictiva. ==== Diagrama de clases ==== Un diagrama de clases nos ayuda a tener un enfoque de las relaciones entre las clases que conforman un programa. Está compuesto de los siguientes elementos: - **Clases**: Reflejan sus atributos y métodos, y la visibilidad de ambos. {{ :bloque5:uml_class_relation.png?direct&200|}} - **Relaciones**: Reflejan la relación entre las clases/objetos: herencia, composición, agregación, asociación, uso, etc. Aunque este tipo de diagramas se deben realizar previo a la etapa de codificación de la aplicación, los IDE's actuales tienen herramientas de ingeniería inversa para generar los diagramas a partir del código de nuestras clases. No está de más incluirlo en la documentación de nuestra aplicación. * **Generar Diagrama de clases en IntelliJ**: Necesitamos seleccionar el //package// que contiene las clases de nuestro programa, y pulsar botón derecho sobre la selección -> Diagram -> Show Diagram. Después podemos indicar qué elementos queremos que se muestren en nuestro diagrama, así como si queremos que se muestren las relaciones. ===== Manual de Usuario ===== Un manual de usuario es la documentación principal de cualquier aplicaciones. Debe indicar cómo utilizar cada funcionalidad y debe ser muy detallada, de forma que indique al usuario si debe introducir todos los datos, solo algunos, cómo usar los botones y cuando, etc. Además debe explicar cada sección de la aplicación, para qué sirve, etc. Para albergar toda la información se crea un índice con sus secciones y subsecciones, agraupándolo de forma organizada. Cuando se ha diseñado la aplicación partiendo de un //diagrama de casos de uso//, este diagrama sirve de importante guía para conocer las funcionalidades de la aplicación de un vistazo rápido. ==== Diagrama de casos de uso ==== Un diagrama de casos de uso es una lista de pasos que definen la interacción entre un actor y el sistema propiamente dicho. Deben cumplir los siguientes objetivos: * Indicar los requisitos funcionales: cómo funciona un programa/sistema. {{ :bloque5:tienda_web_use_cases.png?300|}} * Proporcionar una descripción clara de su uso: cómo el usuario interactúa con el sistema. * Se debe leer con claridad. * Orientar en la realización de pruebas: nos dice cómo debe funcionar (requisitos). * Sirve de guía para crear la documentación de uso del programa. Un diagrama de casos de uso debe mostrar a simple vista, qué se puede hacer con un programa desde el punto de vista de un usuario. Cada cosa que el usuario hace, //es un caso de uso//. Debería ser el paso previo a la creación del manual de usuario. ===== Empaquetado de aplicaciones ===== A la hora de distribuir las aplicaciones, aunque podemos distribuir el código fuente en caso de que nuestra aplicación sea //open soruce//, debemos además distribuir un ejecutable y/o instalador para facilitar el despliegue de la aplicación a usuarios sin conocimientos. En las siguientes secciones vemos como empaquetar nuestra aplicación en un ejecutable, como crear a partir de él otros ejecutables, y cómo empaquetar la aplicación y su documentación en un fichero auto instalable. ==== Ejecutables ==== === Exportar JAR ejecutable en Eclipse === {{ :bloque5:exportarjar.png?300|}} Desde el menú File, export… podremos crear un Jar Ejecutable para ejecutar con un doble click nuestra aplicación en cualquier equipo que tenga la máquina virtual de Java (JVM). Para ello necesitamos que el equipo en el que será ejecutado tenga el paquete JRE de Java. Indicaremos //Runnable Jar// , indicaremos la clase que contiene el ''método main'' (si no aparece, bastará con ejecutar la clase main previamente), le daremos nombre al Jar Ejecutable e indicaremos el lugar donde queremos crearlo. La plataforma Java, no necesita un fichero ''exe'' para ejecutar (traducir el código a código máquina) una ventana, porque la ventana en sí (p.e. JFrame) es un componente nativo de Java, y sabe perfectamente como traducirlo. Por último recordar que se debe marcar la opción de empaquetar librerías en el JAR si mi programa incluye otros JAR con librerías. {{ :bloque5:empaquetar_libs_jar.png?350 |}} === Exportar JAR ejecutable en IntelliJ=== En el IDE IntelliJ debemos seguir los siguientes pasos para crear un fichero Jar ejecutable: - Menú File -> Project Structure -> Artifacts - Pulsamos sobre el botón (+) -> Jar -> From modules with dependencies - Seleccionamos el módulo principal de nuestro proyecto, e indicamos la clase que contiene el método //main// {{ :bloque5:jar-ejecutable-intellij.png?direct&800 |}} {{ :bloque5:build-artifacts-intellij.png?direct&300|}} Después, en la barra de menu principal: - Menú ''Build'' -> Build artifacts - Seleccionamos nuestro Artifact === Generar .exe a partir de Jar === Los ficheros ejecutables de Java que contienen Interfaces gráficas se pueden ejecutar desde cualquier plataforma que tenga instalado Java. Si aun así deseamos crear un fichero //.exe// con nuestra aplicación Java, podemos hacerlo con aplicaciones como //JSmooth// o //Launch4J//. En los [[https://entornos.abrilcode.com/doku.php?id=apuntes:herramientas#generacion_de_ejecutables|apuntes del módulo de entornos de desarrollo]] se explica como usar ambos programas. ==== Instaladores ==== Un generador de instaladores es un programa que contiene una serie de pasos a través de los cuales copia nuestra aplicación y los ficheros necesario dentro de un directorio en nuestro equipo. A estos programas les indicaremos todos los ficheros que queremos copiar en el equipo destino y la ruta donde debe copiarlos. Además de lo indicado anteriormente, estos programas nos permiten añadir multitud de opciones: mostrar licencias, crear accesos directos, crear accesos en el menu inicio de Windows, etc. Normalmente permiten que configuremos todas las opciones que va a tener nuestro instalador mediante un lenguaje de script. Este tipo de programas tienen su propio lenguaje script para definir todas las opciones que queremos que tenga el instalador. Algunos de ellos nos permiten crear el script mediante un modo asistido (//Wizard//) de forma que nos facilita la creación sin necesidad de conocer su lenguaje de //scripting//. A continuación indicamos dos de los programas más famosos: === Nullsoft Scriptable Install System (NSIS) === Es un programa compilador de script, siendo el más utilizado. Además tiene una amplio comunidad de desarrollo y esta comunidad desarrolla multitud de plugins para el programa. Para facilitar nuestra tarea, existe un pequeño editor con un modo asistido llamado [[http://hmne.sourceforge.net/|HM NIS Edit]]. En el siguiente video se explica su funcionamiento: {{ vimeo>493054312?medium }} === Inno Setup Compiler === Al igual que NSIS, [[https://jrsoftware.org|Inno Setup Installer]] utiliza su propio lenguaje de script pero también ofrece un modo asistido de creación de instaladores. Su funcionamiento se explica en este video: {{ vimeo>493057143?medium }} ==== Manual de Instalación ==== El manual de instalación permite al usuario desplegar la aplicación en el sistema. En algunos casos esta documentación se puede incluir en los diferentes pasos guiados de un instalador, o si no incluirla en un documento o página web. Su finalidad es facilitar al usuario la instalación, sobre todo en caso de que se permita elegir diferentes parámetros de instalación (crear accesos directos, instalar componentes extra, indicar una ruta de instalación, etc). ==== Licencias ==== Todo obra de software debe distribuirse bajo los términos de una licencia de software. __La licencia describe el contrato de uso y posesión entre el desarrollador de software y el usuario__. Principalmente existen las licencias de software privativas y las licencias libres. Ambas clasificaciones tienen diversos matices en cuanto a cuanta libertad tiene el usuario final respecto al uso del software. Todos estos matices vienen recogidos en los diferentes tipos de licencias. En nuestro caso, y dado que nuestro software está destinado al ámbito educativo, vamos a decantarnos por utilizar una licencia de código abierto, de entre las que detallamos: ^Licencia^Explicación^Contrato de licencia^ |GPL|GNU General Public License|[[https://www.gnu.org/licenses/licenses.es.html|licencia]]| |LGPL|Lesser General Public License|[[https://www.gnu.org/licenses/licenses.es.html|licencia]]| |BSD|Berkley Software Distribution|| |EPL|Eclipse Public License|| |Apache License||[[http://www.apache.org/licenses/LICENSE-2.0|licencia]]| ===== Distribución de aplicaciones ===== Las aplicaciones se pueden distribuir por diferentes medios, aunque actualmente la mayoría se distribuyen desde internet: páginas de descarga, sitios oficiles de descarga, repositorios de software. Por otra parte desde la creación del sistema de control de versiones [[https://git-scm.com/|Git]] existen diferentes plataformas que actuan como servidores de repositorios de git, ofreciendo una interfaz web para acceso al código fuente y a sus descargas. En esta sección nos centramos al dos de las más populares: [[https://bitbucket.org|bitbucket]] y [[https://github.com|github]]. ==== GitHub ==== Permite crear una wiki para aportar la documentación. ==== BitBucket ==== Permite crear una documentación en la pagina principal del repositorio, o crear una wiki para su documentación. En el enlace siguiente podeis ver un [[https://bitbucket.org/fvaldeon/accesodatosud3/wiki/Home|ejemplo de wiki]] de documentacion en bitbucket. ===== Acceso a documentación desde la aplicación ===== La documentación debe distribuirse con nuestra aplicación. Para ello vamos a plantear dos formas de acceso a la documentación: desde la aplicación y desde fuera de la aplicación. ==== Documentación en sitio Web ==== Podemos mostrar dicha documentación desde alguna ventana de nuestra aplicación, o hacer que nuestra aplicación utilice el navegador web del sistema para acceder al sitio web de la documentación. Para lanzar el navegador web por defecto desde nuestra aplicación: // Creo una etiqueta de color azul JLabel lblFersoft = new JLabel("FerSoft 2020"); lblFersoft.setForeground(Color.BLUE.darker()); // Modifico el puntero del ratón al pasar sobre ella (Hand_cursor) lblFersoft.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); ... //Añadir un MouseListener a la JLabel para hacer click sobre ella //Debemos controlar las excepciones de la siguiente instrucción Desktop.getDesktop().browse(new URI("http://www.bitbucket.org/fvaldeon")); Para mostrar una página web dsde una ventana en nuestra aplicación: Mostrar sitio web en elemento **JTextPane**: JTextPane textPane = new JTextPane(); textPane.setEditable(false); URL myUrl = null; try { myUrl = new URL("http://miSitioWeb.com"); } catch (MalformedURLException ex) { ex.printStackTrace(); } try { textPane.setPage(myurl); } catch (IOException ex) { ex.printStackTrace(); } {{ :bloque5:visorweb-jtextpane.png?direct&400 |}} Las clases ''JTextPane'' o ''JEditorPane'' aunque permiten visualizar y parsear código //html//, no están diseñadas para tal labor. Las librerías de //JavaFX// tienen componentes específicos para mostrar código //html//. Mostrar sitio web con **JavaFX**: JFXPanel fxpanel = new JFXPanel(); JFrame frame = new JFrame(); ... frame.add(fxpanel); WebEngine engine; WebView view = new WebView(); engine = view.getEngine(); fxpanel.setScene(new Scene(view)); engine.load("http://miSitioWeb.com"); frame.setVisible(true); {{ :bloque5:visorweb-javafx.png?direct&400 |}} Estos ejemplos están extraidos del sitio [[http://javatongue.blogspot.com/2015/09/how-to-load-webpage-in-java-app.html|javatongue.blogspot.com]] ==== Documentación en PDF. Librería IcePDF==== Ofreciendo la documentación en formato PDF, podemos también mostrarla desde alguna sección de nuestra aplicación, o permitir al programa utilizar la aplicación por defecto del sistema para abrir dicha documentación. Java no dispone de clases nativas para renderizar ficheros //PDF//, pero existen multitud de librerías //open-source// para renderizar este tipo de archivos. Una de ellas es [[http://www.icesoft.org/java/projects/ICEpdf/overview.jsf|IcePDF]] Para utilizarla necesitamos 2 ficheros jar: * icepdf-core.jar: [[https://mvnrepository.com/artifact/org.icepdf.os/icepdf-core|Repositorio de maven]] * icepdf-viewer.jar: [[https://mvnrepository.com/artifact/org.icepdf.os/icepdf-viewer|Repositorio de maven]] El siguiente ejemplo está planteado con las últimas versiones en la fecha: [[https://mvnrepository.com/artifact/org.icepdf.os/icepdf-core/6.2.2|icepdf.core-6.2.2.jar]] y [[https://mvnrepository.com/artifact/org.icepdf.os/icepdf-viewer/6.2.2|icepdf-viewer-6.2.2.jar]] Necesitamos un JPanel para mostra el visor PDF, que podemos añadir a una ventana específica, o a un area dentro de una ventana. SwingController controller = new SwingController(); SwingViewBuilder factory = new SwingViewBuilder(controller); //Creamos el elemento JPanel donde vamos a mostrar el Visor JPanel viewerPanel = factory.buildViewerPanel(); // En este ejemplo mostramos el JPanel en un Jframe JFrame frame = new JFrame("Visor Pdf"); frame.setContentPane(viewerPanel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); //Finalmente, abrimos el fichero pdf indicando su ruta controller.openDocument("miFichero.pdf"); {{ :bloque5:icepdf-viewer.png?direct&400 | }} ---- (c) {{date> %Y}} Fernando Valdeón