How To Libraries by Ben Fry, Last updated 23 October 2007

El How To de las Librerías en Processing
Son algunas instrucciones básicas sobre cómo trabajan las librerías con Processing. (También se añadió para aquellas personas que tienen problemas con éstas, ya que muy pronto será un completo revoltijo!) Las librerías son una nueva característica que se presenta en las revisiones 70 y superiores. Antes, los usuarios podían colocar cualquier tipo de código dentro de la carpeta de “code” de sus sketches, pero esto también significaba muchas copias de cada librería. La carpeta de código continua siendo una opción, pero el uso del nuevo sistema de “library” se promueve como un simple mecanismo de empaquetado para tus proyectos. Las librerías viven dentro de la carpeta “libraries” de la distribución de Processing, sin embargo los usuarios están motivados a instalar librerías “contribuidas” en la carpeta de su sketch, lo cuál los previene de tener que mover sus librerías junto con las nuevas versiones de Processing. Una librería de Processing puede se cualquier tipo de código Java al que se le ha dado un nombre de paquete y ha sido empaquetado en un archivo .jar. También puede se puede autoregistrar con un applet padre para obtener notificaciones de eventos que se originan en el sketch, por ejemplo cuando draw() es llamado o cuando una tecla es presionada. Muchas de las librerías tal vez no necesiten muchas funcionalidades, pero tal vez quieran implementar la llamada dispose(), la cual ocurre cuando un applet se cierra. Muchas librerías, especialmente aquellas de código nativo, necesitan saberlo para terminar adecuadamente. No es posible construir librerías del mismo Processing. De hecho, la creación de una libreria con Processing causará problemas ya que cuando se exporte como un applet, el archivo jar contendrá la versión actual de las clases processing.core, las cuales causarán mayores conflictos cuando se traten de usar en otro código. El PDE es construido con el sólo propósito de crear sketches cortos que sean parte de Papplet que tenga el menor número de archivos. No planeamos extender el PDE para que también soporte el desarrollo de librerías (o “herramientas”, una vez que estén disponibles) ya que entonces simplemente se convertiría en otro IDE que se generalizará demasiado rápido para nuestra audiencia objetivo. Los usuarios suficientemente avanzados en su habilidades para la programación de librerías serán casi siempre los suficientemente capaces de usar otro IDE como Eclipse (si no es que ya lo son) para construir su librería.

Notas sobre la distribución de Librerías
Las librerías se dividen en dos categorías. Las librerías “núcleo” (Video, Open GL, Serial, Net) son parte de la distribución de Processing, y las “librerías contribuidas” que son desarrolladas, propietarias o mantenidas por los miembros de la comunidad de Processing.

Translated by Dennys Regalado Díaz, Last updated 27 April 2009

How To Libraries by Ben Fry, Last updated 23 October 2007

Es muy posible que las librerías contribuidas se conviertan en parte de la distribución regular si tienen sentido para todos los involucrados. Después de la liberación 1.0, reevaluaremos si algunas librerías deberán ser parte de la distribución estándar. Por ahora no tenemos los recursos necesarios para soportarlas, ya que requeriría depurar las librerías en cada liberación. Tratamos de poner especial atención en la importancia de limpiar la documentación para el proyecto de Processing, así que por favor intenta realizar un esfuerzo similar en la documentación de las características de tu librería a través de un sitio web descriptivo. Si te gustaría tener tu librería publicada en el sitio de Processing (http://processing.org/reference/libraries) por favor escribenos a Processing.org y tomaremos la decisión acerca de su inclusión. Las librerías contribuidas son uno de los aspectos mas importantes del proyecto Processing y tienen un enorme impacto en como la gente entiende Processing. Las librerías han sido diseñadas dentro de un plan a largo plazo para habilitar las extensiones del API núcleo en uno nuevo, innovador y con directivas inesperadas, las librerías son el futuro del proyecto como lo planeamos para processing.core.* para mantenerlo mínimo. Un ejemplo muy básico:
package libraryexample;  import processing.core.*;  public class BoringLibrary {    PApplet parent;    public BoringLibrary(PApplet parent) {      this.parent = parent;      parent.registerDispose(this);    }    public void dispose() {      // cualquier código aquí será llamado automáticamente     // cuando el applet padre termine. Por ejemplo, podría     // terminar un hilo usado por esta librería.     // notar que esto actualmente tiene problemas, ver el bug #183      // http://dev.processing.org/bugs/show_bug.cgi?id=183    }  } 

Usualmente necesitaras pasar “this” al constructor de la librería para que ésta pueda accesar a las funciones del PApplet, por ejmplo, los métodos gráficos como line() y stroke() o loadImage(). Ver más adelante en el documento la información acerca de la lectura y escritura de archivos. Si quieres usar constantes como “RGB”, utiliza lo siguiente:
public class BoringLibrary implements PConstants {

lo cual permite que todas las constantes sean usadas por esa clase.

Translated by Dennys Regalado Díaz, Last updated 27 April 2009

How To Libraries by Ben Fry, Last updated 23 October 2007

Métodos de Librería
public void pre()

método que es llamado justo después de beginFrame(), lo que significa que puede afectar el dibujado.
public void draw()

método que es llamado al final de draw(), pero antes de endFrmae().
public void mouseEvent(MouseEvent e)

llamado cuando un evento del mouse ocurre en el applet padre.
public coid keyEvent(KeyEvent e)

llamdo cuando un evento de tecla ocurre en el applet padre.
public void post()

método llamado después de que el dibujo ha sido completado y el frame se construyó. No se permite dibujar.
public void size(int width, int height)

este será llamado la primera vez que el applet establece su tamaño, pero también en cualquier momento en que sea llamado mientras el Papplet está correindo. No se dibuja dentro de este método, porque no se dará el caso en el nuevo renderizador esté listo y sea válido aún. Usalo solo como bandera para el nuevo tamaño y para preparar el siguiente frame.
public void stop()

pude ser llamado por el usuario, por ejemplo movie.stop() terminará el video que se esté reproduciendo, o camera.stop() detendrá la captura de video. server.stop() terminará el servidor y, lo cuál es idéntico a su función “dispose”.
public void dispose()

solo deberá ser llamado por PApplet.dispose() se llama cuando el applet host es detenido, así que se deben terminar todos los hilos, desconectarse de lared, descar memoria, etc. Actualmente, esté método no es muy consistente:http://dev.processing.org/bugs/show_bug.cgi? id=77 Para registrar cualquiera de estos métodos con el padre, llama a parente.register(this) o cuál sea el nombre de la función que quieras usar. Nota que hacer las cosas “public” es extremadamente importante. Dentro de Processing, cualquier cosa que se deje en blanco, será considerado como público por el preprocesador, es decir, “void  draw()” se vuelve “public void draw()”. Sólo puedes dibujar dentro de pre(), draw(), mouseEvent(), o keyEvent()  de otra manera te meteras en problemas. Pre() y draw() suceden mientras un dibujado legal se lleva a cabo, y los eventos mouse/key suceden justo antes de que draw() sea llamado, estos se encolan por el applet host hasta que sea seguro dibujar. Por esta rason, tu debes usar registerMOuseEvent() y mouseEvent() (lo mismo para las teclas)
Translated by Dennys Regalado Díaz, Last updated 27 April 2009

How To Libraries by Ben Fry, Last updated 23 October 2007

para manejar tus eventos, además de que tus clases implementen el MouseListener. Por ejemplo, para saber qué evento del mouse se te regresa, este es un ejemplo para el manejador:
public void mouseEvent(MouseEvent event) {    int x = event.getX();    int y = event.getY();    switch (event.getID()) {      case MouseEvent.MOUSE_PRESSED:        // do something for the mouse being pressed        break;      case MouseEvent.MOUSE_RELEASED:        // do something for mouse released        break;      case MouseEvent.MOUSE_CLICKED:        // do something for mouse clicked        break;      case MouseEvent.MOUSE_DRAGGED:        // do something for mouse dragged        break;      case MouseEvent.MOUSE_MOVED:        // umm...        break;    }  } 

Más sobre manejadores de eventos en la documentación de Java: http://java.sun.com/j2se/1.4.2/docs/api/java/awt/event/MouseEvent.html que también cubre cosas como modificadores (shift-click). También revisa el código para el PApplet para ver cómo se maneja el ctrl-click en Mac OS X ya que este se registra como un click derecho. La librería sonia de Amit Pitaru es buen ejemplo. Para hacer que la librería se llame sonia, crea una carpeta llamada “sonia” y dentro de ella, una subcarpeta llamada “library”. La carpeta sonia debe ser colocada dentro de la carpeta “libraries” de Processing, o un usuario puede ponerlo dentro de la carpeta de su sketch. Dentro de “library”, encontrarás “sonia.jar”. Todo lo que esté dentro de la librería se exportara junto con tu sketch. Si deben exportarse diferentes archivos entre applets y aplicaciones, se debe incluir un archivo llamado “export.txt”. Para sonia el archivo se ve así:
# solo exporta el archivo jar para los applets. # todo lo demás está instalado por separado como un plugin del navegador applet=sonia.jar  # la aplicación necesita todo application=sonia.jar,JSynClasses.jar,JSynV142.dll,libJSynV142.jnilib 

Este debe incluir el sonia.jar para applets, ya que en un navegador web, los archivos DLL deben ser instalados por separado junto con JsynClasses.jar. El caracter # indica que esa línea es un comentario y será ignorado por el PDE. Como en la revisión 0097, tu puedes especificar que exportar para otras plataformas también (al menos Mac OS X, Windows, Linux). Para el ejemplo anterior, la línea de application debería
Translated by Dennys Regalado Díaz, Last updated 27 April 2009

How To Libraries by Ben Fry, Last updated 23 October 2007

cambiarse por:
application.macosx=sonia.jar,JSynClasses.jar,libJSynV142.jnilib  application.windows=sonia.jar,JSynClasses.jar,JSynV142.dll 

Las especificaciones de exportación de plataforma deben ser revisados primero, y si no existen debe usar “application”. Si ninguno existe ( o el archivo export.txt no existe), todo el contenido de la carpeta de la librería será copiado. /////////////////////////

Usar Otro Código Java como una Librería
Ya que el código está empaquetado, se puede enviar para usarse como una librería. Por ejemplo, si quieres escribir una librería llamada 'poopy' configura la carpeta como se muestra:
poopy ­>   library ­>     poopy.jar

Después, la carpeta debe ser colocada en la carpeta 'librarires' de Processing o dentro de la carpeta del sketch, para que sea reconocido por Processing y aparezca en el menú “Import Library”. Como sabes, necesitas reiniciar Processing para actualizar dicho menu. Mientras este proceso suene un poco complicado, la intensión es hacerlo lo más fácil que un IDE Java convencional. Un poco de trabajo extra para los desarrolladores de librerías (que generalmente son usuarios más avanzados) se agrega para mayor simplicidad de los usuarios, ya que Processing tiene como objetivo principal a los programadores principiantes. Si tu librería es sonia.jar, sonia/library/sonia.jar, todos los paquetes encontrados en sonia.jar serán agregados al sketch del usuario que la importa, es decir, cuando selecciona “Import Library”. En el caso de Sonia, un archivo .jar adicional puede ser encontrado en la carpeta sonia/library/, jsy.jar. El contenido de jsyn.jar no será incluido en las sentencias import. Esto es para evitar que cada librería tenga un rídiculo y alto número de sentencias import. Es decir, si quieres usar la librería de video, no necesitas todos los 15-20 paquetes de librerías del Quicktime ya que los usuarios se confunden. Si quieres cargar otros paquetes .jar desde Processing, entonces necesitarás poner los .class en el archivo .jar principal de la librería (sonia/library/sonia.jar en este caso).

Sentencias Import y la Carpeta Code
Ya que tu código está empaquetado, necesitas asegurarte que está dentro de sus subcarpetas en el archivo .jar. Debes notar que los archivos .jar son simples archivos .zip (que pueden abrirse con WinZip) con archivo de manifiesto. Anteriormente, tenías que usar:
javac *.java

para compilar tus archivos. Una vez que estuvieron empaquetados, deberías usar:
Translated by Dennys Regalado Díaz, Last updated 27 April 2009

How To Libraries by Ben Fry, Last updated 23 October 2007 javac ­d . *.java

lo cual crea las carpetas y subcarpetas para los paquetes. Por ejemplo, para todas las clases en processing.core.* se creará:
processing/ ­>    core/ ­>        Papplet.class        Pgraphics.class       ...etc

Después puedes convertirlo en un jar usando:
jar ­cf core.jar processing

o con la utilidad de línea de comandos info-zip:
zip ­r core.jar processing

El opción del menú “Import Library”
Todo lo que hace es agregar la línea “import yourlibrary.*;” al inicio del sketch. UnsupportedClassVersionError (Java 1.5 and later) Cuando compilo blah.jar (usando el método mencionado) bajo Java 1.5, obtengo el siguiente error:
java.lang.UnsupportedClassVersionError: blah/SomeClass  (Unsupported major.minor version 49.0)

Esto es por las versiones más recientes de Java no tiene compatibilidad hacia atrás. Cuando compiles una librería, usa algo como esto:
javac ­source 1.4 ­target 1.4 ­d . \   ­classpath /path/to/core.jar path/to/java/source/*.java

Agregar Eventos Propios A Tu Librería
Tu librería también puede notificar al applet host algo interesante que haya sucedido, esto es cómo implementar un método de evento del estilo serialEvent, serverEvent, etc.
  public YourLibrary(PApplet parent) {     // your library init code here...     // check to see if the host applet implements     // public void fancyEvent(FancyLibrary f)     try {       fancyEventMethod =         parent.getClass().getMethod("fancyEvent",                                     new Class[] { FancyLibrary.class });     } catch (Exception e) {       // no such method, or an error.. which is fine, just ignore     }   }   // then later, to fire that event   public void makeEvent() { Translated by Dennys Regalado Díaz, Last updated 27 April 2009

How To Libraries by Ben Fry, Last updated 23 October 2007     if (fancyEventMethod != null) {     try {       fancyEventMethod.invoke(parent, new Object[] { this });     } catch (Exception e) {       System.err.println("Disabling fancyEvent() for " + name +                          " because of an error.");       e.printStackTrace();       fancyEventMethod = null;     }   } }

Usar funciones built-in del processing.core
Muchos métodos PApplet son estáticos para que puedan ser usadas por otras librerías y codificar sus interfaces con Processing. Por ejemplo, openStream() requiere un objeto applet, pero loadStrings() es un método estático que puede ser ejecutado sobre cualquier InputStream. Ver la referencia del desarrollador para más información acerca cuáles métodos están disponibles.

Accesando a archivos desde una librería
Para abrir un archivo para el uso de una librería, usa el método openStream(). Es el medio más compatible para cargar datos y te evitará pasar dolores de cabeza intentando portar funciones que lean datos en las distintas plataformas (Mac, Windows y Linux) y circunstancias (applet, aplicación, y otros). Las funciones sketchPath(), savePath(), dataPath() y createPath() facilitan la lectura y escritura de archivos relativos a la carpeta del sketch. Deben usarse para asegurar que la entrada/salida sobre archivos funcione de manera consistente entre tu librería y funciones como loadImage() o loadStrings(). La documentación se puede ver en la referencia en línea creada con javadoc, que se encuentra en dev.processing.org. La variable sketchPath está disponible por conveniencia, pero casi en todos los caso, el método sketchPath() es una mejor (y más compatible) manera. Las funciones xxxxPath() fueron finalizadas en la revisión 0096.

Reglas para nombrar a las Librerías
Las librerías o clases dentro de ellas, no deben llevar el prefijo “P” de la misma manera que lo hacen las clases núcleo de Processing (Pimage, Pgraphics, etc). Está nomenclatura se reserva solo a las clases oficiales, las que existen dentro de processing.core y otras clases asociadas. Lo mismo va para los que usa “Processing-”, “Pro”, o “P5” como “P”, ya sea como prefijos o sufijos. De manera similar, por favor no usen processing.* como prefijo para sus paquetes de librerías. Queremos mantener el espacio de nombres claro para cosas oficiales.

Translated by Dennys Regalado Díaz, Last updated 27 April 2009