mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
point to the new libraries web site pages
This commit is contained in:
@@ -1,480 +1,5 @@
|
||||
LIBRARIES IN PROCESSING
|
||||
This file has been replaced by an entire section of dev.processing.org
|
||||
dedicated to libraries, people who make libraries, and people who
|
||||
love library development trivia. The new page can be found here:
|
||||
|
||||
Some basic instructions on how libraries work with Processing.
|
||||
(I'm also adding to this as people have trouble with it..
|
||||
Pretty soon it's gonna be an outrageous mess!)
|
||||
|
||||
Libraries are a new feature that are present only in revisions 70
|
||||
and higher. Before revision 70, users could place any sort of code
|
||||
inside the 'code' folder of their sketch, but this meant too many
|
||||
copies of each library. The code folder is still an option, but the
|
||||
use of the new "library" system is encouraged as a simple packaging
|
||||
mechanism for your projects.
|
||||
|
||||
A Processing library can be any sort of Java code that's been
|
||||
given a package name and packed into a jar file. It can also register
|
||||
itself with the parent applet to get notification of when events
|
||||
happen in the sketch, for instance whenever draw() is called or a
|
||||
key is pressed.
|
||||
|
||||
Most libraries may not need that much functionality, but they
|
||||
may want to implement the dispose() call, which is called as the
|
||||
applet is closed. Many libraries, especially those with native code,
|
||||
need this to properly shut down.
|
||||
|
||||
It is not possible to build libraries from within Processing itself.
|
||||
In fact, creating a library with Processing will cause problems
|
||||
because when exported as an applet, the jar file will contain the
|
||||
current version of the processing.core classes, which will cause
|
||||
major conflicts when trying to use any other code.
|
||||
|
||||
The PDE is built with the sole purpose of creating short sketches that
|
||||
are part of PApplet that have a few files at most. We don't plan to
|
||||
extend the PDE to also support developing libraries (or "tools," once
|
||||
those are enabled) because then it simply becomes like any other IDE
|
||||
that is quickly too general for our target audience. Users who are
|
||||
advanced enough in their programming skills to build libraries will
|
||||
almost always be skilled enough to use another IDE like Eclipse
|
||||
(if they aren't already) to build their library.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Where to put Libraries
|
||||
|
||||
Core libraries live inside the "libraries" folder of the Processing
|
||||
distribution. Starting with release 0149, user-installed libraries
|
||||
must live in a folder named "libraries" inside the sketchbook folder.
|
||||
|
||||
If a library works only with a particular release of Processing,
|
||||
then it may make sense for the user to put things into the
|
||||
Processing libraries folder, however we'd like to keep users
|
||||
out of there as much as possible. In fact, it may not be visible
|
||||
in future releases of Processing (for instance, on Mac OS X it
|
||||
already lives inside the .app bundle).
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Notes on Library distribution
|
||||
|
||||
There are two categories of libraries. The "core" libraries
|
||||
(Video, OpenGL, Serial, Net) are part of the Processing distribution,
|
||||
and "contributed libraries" are developed, owned, and maintained
|
||||
by members of the Processing community.
|
||||
|
||||
It's very possible that contributed libraries might make their way
|
||||
into the regular distribution if it makes sense for all involved.
|
||||
After the 1.0 release, we'll re-evaluate if some libraries should be
|
||||
made a part of the standard distribution. For now, we don't have the
|
||||
people resources to support this, because it would require us to
|
||||
debug the libraries with each release.
|
||||
|
||||
We try to place a strong focus on the importance of clear
|
||||
documentation for the Processing project, so please attempt similar
|
||||
effort into communicating your library's features to potential users
|
||||
by hosting a descriptive web site.
|
||||
|
||||
If you'd like to have your library posted on the Processing website
|
||||
(http://processing.org/reference/libraries) please email
|
||||
reas at processing.org and we'll make a decision about its inclusion.
|
||||
We strongly encourage (and may someday require as a stipulation for
|
||||
placement on the site) that the source to your library be included.
|
||||
We're giving away all our stuff, and we want others to do so as well
|
||||
because it's good for the community.
|
||||
|
||||
The contributed libraries are one of the most important aspects of
|
||||
the Processing project and have an enormous impact on how people
|
||||
understand Processing. Libraries have been designed into the larger
|
||||
Processing plan to enable simple extensions of the core API in new,
|
||||
innovative, and unexpected directions. The libraries are the future
|
||||
of the project as we plan for processing.core.* to remain as minimal
|
||||
as possible.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
A Very Basic Example
|
||||
|
||||
|
||||
package libraryexample;
|
||||
import processing.core.*;
|
||||
|
||||
public class BoringLibrary {
|
||||
PApplet parent;
|
||||
|
||||
public BoringLibrary(PApplet parent) {
|
||||
this.parent = parent;
|
||||
parent.registerDispose(this);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
// anything in here will be called automatically when
|
||||
// the parent applet shuts down. for instance, this might
|
||||
// shut down a thread used by this library.
|
||||
// note that this currently has issues, see bug #183
|
||||
// http://dev.processing.org/bugs/show_bug.cgi?id=183
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Usually you'll need to pass "this" to a library's constructor so that
|
||||
the library can access functions from PApplet, i.e graphics methods
|
||||
like line() and stroke() or loadImage(). See later in the document for
|
||||
information about reading and writing files.
|
||||
|
||||
If you'd like to use constants such as "RGB", use the following:
|
||||
public class BoringLibrary implements PConstants {
|
||||
which will allow all the constants to be used by that class.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Library Methods
|
||||
|
||||
public void pre()
|
||||
method that's called just after beginFrame(), meaning that it
|
||||
can affect drawing.
|
||||
|
||||
public void draw()
|
||||
method that's called at the end of draw(), but before endFrame().
|
||||
|
||||
public void mouseEvent(MouseEvent e)
|
||||
called when a mouse event occurs in the parent applet
|
||||
|
||||
public void keyEvent(KeyEvent e)
|
||||
called when a key event occurs in the parent applet
|
||||
|
||||
public void post()
|
||||
method called after draw has completed and the frame is done.
|
||||
no drawing allowed.
|
||||
|
||||
public void size(int width, int height)
|
||||
this will be called the first time an applet sets its size,
|
||||
but also any time that it's called while the PApplet is running.
|
||||
no drawing should occur inside of this method, because it may
|
||||
not be the case that the new renderer is yet valid and ready.
|
||||
use this only to flag the new size and prepare for the next frame.
|
||||
|
||||
public void stop()
|
||||
can be called by users, for instance movie.stop() will shut down
|
||||
a movie that's being played, or camera.stop() stops capturing
|
||||
video. server.stop() will shut down the server and shut it down
|
||||
completely, which is identical to its "dispose" function.
|
||||
|
||||
public void dispose()
|
||||
this should only be called by PApplet. dispose() is what gets
|
||||
called when the host applet is stopped, so this should shut down
|
||||
any threads, disconnect from the net, unload memory, etc.
|
||||
currently, this method is not being called consistently:
|
||||
http://dev.processing.org/bugs/show_bug.cgi?id=77
|
||||
|
||||
To register any of these methods with the parent, call
|
||||
parent.registerPre(this) or whatever the name of the function
|
||||
is that you'd like to use.
|
||||
|
||||
Note that making things "public" is extremely important. When running
|
||||
inside Processing, anything left blank has public added by the
|
||||
preprocessor, meaning "void draw()" becomes "public void draw()".
|
||||
|
||||
You can only draw inside of pre(), draw(), mouseEvent(), or keyEvent()
|
||||
otherwise you may run into trouble. pre() and draw() happen while
|
||||
legitimate drawing is taking place, and the mouse/key events happen
|
||||
just before draw() events are called, they're queued up by the host
|
||||
applet until it's safe to draw.
|
||||
|
||||
For this reason, you should use registerMouseEvent() and mouseEvent()
|
||||
(and same for the keys) to handle your events, rather than your class
|
||||
implementing MouseListener. For instance, to figure out what the mouse
|
||||
event is throwing back at you, this would be an example handler:
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
More on mouse handling can be found in Sun's Java documentation:
|
||||
http://java.sun.com/j2se/1.4.2/docs/api/java/awt/event/MouseEvent.html
|
||||
which also covers things like modifiers (shift-click) and whatnot.
|
||||
Also check out the code for PApplet to see how ctrl-click is handled
|
||||
on Mac OS X so that it properly registers as a right-click.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Structure of a Library Folder
|
||||
|
||||
The Sonia library by Amit Pitaru is a good example here. To make a
|
||||
library called sonia, you create a folder called "sonia" and within
|
||||
that, a subfolder named "library". The sonia folder should be placed
|
||||
inside the Processing "libraries" folder, or a user can place it
|
||||
inside their sketchbook folder.
|
||||
|
||||
Inside "library", you'll find "sonia.jar". Anything that is found
|
||||
inside library will be exported with your sketch.
|
||||
|
||||
If different sets of files should be exported with applets versus
|
||||
applications, a file called "export.txt" should be included. For
|
||||
sonia, this looks like:
|
||||
|
||||
# only export the jar file for applets..
|
||||
# everything else is installed as a separate browser plugin
|
||||
applet=sonia.jar
|
||||
# application needs everything
|
||||
application=sonia.jar,JSynClasses.jar,JSynV142.dll,libJSynV142.jnilib
|
||||
|
||||
This will include sonia.jar for applets, because in a web browser, the
|
||||
DLL files must be installed separately along with JSynClasses.jar.
|
||||
The # sign in front of a line means that the line is a comment,
|
||||
and it'll be ignored by the PDE.
|
||||
|
||||
As of revision 0097, you can also specify what to export for other
|
||||
platforms as well (at least Mac OS X, Windows, Linux). For the example
|
||||
above, the application line could instead be changed to:
|
||||
|
||||
application.macosx=sonia.jar,JSynClasses.jar,libJSynV142.jnilib
|
||||
application.windows=sonia.jar,JSynClasses.jar,JSynV142.dll
|
||||
|
||||
Platform-specific exports will be checked first, and if they don't
|
||||
exist, the "application" will be used. If neither exist (or export.txt
|
||||
doesn't exist), the entire contents of the library folder will be
|
||||
copied.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Using Other Java Code As A Library
|
||||
|
||||
So long as the code is inside a package, it can be set up for use as
|
||||
a library. For instance, if you want to make a library called 'poopy'
|
||||
set up a folder as follows:
|
||||
|
||||
poopy ->
|
||||
library ->
|
||||
poopy.jar
|
||||
|
||||
Then, the folder should be placed in the Processing 'libraries' folder
|
||||
or inside the user's sketch folder to be recognized by Processing and
|
||||
its "Import Library" menu. As of now, you may need to restart
|
||||
Processing in order to get the library to show up.
|
||||
|
||||
While this process may sound a little complicated, the intent is to
|
||||
make it easier for users than a typical Java IDE. A little added
|
||||
complexity for the developers of library code (who will generally be
|
||||
more advanced users) is traded for great simplicity by the users,
|
||||
since Processing is intended to target beginning programmers.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Import Statements and How They Work
|
||||
|
||||
If your library is sonia.jar, found at sonia/library/sonia.jar, all
|
||||
the packages found in sonia.jar will be added as imports into the
|
||||
user's sketch when they selected "Import Library".
|
||||
|
||||
In the case of Sonia, an additional .jar file can be found in the
|
||||
sonia/library/ folder, jsyn.jar. The contents of jsyn.jar will not be
|
||||
added to the import statements. This is to avoid every library having
|
||||
a ridiculously large number of import statements. For instance, if you
|
||||
want to use the "video" library, you don't want all 15-20 packages for
|
||||
the QuickTime libraries listed there to confuse your users.
|
||||
|
||||
Bottom line, if you want packages from the other .jar to be loaded by
|
||||
Processing, then you need to put those .class files into the main .jar
|
||||
file for the library (sonia/library/sonia.jar in this case).
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Import Statements and the Code Folder
|
||||
|
||||
The code folder works differently, and every package inside every .jar
|
||||
found in the code folder is simply added to the import statements by
|
||||
the preprocessor. The user never sees this, it just happens magically.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Creating .jar Files For Your Library
|
||||
|
||||
Since your code is inside a package, you need to make sure that it's
|
||||
inside subfolders in the .jar file. It should be noted that jar files
|
||||
are simply .zip files (they can be opened with WinZip or Stuffit) with
|
||||
a "manifest" file.
|
||||
|
||||
In the past, you may have used:
|
||||
javac *.java
|
||||
to compile your files. Once they're inside a packages, you must use:
|
||||
javac -d . *.java
|
||||
which will create folders and subfolders for the packages. For
|
||||
instance, for all the stuff in processing.core.* it would create:
|
||||
|
||||
processing/ ->
|
||||
core/ ->
|
||||
PApplet.class
|
||||
PGraphics.class
|
||||
..etc
|
||||
|
||||
then you can jar that stuff up using:
|
||||
jar -cf core.jar processing
|
||||
or with the command line info-zip utility:
|
||||
zip -r core.jar processing
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
The "Import Library" Menu Item
|
||||
|
||||
All this does is add the "import yourlibrary.*;" statement to the top
|
||||
of your sketch. If you've handwritten the import statements, then
|
||||
there's no need to use "Import Library".
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Getting a UnsupportedClassVersionError? (Java 1.5 and later)
|
||||
|
||||
When I compiled blah.jar (using the successful method mentioned
|
||||
earlier) under Java 1.5, I get the following error from Processing:
|
||||
|
||||
java.lang.UnsupportedClassVersionError: blah/SomeClass
|
||||
(Unsupported major.minor version 49.0)
|
||||
|
||||
This is because more recent versions of Java like to use their own
|
||||
class file format that's not backwards compatible.
|
||||
|
||||
When compiling a library, use somtehing like:
|
||||
javac -source 1.4 -target 1.4 -d . \
|
||||
-classpath /path/to/core.jar path/to/java/source/*.java
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Adding Your Own Library Events
|
||||
|
||||
So that your library can notify the host applet that something
|
||||
interesting has happened, this is how you implement an event
|
||||
method in the style of serialEvent, serverEvent, etc.
|
||||
|
||||
|
||||
public class FancyLibrary {
|
||||
Method fancyEventMethod;
|
||||
|
||||
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() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Using built-in functions from processing.core
|
||||
|
||||
Many methods in PApplet are made static for use by other libraries
|
||||
and code that interfaces with Processing. For instance, openStream()
|
||||
requires an applet object, but loadStrings() is a static method
|
||||
that can be run on any InputStream. See the developer's reference
|
||||
for more information about which methods are available.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Accessing files from inside a library
|
||||
|
||||
To open files for use with a library, use the openStream() method.
|
||||
This is the most compatible means for loading data, and makes use
|
||||
of many hours of headaches that were the result of attempts to
|
||||
create functions that loaded data across platforms (Mac, Windows,
|
||||
and Linux) and circumstances (applet, application, and other).
|
||||
|
||||
The functions sketchPath(), savePath(), dataPath(), and createPath()
|
||||
all facilitate reading and writing files relative to the sketch
|
||||
folder. They should be used to ensure that file I/O works consistently
|
||||
between your library and functions like loadImage() or loadStrings().
|
||||
Their documentation can be seen in the online javadoc reference found
|
||||
on dev.processing.org. The variable sketchPath is available for
|
||||
convenience, but in nearly all cases, the sketchPath() method is
|
||||
a better (and more compatible) route.
|
||||
|
||||
The xxxxPath() functions were finalized in revision 0096.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Library Naming Rules
|
||||
|
||||
Libraries, or classes inside them, should not be prefixed with "P"
|
||||
the way that the core Processing classes are (PImage, PGraphics, etc).
|
||||
It's tempting to prefix everything that way to identify it with
|
||||
Processing, but we'd like to reserve that naming for "official"
|
||||
things that are inside processing.core and other associated classes.
|
||||
|
||||
Same goes for using "Processing", "Pro", or "P5" just like "P",
|
||||
or whether it's a prefix or a suffix.
|
||||
|
||||
Similarly, please don't using processing.* as the prefix for your
|
||||
library packages. We'd like to keep that name space clear for
|
||||
official things as well.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Ben Fry, last updated 19 August 2008
|
||||
http://dev.processing.org/libraries/
|
||||
|
||||
Reference in New Issue
Block a user