[Métodos] Crear un jar ejecutable en IDE: eclipse, netbeans o intelliJ



Para poder crear un .jar de nuestro con nuestro IDE:

Eclipse:


Sobre la vista de nuestros proyecto, click derecho para acceder al menu contextual:


Damos click en Export..., para que nos abra un ventana de exportación


En la lista lista con carpeta que nos ofrece esta nueva ventana, elegimos Java, y esta contiene 3 opciones


Aqui elegiremos Runnable JAR file, para que sea autoejecutable.

El ultimo paso es elegir cual será la clase principal(Que contenga el método main) a traves de la cual se comenzara a ejecutar la aplicacion. En el combo Launch configuration que te da a elegir con todas las clases que contengan un metodo main ejecutable y a que proyecto pertenece.

Como asi tambien en Export destiantion la ruta completa donde estará el nuevo jar





Netbeans


PAra generar nuestro jar con NetBeans, hay que seleccionar nuestro proyecto desde la vista de proyectos, e ir al menu de la superior a la opcion Run


Para seleccionar una de las 2 opciones: Build Project o Clean and Build Project con el nombre entre parentesis del proyecto que tengamos seleccionado. Tambien nos da el atajo de teclado para hacerlo ;)

Luego podemos chequear el resultado en nuestra consola:


Con eso bastará para ir a la carpeta de nuestro proyecto, y buscar en la carpeta dist el jar generado.
En la consola se puede como genera el jar a través de comandos ejecutados en la consola con ant y te sugiere como hacer para correrlo




intelliJIDEA


Para generar un jar de nuestro proyecto en intelliJIDEA, de la manera que nos resulto, es ir al menu principal de la parte superior:


Sobre File >> Project structure para abrir la siguiente ventana:


Y en el menu de la izquierda, vamos a Project Setting y en el sub-menu de artifact, para hacer click en el + y posteriormente en el menu contextual: JAR >> From modules with dependencies


En la siguiente ventana, configuramos el proyecto y la clase principal.

Luego marcamos el ckeck Build on make para darle a aceptar

Por ultimo, cada vez que querramos generar nuestro jar, sobre el menu principal de la parte superior Build >> MakeProject, para generarlo en la ruta ..out/artifact/*.jar

[Métodos] Cómo crear un Jar ejecutable desde la consola y en un IDE


Consola CMD


Para poder generar un jar a través de la consola de windows debemos:

  1. Contar con la variable JAVA_HOME
    • Esta debe apuntar al root de JDK de la versión que tengamos.
    • De dudar si esta configurada, o entre tantas a cual apunta, podemos escribir en la consola:
    • 1
      2
      echo %JAVA_HOME%
      C:\Programs File\Java\jdk1.8.0_112
      
    • La respuesta deberia de ser la ruta a la carpeta de java, de lo contrario mostraria el literal "%JAVA_HOME%"


  2. Escribir una clase java con un metodo main
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package com.blogspot.dar10comyr;
    
    import java.awt.FlowLayout;
    import java.awt.Frame;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    
    public class Principal {
    
        public static void main(String[] args) {
            JLabel etiqueta = new JLabel("Hola mundo");
            Frame marco = new JFrame("LegenDar10");
            marco.setLayout(new FlowLayout());
            marco.add(etiqueta);
            marco.setLocationRelativeTo(null);
            marco.setSize(250, 100);
            marco.setVisible(true);
        }
    }
    


  3. Compilar el archivo java para convertirlo en .class
    • Hay que llamar al archivo javac.exe y a nuestro archivo java, con lo cual podría llamar a la ruta absoluta de cada cual o aprovechando tener la variable global JAVA_HOME, podemos abrir la consola desde la barra de direcciones en la carpeta donde esta nuestra clase:
    • 1
      "%JAVA_HOME%/bin/javac.exe" Principal.java
      
    • Es importante notar que generalmente la carpeta Program File, lleva un espacio por lo que es mejor encerrar la ruta con las comillas dobles.
    • La primera parte de esta sentencia, llama al compilador del jdk, el archivo javac.exe
    • Y como primer parametro le pasa la clase java que deseamos compilar.


  4. Configurar Main-Class
    • Esto se logra a traves del archivo Manifest.txt, este se situa sobre el root del proyecto
    • 1
      2
      Main-Class: com.blogspot.dar10comyr.Principal
      
      
    • Es un simple archivo de texto, pero de suma importancia su nombre, contiene pares de clave-valor separada por los dos puntos.
    • La clave Main-Class, con sus correspondientes mayusculas, indica cual es la calse principal del proyecto que contiene el metodo main
    • El valor com.blogspot.dar10comyr.Pricnipal, indica la clase a través de su nombre con los paquetes a los que pertence y sin extención, ya que existe el .java, humanamente leible y el .class, un archivo binario.
    • Es muy importante! que este archivo termine con un salto de linea, ya que de lo contrario, no sabra cuando termina la primera declaracion


  5. Generar el jar
    • suponiendo que la estructura de nuestro proyecto es:
      1
      2
      3
      C:/Proyecto/Manifest.tx
      C:/Proyecto/com/blogspot/dar10comyr/Pricipal.java
      C:/Proyecto/com/blogspot/dar10comyr/Pricipal.class
      
    • Llamaremos a través de la variable global JAVA_HOME, al archivo jar.exe
    • Con los puntos de entrada-cvfm, donde:
      • -c indica que creará un nuevo archivo, el .jar
      • -v nos brinda la información detalla del proceso
      • -f le da el nombre al jar, en nuestro caso Saludos.jar
      • -m indica que daremos la información del 'manifest.txt'
    1
    "%JAVA_HOME%/bin/jar.exe" -cvfm Saludos.jar manifest.txt com/blogspot/dar10comyr/Principal.class
    
    • Luego de la point-entry, le damos un nombre al jar, la ubicacion del manifest y de las clases


Ya por ultimo, desde la misma consola llamamos al archivo jar o dando dobel click, el resultado será:

[Métodos] Generar tabla en PDF con xstream y xls en Java


Imaginemos que contamos con un xml de la siguiente manera:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="UTF-8"?>
<list>
  <juego>
    <nombre>Rise Of The Tomb Raider</nombre>
    <desarrolladora>Square Enix</desarrolladora>
    <distribuidora>Crystal Dinamics</distribuidora>
    <plataformas>PC, PS4, XBOX ONE XBOX 360</plataformas>
    <genero>Accion Aventura </genero>
    <fechaLanzamiento>2015-11-10 03:00:00.0 UTC</fechaLanzamiento>
  </juego>
  <juego>
    <nombre>Far Cry Primal</nombre>
    <desarrolladora>Ubisoft Montreal</desarrolladora>
    <distribuidora>Ubisoft</distribuidora>
    <plataformas>PC, PS4, XBOX ONE</plataformas>
    <genero>Accion Aventura Mundo Abierto </genero>
    <fechaLanzamiento>2016-02-23 03:00:00.0 UTC</fechaLanzamiento>
  </juego>
  <juego>
    <nombre>Resident Evil 7 BioHazard</nombre>
    <desarrolladora>Capcom</desarrolladora>
    <distribuidora>Capcom</distribuidora>
    <plataformas>PC, PS4, XBOX ONE</plataformas>
    <genero>Survival Horror</genero>
    <fechaLanzamiento>2017-01-24 03:00:00.0 UTC</fechaLanzamiento>
  </juego>
</list>

Entonces la idea seria poder generar un tabla, similar a las HTML, para poder asemejar cada etiqueta juego como un columna de nuestra tabla.
La sintaxis a usar para una tabla es:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<fo:table border="solid">
    <!-- declarar aqui las columnas que sean necesarias -->
    <fo:table-column column-width="30mm" />
    <!-- declaramos un cabecera -->
    <fo:table-header>
        <fo:table-row>
            <fo:table-cell>
                <fo:block font-weight="bold">Titulo de la columna</fo:block>
            </fo:table-cell>
        </fo:table-row>
    </fo:table-header>
    <!-- declaramos el cuerpo de la tabla -->
    <fo:table-body>
        <fo:table-row>
            <fo:table-cell>
                <fo:block>
                    <xsl:text>contenido de la celda</xsl:text>
                </fo:block>
            </fo:table-cell>
        </fo:table-row>
    </fo:table-body>
</fo:table>

    Es muy importante respetar la secuencia de etiqueta
  • <table-body></table-body>
  • <table-row></table-row>
  • <table-cell></table-cell>
  • <fo-block></fo-block>
  • Ya que de lo contrario, el transformador no entenderá y no generará el reporte

Para poder iterar sobre todas las etiquetas 'juego' vamos a hacer uso del tag <xsl:for-each select="list/juego">, 'seleccionando' a list y por cada juego:

1
2
3
<xsl:for-each select="/">
    <!-- aqui se repite por cada elemento -->
</xsl:for-each>

El XSL

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output method="xml" indent="yes" />
    <xsl:template match="/">
        <fo:root>
            <fo:layout-master-set>
                <fo:simple-page-master master-name="A4-portrait" page-height="29.7cm" page-width="21.0cm"
                    margin="1cm">
                    <fo:region-body />
                </fo:simple-page-master>
            </fo:layout-master-set>
            <fo:page-sequence master-reference="A4-portrait">
                <fo:flow flow-name="xsl-region-body">

                    <fo:table border="solid">
                        <fo:table-column column-width="30mm" />
                        <fo:table-column column-width="30mm" />
                        <fo:table-column column-width="30mm" />
                        <fo:table-column column-width="35mm" />
                        <fo:table-column column-width="35mm" />
                        <fo:table-column column-width="30mm" />
                        <fo:table-header>
                            <fo:table-row>
                                <fo:table-cell>
                                    <fo:block font-weight="bold">Juego</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block font-weight="bold">Desarrolladora</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block font-weight="bold">Distribuidora</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block font-weight="bold">Fecha de Lanzamiento</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block font-weight="bold">Genero</fo:block>
                                </fo:table-cell>
                                <fo:table-cell>
                                    <fo:block font-weight="bold">Plataforma</fo:block>
                                </fo:table-cell>
                            </fo:table-row>
                        </fo:table-header>
                        <fo:table-body>
                            <xsl:for-each select="list/juego">
                                <fo:table-row>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="nombre" />
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="desarrolladora" />
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="distribuidora" />
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="fechaLanzamiento" />
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="genero" />
                                        </fo:block>
                                    </fo:table-cell>
                                    <fo:table-cell>
                                        <fo:block>
                                            <xsl:value-of select="plataformas" />
                                        </fo:block>
                                    </fo:table-cell>
                                </fo:table-row>
                            </xsl:for-each>
                        </fo:table-body>
                    </fo:table>

                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>
</xsl:stylesheet>



Clase de ayuda con el método de transformacion


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package dar10;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;

public class FopHelper {

    public void xmlString2Pdf(String xml, String xslPath, String pdfPath) throws IOException, FOPException, TransformerException{
        FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
        FOUserAgent foUserAgent = fopFactory.newFOUserAgent();

        OutputStream out;
        out = new FileOutputStream(pdfPath);

        try {
            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);

            // Ubicacion del archivo XSL
            File xsltFile = new File(xslPath);
            Source xslSource = new StreamSource(xsltFile);
            // Setup XSLT
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer(xslSource);

            // Resulting SAX events (the generated FO) must be piped through to FOP
            Result res = new SAXResult(fop.getDefaultHandler());

            // Se convierte a 'Source' el xml
            StringReader reader = new StringReader(xml);
            Source xmlSource = new StreamSource(reader);

            // se crea el PDF
            transformer.transform(xmlSource, res);
        } finally {
            out.close();
        }
    }

    public void xmlFile2Pdf(String xmlPath, String xslPath, String pdfPath) throws IOException, FOPException, TransformerException{
        FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
        FOUserAgent foUserAgent = fopFactory.newFOUserAgent();

        OutputStream out;
        out = new FileOutputStream(pdfPath);

        try {
            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);

            // Ubicacion del archivo XSL
            File xsltFile = new File(xslPath);
            Source xslSource = new StreamSource(xsltFile);
            // Setup XSLT
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer(xslSource);

            // Resulting SAX events (the generated FO) must be piped through to FOP
            Result res = new SAXResult(fop.getDefaultHandler());

            // Se convierte a 'Source' el xml
            File xmlFile= new File(xmlPath);
            Source xmlSource = new StreamSource(xmlFile);

            // se crea el PDF
            transformer.transform(xmlSource, res);
        } finally {
            out.close();
        }
    }

}



La llamada


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public static String xmlPath = "src//dar10//juegos.xml";
public static String xslPath = "src//dar10//template.xsl";
public static String pdfPath = "src//dar10//resultado.pdf";

public static void main(String...Legendar10){
    FopHelper fopHelper = new FopHelper();
    try {
        fopHelper.xmlFile2Pdf(xmlPath, xslPath, pdfPath);
    } catch (FOPException | IOException | TransformerException e) {
        e.printStackTrace();
    }
}



El resultado


[Métodos] Generar PDF con xls en Java - Hola Mundo


Apache FOP, de sus siglas en inglés Formatting Objects Processor, el equivalente en español de Procesador de formato de objetos, es un formateador de impresión a través de archivos XSL formatting objects (XMLFO)
Según el mismo framework es capaz de imprimir en muchisimos formatos:
  • PDF, el mas típico y más usado
  • ASCII, PostScript, Direct printer output (PCL), AFP, RTF, Java2D/AWT, menos usuales

Esquema

El esquema básico es se toman tanto el xml como string que genero con xstream, dado en un webservice como desde un archivo, junto al xsl para ser procesados en java a través de apache FOP para generar un pdf(sigla del inglés Portable Document Format, «formato de documento portátil»)



Método

  • Declara 2 objetos FOPFactory y de éste instancia FOUserAgent que servirá para crear el FOP
  • También declara un OutputStream con el path de salida donde se creara el archivo
  • Estos los usa para instancia el objeto FOP junto a una constante que indica que será del tipo PDF
  • Con el path del archivo xsl crea un File y a partir de este un StreamSource que hereda de Source
  • Se crea un TransformerFactory para que junto al xsl instancie un Transformer que procece el xml
  • Declara un objeto Result instanciando un SAXResutl a partir del objeto 'fop'
  • Crea un Source, instanciando StreamSource pero esta vez a partir de un StringReader ya que se trata esta vez de un xml como String.
    Este paso puede cambiar instanciando el streamsource con un objeto file con el path del archivo xml, de igual manera que se hace con xsl.
  • Y el ultimo paso de esta receta mágica, es que el objeto Transformer transforme la fuente del xml junto con el resultado para crear el PDF

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public static String xml = "<valor>Mundo</valor>";
public static String xslPath = "src//dar10//template.xsl";
public static String pdfPath = "src//dar10//resultado.pdf";

public static void main(String...Legendar10) throws IOException, FOPException, TransformerException{
    //Setea el agente para el FOP
    FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
    FOUserAgent foUserAgent = fopFactory.newFOUserAgent();

    OutputStream out = new FileOutputStream(pdfPath);

    try {
        Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);

        // Ubicacion del archivo XSL
        File xsltFile = new File(xslPath);
        Source xslSource = new StreamSource(xsltFile);
        // Transformer a partir del xslt
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer(xslSource);

        // Resulting SAX events (the generated FO) must be piped through to FOP
        Result res = new SAXResult(fop.getDefaultHandler());

        // Se convierte a 'Source' el xml
        StringReader reader = new StringReader(xml);
        Source xmlSource = new StreamSource(reader);

        // se crea el PDF
        transformer.transform(xmlSource, res);
    } finally {
        out.close();
    }
}

En este caso esta todo contendio en un método main que ejecuta el proceso java. Se crea del proyecto un solo paquete que lo he llamado 'dar10' y los 3 string declarados como estaticos que representan el xml, la ubicacion del xsl, y la ubicacion de destino (que son el mismo paquete dentro del proyecto)

Añadir dependencias en el pom/classpath


1
2
3
4
5
<dependency>
    <groupId>com.thoughtworks.xstream</groupId>
    <artifactId>xstream</artifactId>
    <version>1.4.10</version>
</dependency>


El XSL (Transformador)


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
    <fo:root>
      <fo:layout-master-set>
        <fo:simple-page-master master-name="A4-portrait"
              page-height="29.7cm" page-width="21.0cm" margin="2cm">
          <fo:region-body/>
        </fo:simple-page-master>
      </fo:layout-master-set>
      <fo:page-sequence master-reference="A4-portrait">
        <fo:flow flow-name="xsl-region-body">
          <fo:block>
            Hola, <xsl:value-of select="valor"/>!
          </fo:block>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>
</xsl:stylesheet>

El xsl declara en su etiquetas:
  • la version de stylesheet
  • que la fuente de datos será xml
  • que el root del xml empieza en "/" y es a partir de lo que contengan intermente estas etiquetas, aunque nuestro xml solo contiene un tag
  • tmabién declara un layout por defecto y al 'Documento' con las dimensiones de la pagina (A4) y un cuerpo (body)
  • en las etiquetas siguientes declara 'page-sequence' y 'flow' haciendo referencias las anterior mencionadas
  • Y aqui comienza lo bueno, simplemente declara un fo:block, como un contenedor 'div'
  • y buscará con xsl:value-of dentro del root que estemos posicionados ("/") el valor contenido por las etiquetas 'valor'


El resultado:


[Métodos] Imprimir a través de una impresora en java


El objetivo es sencillo poder imprimir un String a través de una impresora.
Las dificultades que vamos a obviar son:
  • Que haya una impresora configurada para la maquina en curso.
  • Que este encendida.
  • Que tenga papel y tinta.

Suponiendo que lo anterior está resuelto procedemos a...
  • Crear un objeto de la clase java.awt.print.PrinterJob
    1
    PrinterJob job = PrinterJob.getPrinterJob();
    

  • Llamamos a su método setPrintable
    1
    job.setPrintable(new Imprimir());
    
    • public abstract void setPrintable(Printable painter)
      • Llama al impresor que renderiza las páginas. Las páginas en el documento que se imprimirá por este 'PrinterJob' se representan por el objeto de impresión, 'painter'. El 'PageFormat' para cada página es el formato de página predeterminado.
      • Recibe como paramétro un objeto de la interfaz Printable.

  • Nuestra pequña clase va a ser el objeto que le pasaremos por parámetro, por ende vamos a extender de la interfaz.
    1
    public class Imprimir implements Printable {
    

  • Esta interfaz va a necesitar que implementemos el método print
    • int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException
      • Imprime la página en el índice especificado en el contexto Graphics especificado en el formato especificado.
      • Parámetros (estos se toman con los valores por defecto)
        • graphics - el contexto en el que se dibuja la página
        • PageFormat - el tamaño y la orientación de la página que se está dibujando
        • PageIndex - el índice basado en cero de la página a dibujar
  • Lo siguiente es llamar al mètodo que muestra el tipico cuadro de pre-impresión del sistema operativo:

    1
    boolean doPrint = job.printDialog();
    

    • Este devuevle un boolean, el cual será de utilidad para determinar si se prosigue con la impresión ya que es el ultimo paso antes de cancelar.
    • Tambíen en este paso se setean el número de páginas a imprimir.

  • Ya sólo nos queda por saber cual ha sido el estado de la impresión, y llamar al método overradeado print
    1
    2
    3
    4
    5
    6
    7
    if (doPrint) {
        try {
            job.print();
        } catch (PrinterException e) {
            e.printStackTrace();
        }
    }
    

  • Dentro del método que sobreescribimos, devolvemos un int que puede ser 0 o 1 dependiendo de la existencia de la página. Y determinar el area imprimible y pasarle el string junto con la ubicacion cartesiana de donde comenzar:
    • Determinar existencia:
      1
      2
      3
      4
      5
      6
      if (page > 0) {
          return NO_SUCH_PAGE;
      }else{
      ...
          return  PAGE_EXISTS;
      }
      

      Ambas constantes son parte de java.awt.print.Printable, PAGE_EXISTS tiene un valor de '0' mientras que NO_SUCH_PAGE vale '1'

    • Determinar el area imprimible: Le pasamos la referencia del paramétro g casteada a un objeto Graphic2d y será este quien llame a su método translate que toma como parámetros los valores por defecto del eje X y eje Y de PageFormat pf, el otro parámetro de la firma print.
      1
      2
      Graphics2D g2d = (Graphics2D) g;
      g2d.translate(pf.getImageableX(), pf.getImageableY());
      

    • Y por ultimo, llamamos al método de Graphics g:dranstring
      1
      g.drawString("Papi ama a juli!", 100, 100);
      
      • El primer parámetro es el string a imprimir(aquí inclui el sentimiento por mi hija que me esta acompañando en esto)
      • Los siguientes corresponden a la posición (x,y) respectivamente.

El resultado será:

una hoja a4 con el string pasado por parametro, en la posicion (100,100) que imprimi y escanie para ilustrarlo. La clase completa es:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.dar10comyr.printer;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.*;

public class Imprimir implements Printable {

    public static void main(String[] args) {
        PrinterJob job = PrinterJob.getPrinterJob();
        job.setPrintable(new Imprimir());
        boolean doPrint = job.printDialog();
        System.out.println(doPrint);
        if (doPrint) {
            try {
                job.print();
            } catch (PrinterException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
        if (page > 0) {
             return NO_SUCH_PAGE;
        }

        Graphics2D g2d = (Graphics2D) g;
        g2d.translate(pf.getImageableX(), pf.getImageableY());

        g.drawString("Papi ama a Juli!", 100, 100);

        return PAGE_EXISTS;
    }
}

[Métodos] Generar XML a partir de un BEAN y viceversa - Java XStream



XStream es una libreria para serializar objetos a XML y viceversa.

Es de las librerias mas faciles de usar, y cuando dice 'fácil' es realmente facil! (después de hacerse con la dependencia)
  • Crear un objeto de la clase XStream a través de un contructor vacío...
    1
    XStream xstream = new Xstream();
    
  • Serializar a XML

  • Simplemente llamando al método toXML(Object objecto), 'a xml' tiene sentido no?, y pasandóle como parámetro el objeto.
    1
    xstream.toXML(objeto);
    
  • Deserializar

  • el mismo objeto xstream llamará al método fromXML(String xml), pasandóle el xml como un objeto String
    1
    xstream.fromXML(stringXml);
    


Pequeño ejemplo ilustrado:


Contamos con una entidad llamada persona:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.dar10.entity;

public class Persona {
 // ATRIBUTOS
    private String nombre;
    private String apellido;
    private Integer años;
 // CONSTRUCTORES
    public Persona() {
    }
    public Persona(String nombre, String apellido, Integer años) {
        super();
        this.nombre = nombre;
        this.apellido = apellido;
        this.años = años;
    }
 // GETTERS Y SETTERS
    public String getNombre() {
        return nombre;
    }
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
    public String getApellido() {
        return apellido;
    }
    public void setApellido(String apellido) {
        this.apellido = apellido;
    }
    public Integer getAños() {
        return años;
    }
    public void setAños(Integer años) {
        this.años = años;
    }
}

Es necesario declarar un constructor vacío en caso de usar otro con los atributos, ya que xstream usará el por defecto para serializar el objeto.

Corriendo la app


1
2
3
4
5
6
    public static void main(String[] args) {
        XStream xstream = new XStream();
        Persona pepe = new Persona("José", "Hernandez", 28);
        String xml = xstream.toXML(pepe);
        System.out.println(xml);
    }

La salida será:


1
2
3
4
5
<com.dar10.entity.Persona>
  <nombre>JOSE</nombre>
  <apellido>Hernadez</apellido>
  <años>15</años>
</com.dar10.entity.Persona>

Si de repente parece feo el nombre de la clase a través de todos los paquetes a los que pertenece, puede ser cambiado configurando el objeto 'xstream' con su
metodo
alias(String alias, <nombre de la clase>)
1
xstream.alias("criatura", Persona.class);

Recordando como guardar cadenas de texto en algun viejo post podemos obtener algo asi:


Convirtiendo a Objeto


Si bien el método que hace la magia es fromXML


Existen diversos problemas como que:
  • El xml contenga otra jerarquia de etiquetas/atributos
  • El xml contenga distintos tipos de variables(un string en lugar de un número)
  • El xml esté vacío o finalice abrutamente
  • O simplemente el xml no es el correcto para deserializar la clase pretendida entre tantas otras...


Si el camino es feliz o tenemos la seguridad de convertir el xml que soñamos se hará correctamente, de lo contrario hay que cachear el XStreamException

1
2
3
4
5
try{
    xstream.fromXML(xmlString)
}catch(XStreamException e){
    e.printStackTrace();
}