Processing

Creative Coding and Computational Art

Ira Greenberg

Processing: Creative Coding and Computational Art
Copyright © 2007 by Ira Greenberg All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording, or by any information storage or retrieval system, without the prior written permission of the copyright owner and the publisher. ISBN-13: 978-1-59059-617-3 ISBN-10: 1-59059-617-X Printed and bound in the United States of America 9 8 7 6 5 4 3 2 1 Trademarked names may appear in this book. Rather than use a trademark symbol with every occurrence of a trademarked name, we use the names only in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark. Distributed to the book trade worldwide by Springer-Verlag New York, Inc., 233 Spring Street, 6th Floor, New York, NY 10013. Phone 1-800-SPRINGER, fax 201-348-4505, e-mail orders-ny@springer-sbm.com, or visit www.springeronline.com. For information on translations, please contact Apress directly at 2855 Telegraph Avenue, Suite 600, Berkeley, CA 94705. Phone 510-549-5930, fax 510-549-5939, e-mail info@apress.com, or visit www.apress.com. The information in this book is distributed on an “as is” basis, without warranty. Although every precaution has been taken in the preparation of this work, neither the author(s) nor Apress shall have any liability to any person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by the information contained in this work. The source code for this book is freely available to readers at www.friendsofed.com in the Downloads section.

Credits
Lead Editor Chris Mills Technical Editor Charles E. Brown Technical Reviewers Carole Katz, Mark Napier Editorial Board Steve Anglin, Ewan Buckingham, Gary Cornell, Jason Gilmore, Jonathan Gennick, Jonathan Hassell, James Huddleston, Chris Mills, Matthew Moodie, Jeff Pepper, Dominic Shakeshaft, Matt Wade Project Manager Sofia Marchant Copy Edit Manager Nicole Flores Copy Editor Damon Larson Assistant Production Director Kari Brooks-Copony Production Editor Ellie Fountain Compositor Dina Quan Artist Milne Design Services, LLC Proofreaders Linda Seifert and Nancy Sixsmith Indexer John Collin Interior and Cover Designer Kurt Krames Manufacturing Director Tom Debolski

C INTEGRATING PROCESSING WITHIN JAVA

if I create a Ball class in a package named shapes. either for my own later reuse or eventual distribution. I recommend reviewing Sun’s online Java tutorials at http:// java.sun.Ball class. including how to compile and run a Java program. In addition. used to “organize classes belonging to the same category or providing similar functionality. The IDE is just a development environment (albeit a very user-friendly one) that allows you to write. which is unique (among domain names). The API (the actual commands making up the language) is an independent library of code accessible from within the IDE and structured as a Java package.” (See http://en. Processing outside of Processing Because Processing is ultimately Java. Java is a very expandable language. here’s what the complete directory structure could look like (note that subdirectories follow the forward slash character [/]): com/greenberg/shapes/Ball 2 .org/wiki/Java_package. it is possible to incorporate the Processing language commands into Java projects built completely outside of the Processing environment. called processing. in that anyone can create classes and packages. or getting a good book on Java. One of the potential risks of a structure like this is that it’s possible (actually very likely) for developers to specify the same names for different classes—referred to as a name collision. Astute readers may then ask what happens if there is another package named shapes that also contains a Ball class? This too could be a likely scenario. I’d use my domain name for the name of the base package.Ball. Keeping with the shapes. This appendix assumes a basic understanding of Java. preventing naming conflicts from occurring. I will review these procedures. but in a cursory fashion. in the words of Wikipedia.core. Processing is composed of two distinct components: the Processing IDE (integrated development environment) and the Processing API (application programming interface). For example.P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T This final appendix includes information on integrating the Processing core graphics library within Java projects created independently of the Processing environment. This potential. To learn more about Java. can lead to annoying and hard-to-track-down bugs. For example. a unique name is often specified for the base package structure. class names are evaluated to the package name they reside within. To avoid package/class name conflicts. Packages in Java are simply directory structures (including subdirectories) containing Java classes and. some Processing and creative coding resources and references are included. left unchecked. run.com/docs/books/tutorial/. and view your Processing programs. if I was going to create a library of classes. Through the use of packages. which can then easily be used by other coders.wikipedia.) Packages also keep the naming of Java classes (the namespace) organized. the full class name will resolve to shapes.

candy processing. setting up a large library of interrelated classes and packages can be a daunting organizational challenge (not to mention a technical one).xml These packages contain classes that.serial processing. this initial program will only output some text. Here’s an example: com/greenberg/geometry/shapes3D/Ball As you might imagine.core package into a Java application.core processing.dxf processing. Before describing how to actually integrate the processing.opengl processing. create the Processing development environment. processing. I want to provide a simple example demonstrating how to code. To run these next examples.org/reference/everything/. specify the language commands. including viewing the classes they contain.core package. you’ll need to have the Java Standard Edition (SE) Development Kit (JDK) installed. among other things.preproc processing.processing.I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA It would of course also be possible to use greater specificity.java processing. but you can find system-specific info here: Mac OS X users: www. as well as the graphics context—the structure needed to actually draw stuff to the screen in Java. To incorporate Processing’s graphic functions within your Java projects.syntax processing. I won’t be covering how to set up Java on your respective platform. For our purpose—learning how to utilize the Processing API (the language commands) outside of the Processing environment—we’re interested in the processing. adding additional subdirectories.app. You can learn more about these packages. the Processing software is composed of the following 14 Java packages: antlr antlr.processing. and run a simple Java program.org/reference/everything/ javadoc/processing/core/package-summary. you need to explicitly import the processing.com/macosx/features/java/ Windows and Linux users: http://java.app. Returning to Processing. To keep things really simple.pdf processing. You can view the 12 classes in the processing.app processing. compile.core package.com/javase/downloads/index.core package at http://dev.html.net processing.apple.jsp C 3 . in defining a package structure.sun. and add specialized library features. at http://dev.core includes 12 classes that control most of the Processing language API.video processing.

} } 4 .sun. Notepad on Windows and TextEdit on OS X will work. there are other IDEs you can use to write Java programs.net/2006/ 10/05/an-introduction-to-the-os-x-terminal/ Windows: http://java. html Finally. } // main method public static void main(String[] args){ new MyFirstJavaProgram(). I’ll only be showing you how to run the examples from the command line.com/macosx/features/unix/ and www. you’ll need a simple text editor to write the Java programs. that being said. Eclipse is an industrial strength open source development environment.barebones.org/).” so to speak. but it will be much easier to understand precisely how the Processing/Java integration works by doing it “by hand. One of the more popular of these is Eclipse (www.P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T You’ll be running the Java examples from the command line. Programs like Eclipse.apple.com/products/textwrangler/index.html In addition to a plain vanilla text editor (or the Processing environment). really speed up the software development process.shtml Windows: www.sun.com/docs/books/tutorial/getStarted/cupojava/ win32.com/docs/books/tutorial/getStarted/cupojava/unix. I have nothing against IDEs (some of my best friends use them). However. there are also many other free (and better) text editors you can download off the Web.com/ Linux: http://bluefish. so you’ll also need to know how to access a shell or terminal application on your system: Here are some additional links to help with that: OS X: www.openoffice.simplehelp. Creating your first Java program Launch your trusty text editor and enter the following code into it: public class MyFirstJavaProgram { // constructor public MyFirstJavaProgram(){ System.eclipse. once mastered.println("Waaaaaz up World!").out.nl/index.crimsoneditor.html Linux: http://java. Here are links to some text editors: OS X: www.

so I’ll assume you get the concept. which you’ll learn how to do in a moment. In Processing. when you create a class (working in continuous mode). naming it exactly the same name as the class. you don’t add the public keyword (which is referred to as an access modifier).println("Waaaaaz up World!"). I instantiate an object of the class (new MyFirstJavaProgram(). class constructor. in this case through the expression new MyFirstJavaProgram(). You can confirm this by exporting one of your Processing sketches and then opening up the . Lastly. I’ll describe the different parts of the Java code.java file created. I discussed constructors in numerous places throughout the book.g. when you execute the program. MyClass. the main() method is invoked automatically. via dot syntax (e. Rather. preceding the method name. and think that linearity is a bad word.java.statusMethod()). when your Processing code is converted to standard Java. if you’re like me.) You also need to add . In fact. You do not instantiate an object to call a static method. Notice the public keyword preceding the class declaration. } A main() method is required to execute a Java program. However. What’s probably new to many of you is the main() method: // main method public static void main(String[] args){ new MyFirstJavaProgram(). this is where program execution begins. First is the constructor: // constructor public MyFirstJavaProgram(){ System.). which you’ll remember calls the class constructor mentioned earlier. OK. if not. Next. C 5 . However. If you’ve read the entire book in order—learning about OOP in Chapter 8 and then how to work in Java mode in Chapter 14—most of the code in MyFirstJavaProgram. } The constructor is the method that’s called when an object of the class is created (instantiated).out. I named the file MyFirstJavaProgram.I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA Then save the file. The static keyword specifies that the method is a class method (as opposed to an instance method). The main() method is unique in that you don’t explicitly call it. so now let’s run our exciting first Java program. this code might need some clarification. (Remember that Processing and Java are case sensitive.java to the end of the name. these modifiers are automatically put in for you. please refer to Chapter 8.. Static methods are called using the class name. and main() method.java probably looks familiar. notice that from within the main() method.

I put the file in a directory named appc on my desktop. I entered the following UNIX command to navigate within the appc directory (obviously. 6 .java file): cd desktop/appc To then confirm that the file is in the directory.P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T Running your first Java program Well.class files that are run. Bytecode is the code the Java interpreter reads as it executes your program.java files will create . you’ll need to open your shell or terminal program.class files of the same exact name. compiling the file Program1. Figure C-1. you’ll need to enter the commands specific to your system and terminal application and relative to where you saved the MyFirstJavaProgram.java file is saved.java will generate Program1. In the terminal program in OS X. To compile and run the program. The Java code you write needs to be compiled into what’s referred to as bytecode. I entered the following command: ls The dir command should work accordingly on Windows. there is actually one more step you need to do before you can run your program. Compiling your . Figure C-1 shows a screenshot of my terminal program in OS X. For example. and again. OS X terminal application screenshot You’ll need to navigate to the directory where the MyFirstJavaProgram.class. it’s the compiled .

java.I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA This then outputs the following: MyFirstJavaProgram.println("Hello there " + name). really simple class.core package into the mix involves a few more steps. Simply enter the following command: java MyFirstJavaProgram Hopefully your program outputs the following (within your terminal program): Waaaaaz up World! Pretty easy. Next. look again inside the directory where MyFirstJavaProgram.out.class MyFirstJavaProgram. right? Adding the processing.java in the same directory as MyFirstJavaProgram. After entering the javac MyFirstJavaProgram.java Congratulations! You just compiled your first Java program.java. Create a new file in your text editor and enter the following code: public class MySecondJavaProgram { // constructor public MySecondJavaProgram(String name){ System. which you’ll reference from the first class. You’ll also need to make a simple change to MyFirstJavaProgram. Notice that the only change (displayed in bold) is to the constructor. you’ll add a second really. to the directory in which MyFirstJavaProgram. Following is the updated code. and that the Java JDK is successfully installed. Now it’s time to compile the program.java Javac is a compiler application that comes with the Java JDK and compiles your .java is stored. but not many. via your command-line tool. you should type the following: javac MyFirstJavaProgram.java command.class files (bytecode). You should now see two files listed: MyFirstJavaProgram. } C 7 . } } Save this file as MySecondJavaProgram. public class MyFirstJavaProgram { // constructor public MyFirstJavaProgram(){ new MySecondJavaProgram("Creative Coder").java. Assuming that you have successfully navigated. The next step is easy—running your program.java is saved.java files to .

class and MySecondJavaProgram. files will be overwritten by the same named files without warning. where the . java into the pkg1 subdirectory. Now try running MyFirstJavaProgram again: java MyFirstJavaProgram You should see the following output: Hello there Creative Coder Java packages The last thing you need to understand before plugging in the processing.java files are saved. from the main directory. specifying the pkg1 package in which it now resides.core package is how to both specify and then communicate with a Java package.class. you need to update the Java file MySecondJavaProgram.) Next.java MySecondJavaProgram.P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T // main method public static void main(String[] args){ new MyFirstJavaProgram().java If you look at your directory again.java: javac MyFirstJavaProgram. you can also delete the two class files. Also. } } Returning to your terminal program. it is not necessary to do so.class MyFirstJavaProgram. Then move the file MySecondJavaProgram.java. when compiling. you should now see four files in the directory: MyFirstJavaProgram. MyFirstJavaProgram. Create a subdirectory named pkg1 in the directory where the MyFirstJavaProgram. recompile MyFirstJavaProgram. (If you’d like to.java files reside. java file. However.class MySecondJavaProgram.java Please note that you don’t need to explicitly compile the new MySecondJavaProgram. this just requires a package declaration statement to be added to the top of the class (shown in bold in the following code): 8 . as the compiler will automatically compile any other referenced classes.java and MySecondJavaProgram.

to new pkg1. Let’s try this. if you try to recompile MyFirstJavaProgram. Although it’s possible to use full package.java:7: cannot find symbol symbol : class MySecondJavaProgram location: class MyFirstJavaProgram new MySecondJavaProgram("Creative Coder"). which allows you to import both individual classes and groups of classes. compiling and running your Java programs gets more complicated (an issue that unfortunately needs to be addressed if you eventually want to incorporate processing. Returning to your terminal program. However. ^ 1 error What’s happening is that the MyFirstJavaProgram class can’t find the MySecondJavaProgram class.class addressing as you just did.println("Hello there " + name). change the line new MySecondJavaProgram("Creative Coder"). especially once you begin using multiple packages in your programs.out. Java includes the import keyword. it’s not really practical.MySecondJavaProgram("Creative Coder"). C 9 . you’ll get an error such as the following: MyFirstJavaProgram. as it would require a lot more code to be written. public class MySecondJavaProgram { // constructor public MySecondJavaProgram(String name){ System.I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA package pkg1.java from MyFirstJavaProgram.java.java now. this works! The compiler can now find the MySecondJavaProgram class from within the MyFirstJavaProgram class. Change the line with the explicit package reference that now reads new pkg1. } } Again. a package is nothing more than a directory. once packages are introduced into Java. avoiding the need to include the explicit package directory structure in each class reference. In MyFirstJavaProgram. Sure enough. core in Java projects).MySecondJavaProgram("Creative Coder"). and try recompiling. Your initial thought might just be to update the path to MySecondJavaProgram. since it’s been put into the pkg1 subdirectory.

Copy this file (being sure to not remove it from the lib directory) into the directory in which you’ve been running the Java examples.shapes2D. However. Or. The .2/ docs/guide/jar/jar.).. these strategies would still require lots of separate long class reference or import statements.html.core package can be found within the lib directory. import pkg1.4. which essentially adheres to the popular ZIP file format.*. There is one other variation that can be made to the import statement to make it even more efficient. within your Processing application directory.P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T back to new MySecondJavaProgram("Creative Coder"). The processing.com/j2se/1. The first step is to copy the processing. Imagine if you created a program that relied on 20 classes defined in another package.*. The JAR format includes some other geeky stuff as well. as we did earlier (new pkg1.).MySecondJavaProgram.. 10 . you could add an import statement for each class in the package (e. A better solution is to import all the classes in a package in one fell swoop.*. bundled file. check out http://java.g. One option would be to add the package name explicitly in front of each class reference from the package throughout your program.jar and appears to be a single file rather than a directory. The JAR format is mostly used to bundle together classes and necessary resources.jar suffix specifies a compressed.core package into the directory where your Java class will reside. Then add the statement import pkg1..core package is called core. beyond this discussion. you’d write import geometry.MySecondJavaProgram. to the very top of the MyFirstJavaProgram class (above the class declaration statement). such as images and sounds. since the MySecondJavaProgram class can again be found from within MyFirstJavaProgram. Perhaps you’re wondering why the processing. to import all the classes in a package named geometry.jar. Please note that package names begin with a lowercase letter. If you wanted to use all the classes in a subdirectory within geometry named shapes2D. while class names begin with a capital letter..jar Let’s now try importing the processing. For example.MySecondJavaProgram("Creative Coder").sun.core package into a Java program. core. If you’re interested in learning more about the JAR format. which can be accomplished using the syntax import packageName. The package is called core. This file should compile successfully. you could use the import statement import geometry.

class processing/core/PGraphics2D. such as the complier javac and a tool called jar.class processing/core/PGraphicsJava2D$ImageCache. as well as how the processing.class processing/core/PApplet$5. as I did with the pkg1 package created earlier. you can begin to use it.class processing/core/PShape. However. Using your command-line tool.class processing/core/PMatrix.class Notice that the core. a number of tools and applications come with it.class processing/core/PApplet$WorkerVar. which contains a core directory.class processing/core/PApplet$7. It’s also possible to look inside the core.jar file.jar archive contains a processing directory.class processing/core/PApplet$Worker$1. Once there.class processing/core/PGraphicsJava2D.class processing/core/PGraphics.class processing/core/PApplet$RegisteredMethods. I’ll show you how to access a single value in C 11 .class processing/core/PApplet$6.class processing/core/PApplet$Worker. Next. as I mentioned earlier.class processing/core/PFont. The jar tool allows you to create and edit JAR files as well as view and extract their contents.class processing/core/PImage. type the following command: jar tf core. navigate to the directory where you copied the core. Lets take a look inside core.jar) is organized.class processing/core/PApplet.class processing/core/PLine.I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA The core.class processing/core/PGraphics3D. Once you know the directory structure of the package.class processing/core/PApplet$4. working with JAR files is slightly trickier than with straight (un-jarred) packages.jar.class processing/core/PConstants.jar You should then see the following output: processing/ processing/core/ processing/core/PApplet$1.jar file to see these 12 classes.core package (within core.jar file contains numerous Java classes.class processing/core/PApplet$3.class processing/core/PPolygon.class processing/core/PApplet$8. which then contains all the classes. that form most of the Processing language API.class processing/core/PTriangle. When the JDK is installed.class processing/core/PApplet$2.

^ 2 errors 12 . you’d write PConstants.A = " + PConstants.A = " + PConstants. please refer to Chapter 8. as the compiler will automatically look within the JAR file for the necessary packages and classes.) at the top of the class.MySecondJavaProgram.out.jar.out.A). if you didn’t. add the following import statement to the top of the class (you can leave the import pkg1.A. Within the processing.A). make sure you comment out or remove new MySecondJavaProgram("Creative Coder") from the constructor.println("PConstants. to refer to it. PConstants.*. In MyFirstJavaProgram. add a second println() statement to the MyFirstJavaProgram. Please note that it is unnecessary to convert core.P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T core. then I’ll finally show you how to create a real Java graphics application utilizing the Processing API.core.*. now try compiling MyFirstJavaProgram.core directory is a PConstants class file. For example.MySecondJavaProgram.java again using the following line (warning: this shouldn’t work): javac MyFirstJavaProgram.jar back to its uncompressed package directory structure. System. Next. there is a constant in the PConstants interfaced named A. Let’s try this.java constructor (displayed in bold in the following code): // constructor public MyFirstJavaProgram(){ new MySecondJavaProgram("Creative Coder"). } You can leave the other statement (new MySecondJavaProgram("Creative Coder")) in the constructor as well. you use the class name. In your terminal program.core.java. (If you don’t remember what an interface is.java:2: package processing.java Trying to compile should generate the following error message: MyFirstJavaProgram.println("PConstants. followed by a dot and the constant name. statement there as well): import processing.) To access a constant in Java (assuming that the constant is defined with the static keyword).java:9: cannot find symbol symbol : variable PConstants location: class MyFirstJavaProgram System.class is actually an interface that contains lots of constants—thus its name. ^ MyFirstJavaProgram.core does not exist import processing. as long as you also left the import statement (import pkg1.

check out www-128.java Since you’re changing the default classpath (which includes just the current directory). you can pretty much take these sorts of processes for granted.:core.I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA I told you working with JAR files is a little more complicated than working with straight packages. Working in Processing. Now try running the updated program again.ibm.core package independently of the Processing IDE (which will now allow you to do some exciting things). C Please note that in my example.core package.A = 6 Note that if you removed the line new MySecondJavaProgram("Creative Coder") from the MyFirstJavaProgram constructor. 13 . For more information about working with the classpath in OS X (and UNIX). Putting it all together Two of the challenges of graphics programming in Java are setting up the drawing component (the actual window that you draw to) and correctly communicating with the graphics context of this component to control when something needs to be drawn to the screen. Here’s the compile statement with the classpath argument added: javac -classpath .com/developerworks/ java/library/j-classpath-windows/?ca=dgr-lnxw07clspth-Windows. The error was caused because the compiler couldn’t find the processing. using a classpath argument with the javac command. I realize that the output is not terribly exciting. since it’s mostly handled for us behind the scenes. using the following command: java MyFirstJavaProgram The program now outputs the following: Hello there Creative Coder PConstants.A = 6 tells you that you are now indeed accessing the processing.jar MyFirstJavaProgram.ibm.jar in the compile statement. If you’ve ever worked with HTML tables. you’ll only get one line of output. For information about the classpath in Windows. please refer to www-128.com/developerworks/ java/library/j-classpath-unix/?ca=dgr-lnxw07clspth-Unix-MacX. You need to explicitly tell the compiler where the JAR is located.jar. you now need to explicitly include the current directory (where the Java file you’re compiling is located) along with the path to core. The classpath argument tells Java where to look for class files—which is by default the current directory containing the Java file you’re compiling. Use a dot to refer to the current directory. but the line PConstants. I used a colon to separate the current directory from core. which I coded in OS X. Windows instead requires a semicolon to separate multiple paths.

P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T you know how difficult (and really annoying) it can be sometimes just to code the simplest layouts. background(255). However. rw. but just make sure to be consistent in properly changing the name in any import statements as well. float spacer = 1.*. just use my domain name for now. I’ll create two simple classes: Controller.iragreenberg.core. Here’s the EmbeddedP55 class: package com. public class EmbeddedP55 extends PApplet { private private private private private private int w. In the next example. } public void setup() { /* account for height of frame title bar.java and EmbeddedP55.0f. yc. width and height) */ int titleBarHt = getBounds(). import java. when sizing applet.*. I’ll also set up a package structure based on my domain name (iragreenberg. size(w. frameRate(30). ry. this. public EmbeddedP55(int w.y. by using the processing. you can greatly simplify the graphics coding process while retaining the benefit of working in pure Java. } public void draw(){ if (ry < height){ fill(50. h-titleBarHt). h. xc = width/2.0f. int xc. if you have any doubt about being able to successfully do this. int h){ this. getBounds() returns a Java Rectangle object that has 4 public properties: (x. Feel free to substitute your own domain name for mine. noStroke().com). alph). smooth(). Coding graphics in Java can be equally frustrating.h = h. float alph = 50.w = w. float ang. 14 . y. import processing.awt. rh. yc = height/2. float rx.core package. radius. java.

including the java. and then create another directory within com named iragreenberg.sun. then save the EmbeddedP55. radius +=. is the “base class for all sketches that use processing. By extending PApplet. an enormous library of code comes with it.0f). ry = yc + sin(ang)*radius. notice that I begin the class with the following package declaration statement: package com. rw = cos(ang*spacer)*(radius/8. I declare the EmbeddedP55 class extending Processing’s PApplet class.java class.08f.jar) and the Java package java. ang += . when we look next at the Controller. the package declaration should match where your class is indeed located.core. Next. rh).core package (archived within core. you’ll be able to refer directly to Processing’s function calls from within the EmbeddedP55 class. objects created from the EmbeddedP55 class will also be of the second type. Looking at the EmbeddedP55. refer to Chapter 8. within the directory structure com/iragreenberg. spacer +=.com/docs/books/tutorial/java/concepts/inheritance. In other words.001f. which I believe I’ve explained enough throughout the rest of the book. When you download the Java JDK. For now. C 15 . Obviously.0f). There are three finer points.java class. } } } Enter the class into your text editor and save the class as EmbeddedP55.java file within there. The PApplet class. I’ll discuss Java’s awt package shortly. though. it doesn’t matter where the outer com directory is located. ellipse(rx.awt package. The rest of the class is pretty much straightforward Processing code. create a directory named com.html. and have access to the (non-private) members (properties and methods) of this class.075f.” This class contains methods with the same names as the function calls in the Processing API. or check out http://java. since you refer to the methods from within the same class (or a subclass) directly—without the need to first instantiate an object.awt. I import the processing. rh = sin(ang*spacer)*(radius/8. as long as you can navigate to it using your terminal program. Remember. To learn more about inheritance.java. alph +=. PApplet.I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA rx = xc + cos(ang)*radius. as stated in the Processing reference. Following the package statement. rw.iragreenberg.00001f. ry. through this inherited relationship.

However.P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T that might need some clarification. The first is the use of the public and private access modifiers.*. is to make your properties private and then create get() and set() methods to change and access the values of the properties.y method (of Java’s Component class). you could leave the private modifiers off. public class Controller extends Frame { private int w = 400.0f. as I did throughout the class. The last fine point is in the following lines within the EmbeddedP55 setup() method: int titleBarHt = getBounds(). java. I wanted to account for the title bar height to allow any output to be properly centered in the PApplet component.Applet. The float primitive type in Java is 32 bits long. The second point to clarify is the use of f after the decimal values in the class (e. all decimal values are of primitive type double. java. at which the PApplet component was placed. again. By using the getBounds(). h = 422. while the double primitive type is 64 bits. size(w.awt.awt.g. you can explicitly cast double values to float values.).. Processing functions can only handle float arguments. java. I then sized the PApplet component to the size of the outer frame minus the height of the menu bar. while properties should be declared private. I was able to get the specific y position. float alph = 50. In general.iragreenberg. 16 . I would include them. as I discussed in Chapter 14. But the convention in Java. By using f as post notation after a decimal value.event. Here’s the Controller class: import import import import com. and the program would still run (the public modifiers on the other hand are required). In truth. and the classes themselves should be declared public. From within the Controller class (which I’ll discuss next). However. I knew this value represented the height of the menu bar. Since the PApplet component will reside within a Frame window (which includes a title bar). I chose to not include any get() and set() methods in the example for the sake of brevity.*. constructors.y. Processing was designed based on the trade-off that a slight loss in accuracy (from 64 bits to 32 bits) was worth it for increased performance. but also one of those problems that can annoy you to no end until you solve it—which hopefully I’ve (more or less) done for you. these values referred to the complete Frame window. I also wanted to be able to keep using Processing’s handy width and height properties. Normally. relative to the Frame window. methods. Processing uses float values. h-titleBarHt).EmbeddedP55. especially if I were creating a real reusable class. By default in Java. By default. I realize this is a pretty subtle point. thus. I passed in width and height values for the PApplet component to the EmbeddedP55 constructor. including the top menu bar.applet.

"*/ p55.exit(0).iragreenberg.EmbeddedP55. so I won’t bother putting it into a custom package. } } The Controller class is sort of the conductor class. in my example. Notice the import statements at the top of the Controller class. 0)).I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA // constructor public Controller() { // call to superclass needs to come first in constructor super("Frame with Embedded PApplet Component"). // won't allow frame to be resized setResizable(false). setLayout(new FlowLayout(FlowLayout.setVisible(true).. But hey! I’m an artist.. // add Applet component to frame add(p55). The first one import com. h). // allow window and application to be closed addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.ensures that the animation thread is started and that other internal variables are properly set. // Next comment taken directly from PApplet class: /* ". (Some Java purists—who believe fervently that all classes should be explicitly put in a package—might not like that. The Controller class is not designed to be a reusable class or something that would be included in a code library.LEFT. 0.init(). // set up frame (which will hold applet) setSize(w. You can also think about it as the stage for the code performance (so to speak) to take place.java) at the same location as the com directory. } }). } public static void main(String[] s){ new Controller(). h). // Instantiate Applet object Applet p55 = new EmbeddedP55(w.) Simply save the class (naming it Controller. C 17 .

and importantly. you can avoid having to use the full package address when referring to a class in the package. and java. the wildcard syntax (. You’ll put your PApplet object within the literal frame window. which should key you in that the Frame class will be the superclass to the Controller class.com/docs/books/tutorial/uiswing/layout/using. In fact.event. 18 . I set the size of the external window. Here’s a link to more about the art of laying stuff out in Java components: http:// java.P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T references the EmbeddedP55 class.*. The arguments I passed into the FlowLayout instantiation statement. the first call super("Frame with Embedded PApplet Component"). Because the Frame class organizes graphical elements. Java’s Frame class is referred to in the Java API as a “top-level window” class (see http://java. The FlowLayout class is another Java class.html.*.html.iragreenberg directory structure.com/j2se/1.com/javaworld/jw-07-1996/jw-07-awt. The next three statements import java. In the Controller class constructor.html). 0). layout issues are not trivial in Java.4. reference classes in existing Java packages that come with the Java JDK.applet.LEFT. If you plan on doing a lot of coding of Java UIs.awt. 0. seem to almost reference the same package. by including the import statements. I highly recommend getting a few good dedicated books on the subject (and perhaps one of those squishy balls for stress relief).awt. Remember. it is equipped with layout capabilities.awt.event. involving complexity beyond this discussion. is to the Frame superclass constructor. Notice that java.*.Applet. will (hopefully) ensure that the PApplet object is placed flush against the top and left edges of the frame window. Remember that packages begin with a lowercase letter and classes begin with an initial cap. import java. Next.sun. Remember. again not dissimilar to how a table works in HTML. saved within the com.2/docs/api/java/awt/Frame. Next. import java. any calls to super() need to occur first in the subclass constructor.*. notice that the Controller class declaration statement includes the extends Frame keywords.awt. new FlowLayout(FlowLayout. passing in a FlowLayout object. javaworld. passing in a String argument ("Frame with Embedded PApplet Component") used to title the window. not all the subdirectories in a package. Java’s Abstract Windowing Toolkit (awt) is a large and complex code library (12 overflowing directories chock-full of tasty code) devoted to constructing user interfaces in Java (a task not for the faint of heart). as well as the layout rule for the window.*) only refers to all the classes in a directory. You can learn more about it at www. Also. The difference is that the event directory is a subdirectory of awt (not a class in awt).sun.

let’s try running the program from the command line. and com. The line p55. I navigated. Using your terminal program. passing in the frame’s width and height. to the ig_java directory. navigate to where the Controller.) Next. } }).java file. You can of course put these calls on two separate lines if you prefer. like this: Controller c = new Controller() c. simply removes the default resizing handle in the bottomright corner of the window. C 19 . You of course also need admin rights to be able to compile and execute Java from the directory they’re stored in.jar archive. Now. (You can put the Controller. the line new Controller().jar archive at the same location.setVisible(true). Figure C-2 shows a screenshot of the ig_java directory.java class and com. not only calls the Controller class constructor. The line add(p55). gets your embedded PApplet running.iragreenberg directories anywhere you want on your system. iragreenberg directory are saved.exit(0). as long as they stay in the same relative position to each another. I created a directory called ig_java. literally adds the EmbeddedP55 object (also of type PApplet) into the outer frame. and as we looked at earlier. the class you wish to explicitly execute needs a main() method. which you’ll remember I use in the EmbeddedP55 class to size the embedded PApplet. within my Documents directory. On my system.init(). using my terminal application. and put everything in there. Finally. In the Controller class’s main() method. The line setResizable(false). The next block of code is necessary if you want users to be able to close the application (not just the window itself) by clicking on the window’s close button: // allow window and application to be closed addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System. core. I instantiated the PApplet object. You can eventually comment out this line if you’d like to be able to resize the window as the program runs. but also makes the frame visible.setVisible(true). You’ll also need to place a copy of the core. and Figure C-3 shows a screenshot of my terminal program.I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA Next.

P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T Figure C-2. iragreenberg (or whatever you named them) directories. enter the following command to compile: javac -classpath . Figure C-4. ig_java directory Figure C-3.:core. Terminal application showing the contents of ig_java directory Within the terminal program.jar Controller.java Successfully compiling should create a bunch of class files in your ig_java and com. ig_java directory after compiling 20 . Figure C-4 show a screenshot of my ig_java directory after compiling.

Figure C-5. The “$1” part of the name is not a typo.java class contains one anonymous inner class.jar Controller Congratulations. the anonymous class is the argument passed in the addWindowListener call: addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System. with embedded Processing PApplet 21 . but indicates that the Controller. you have just run your first Java graphics sketch with an embedded PApplet—woo hoo! Figure C-5 shows an output of this fabulous sketch. you need to include the classpath argument as well. } }). combining object instantiation of the class and the class declaration in the same statement. com/java/other/article.:core. which automatically got compiled.php/3300881. Notice how the instantiation call new WindowAdapter() is followed by a block of code.I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA Notice the class created named Controller$1. Anonymous classes by definition are classes without names. Next is the java command: java -classpath . C To run the application. In the Controller class. First Java graphics sketch. You can learn more about anonymous and inner classes at www. just like you did during compiling.developer.exit(0).class.

I’ll be building these applications. it’s got one button). in the ig_java directory. Swing also provides for some skinning capabilities of components. However. import java. I mentioned AWT earlier. there are some other Java widget toolkits.core. that is a nice idea. developed by IBM as an open source alternative to Swing. theoretically.java and Kite. I’ll create two new classes: KiteController. You can learn more about SWT at www. within the PApplet class. AWT components will look like the native windows on your respective platform.iragreenberg.org/swt/.or Swing-based GUI.org/reference/core/javadoc/ processing/core/PApplet.eclipse. Swing is another GUI (or widget) toolkit for Java that tried to expand and improve upon the limitations of AWT. import processing.processing. public class Kite extends PApplet { 22 . I’ll integrate the kite into a Swing layout.awt.” (See http://dev. Finally. You can learn more about Swing at http://java. Here’s Kite.sun. Of course. Probably the best known is the Standard Widget Toolkit (SWT).java class within the ig_java directory and I’ll put Kite. The surface is made to automatically update itself. while Swing components are completely written in Java. Thus.java within com.*. I’ve created a playful kite toy example that I’ll initially just plop in a frame. Well. Then I’ll add the kite PApplet into a slightly more sophisticated AWT application (all right. Fundamentally. allowing you to change the look and feel of the widgets. while Swing should look the same on all platforms. again. Besides AWT and Swing. On the Processing dev site. I’ll put the KiteController. Swing does allow a lot more sophisticated types of GUI controls to be (relatively easily) added to your applications.jar within the ig_java directory as well. Initially. To wrap up this appendix (as well as the entire book). as I did in the last example. the two toolkits are different in that AWT relies on the native windowing toolkit of your respective system. is a cautionary note about including Java GUI elements directly within Processing sketches: “You should not use AWT or Swing components inside a Processing applet. which apparently IBM found too sluggish. I’ll still need a copy of core.java: package com.) The note goes on to say that if you want to use AWT or Swing elements.com/docs/books/tutorial/uiswing/start/ index. and will cause problems with redraw of components drawn above it. but it doesn’t quite work as flawlessly as that.P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T Creating a simple GUI The last thing I want to briefly cover is how to integrate a Processing PApplet component within a graphical user interface (GUI).html. you should incorporate the PApplet component as a separate element within a larger AWT.*.java. providing some user control of a few of the kite’s parameters.html.iragreenberg (inside ig_java).

private Vect2D leadVel.05f.I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA // instance properties private Point2D dummy. feetVel[i] = new Vect2D(0. private Point2D[] feet = new Point2D[feetCount].1f. height/2). } public void setup(){ /* account for height of frame title bar. private int w. private float springSpdMin = .y + sin(theta)*botRadius).0f. float rad = 100. feet[i]. springSpdMax = . 2. private Vect2D[] feetAccel = new Vect2D[feetCount]. smooth(). frameRate(30).h = h.x + cos(theta)*botRadius. private Vect2D[] feetDelta = new Vect2D[feetCount]. dummy = new Point2D(width/2. 0). .length. h.y-dummy. springSpeed[i] = random(springSpdMin. ➥ dummy. private float[] springSpeed = new float[feetCount].0f). getBounds() returns a Java Rectangle object that has 4 public properties: (x. private float damping = .y). } } C 23 . dummyVel = new Vect2D(3.y. for (int i=0. private int feetCount = 4. 0). // set legs with some trig float theta = 0. feetDelta[i] = new Vect2D(feet[i]. feetAccel[i] = new Vect2D(0. leadVel = new Vect2D(. size(w. height/2). private Vect2D dummyVel. lead = new Point2D(width/2. i++){ feet[i] = new Point2D(dummy.65f.x-dummy. // constructor public Kite(int w.05f). theta += TWO_PI/feet.w = w. this. springSpdMax). private Point2D lead. i<feet. when sizing applet.04f. width and height) */ int titleBarHt = getBounds().x.length. private Vect2D[] feetVel = new Vect2D[feetCount]. int h){ this. private float botRadius = 45.9f. y. h-titleBarHt).

feet[0]. } public void moveBot(){ Vect2D[] feetMotionDelta = new Vect2D[feetCount]. feetAccel[i].vy)*springSpeed[i]). feet[i+1]. for (int i=0.vx.y).y = mouseY + sin(rotAng)*200.P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T public void draw(){ background(255). i++){ feetMotionDelta[i] = new Vect2D((dummy.y+feetDelta[i].length.x. if (i<feet.x = feetVel[i]. feet[i+1]. feet[i]. i<feet. feet[0]. i<feet.vy. feet[i]. float rotAng = atan2(mouseY-(height+100).y = feetVel[i]. feetAccel[i].y. feet[i]. moveBot().vy. } } /* two simple inner classes to help keep things semantically clear */ 24 . dummy.vx += feetAccel[i].vy *= damping.y-feet[i].x+ ➥ feetDelta[i].vx+= feetMotionDelta[i]. mouseY. mouseX-width/2).y). fill(0).x. i++){ line(dummy.length-1){ line(feet[i].vy+= feetMotionDelta[i].length. } else { line(feet[i]. feetAccel[i].x. feet[i].y). dummy.x-feet[i].y. for (int i=0. drawBot(). } public void drawBot(){ rectMode(CENTER). feetAccel[i]. feetVel[i].vx *= damping.x = mouseX + cos(rotAng)*200.vx .x. feetVel[i]. } } line(mouseX. dummy.vy .x.vy += feetAccel[i]. feet[i].y. feet[i].y).x.vx.vx)*springSpeed[i]. fill(255). dummy.x. (dummy. dummy.

vy. java. 0)). // Instantiate Applet object Applet kite = new Kite(w. Point2D(float x.applet.event.vx = vx.awt.awt.*. // constructor public KiteController() { // call to superclass needs to come first in constructor super("Go Fly a Kite"). // won't allow frame to be resized setResizable(false). h = 422. h). y.java class: import import import import com. Next is the KiteController.iragreenberg.LEFT. // set up frame (which will hold applet) setSize(w. } } } This class doesn’t include any new concepts. float y){ this.Kite.x = x. java.y = y. this. so I’ll leave it to you to sort out the Processing code. Vect2D(float vx.*.I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA class Point2D{ float x.vy = vy. The simple springing physics in the class is based on the springing example I included in Chapter 11 (inspired by Keith Peters). java. // add Applet component to frame add(kite). h). } } class Vect2D{ float vx.Applet. 0. float vy){ this. this. 25 . setLayout(new FlowLayout(FlowLayout. C public class KiteController extends Frame { private int w = 400.

Initial Kite application in a single window 26 .. } } You’ll compile this program following exactly the same structure you did with the last program.P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T // allow window and application to be closed addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System. } }).:core. // Next comment taken directly from PApplet class: /* ".jar KiteController Figure C-6 shows the initial output of the Kite application in a single window.ensures that the animation thread is started and that other internal variables are properly set.:core.java And the Java command to run it also follows the same structure: java -classpath ."*/ kite.. The compile command is as follows: javac -classpath . Figure C-6.init().exit(0).setVisible(true). } public static void main(String[] s){ new KiteController().jar KiteController.

CENTER).awt. // set up frame (which will hold applet) setSize(w.I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA Building an AWT-based GUI Next. // import java. 27 .event. 100.awt.exit(0).java code.applet. with the changes displayed in bold: import com. int buttonH = 50.setBounds(0.Kite. import java. add(b. setBackground(new Color(100.*. import java.SOUTH). public class KiteController extends Frame { private private private private Button b.*.iragreenberg. I’ll add a button to the bottom of the application that will increment the number of sides to the kite each click. 100)). // allow window and application to be closed addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System. BorderLayout. h-buttonH). // add Button b. h = 422. BorderLayout. 0. // add Kite object component to frame add(kite.Applet. // Instantiate Kite object kite = new Kite(w. C // constructor public KiteController() { // call to superclass needs to come first in constructor super("Go Fly a Kite"). buttonH). h). w. setLayout(new BorderLayout()). int w = 400. Here’s the revised KiteController. // create Button b = new Button("Increase Kite Sides"). // won't allow frame to be resized setResizable(false). Kite kite.

setVisible(true). } public static void main(String[] s){ new KiteController().length. // add to Kite. springSpeed[i] = random(springSpdMin. 0).x + cos(theta)*botRadius. float rad = 100.. } } Next. } } 28 .java class. feet[i]. } }).y + sin(theta)*botRadius).setFeetCount(1).P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T } }). feetAccel[i] = new Vect2D(0. but (of course) it shouldn’t be put within another method. feetDelta[i] = new Vect2D(feet[i]. The method can be put anywhere within the class.x."*/ kite. feetVel = new Vect2D[feetCount]. Add the following method to the Kite. springSpdMax). I’ll update the Kite. feet = new Point2D[feetCount]. i++){ feet[i] = new Point2D(dummy. // Next comment taken directly from PApplet class: /* ".java // dynamically change kite parameters public void setFeetCount(int val){ // reinitialize arrays feetCount += val.x-dummy. for (int i=0. feetDelta = new Vect2D[feetCount]. b.y-dummy. // reset values float theta = 0. i<feet. theta += TWO_PI/feet.init().length.ensures that the animation thread is started and that other internal variables are properly set.java class.. feetAccel = new Vect2D[feetCount].y). springSpeed = new float[feetCount]. ➥ dummy. 0).addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { kite. a setFeetCount(int val) method. which only gets one new addition. feetVel[i] = new Vect2D(0.

Enjoy. AWT application Building a Swing-based GUI Finally.I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA I’ll leave it to you to compile and run this example.swing.don't need anymore // new import javax. public class KiteController extends JPanel { private int w = 600.*.awt. I recommend doing a little API diving at http://java.*. 29 . so I include the full code. . // updated KiteController. I’ll also leave it to you to decipher the new AWT code I added.swing.java and Kite. C Figure C-7. import javax. and happy creative coding. //import java.iragreenberg. private Kite kite. h = 422. it’s actually pretty straightforward. import java. I’ll leave you with a Swing-based GUI example.awt.*.Kite. (Hint: Just use the same two commands you used for the previous example. There were lots of changes. Following are the updated KiteController.java classes.event.java class import com.sun.event.4.) The output is shown in Figure C-7.com/j2se/1.2/docs/ api/.*. If you get stuck. I’ve added comments throughout and tagged the new stuff I added.

createTitledBorder("Kite Sides")). rtPanel. js1.setMajorTickSpacing(30). JLabel jl = new JLabel(" Drag the Kite String").setPaintLabels(true). js0.setBorder(BorderFactory.setPaintLabels(true).HORIZONTAL.setMajorTickSpacing(12). 180.setRadius(slider. 100.setMinorTickSpacing(1).setPaintTicks(true).createTitledBorder("Kite Radius")). 220)).getSource(). 3. if (!slider. // right tools pane JPanel rtPanel = new JPanel(). } } } ). 40). 400). js1.HORIZONTAL. 63.setBorder(BorderFactory. ➥ BoxLayout. // Instantiate Kite object kite = new Kite(400.setPaintTicks(true). // handle js0 change events js0. // kite radius slider JSlider js0 = new JSlider(JSlider. rtPanel. 30 .addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent evt) { JSlider slider = (JSlider)evt.getValue()). js0. js0. /* create 2 pane across layout left pane holds processing PApplet right pane holds user widgets */ setLayout(new BoxLayout(this. BoxLayout. // kite sides slider JSlider js1 = new JSlider(JSlider. 4). js0.P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T // constructor public KiteController() { setBackground(new Color(180.setOpaque(false). js1.setMinorTickSpacing(4).getValueIsAdjusting()) { kite. js1. 10.setLayout(new BoxLayout(rtPanel. js0. js1.LINE_AXIS)).PAGE_AXIS)).

} 31 .getValue()/20.HORIZONTAL. js2. // handle js3 change events js3. 4).getSource(). js2. 1.0f).addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent evt) { JSlider slider = (JSlider)evt.getValueIsAdjusting()) { kite. // spring speed slider JSlider js2 = new JSlider(JSlider. } } } ). } } } ).createTitledBorder("Spring Damping")). js3.setSpringDamping(1. js3.setMajorTickSpacing(1).setMinorTickSpacing(1).createTitledBorder("Spring Speed")). 1.getValue()).setSpringSpeed(slider.getValue()/30. 10.0f).getSource(). js2.setPaintLabels(true).setPaintTicks(true).addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent evt) { JSlider slider = (JSlider)evt. // handle js2 change events js2.setMajorTickSpacing(3). js3. if (!slider.HORIZONTAL.slider. C // spring damping slider JSlider js3 = new JSlider(JSlider.setBorder(BorderFactory. js2. js2. js3. js3.getValueIsAdjusting()) { kite.getSource(). 10. if (!slider.setBorder(BorderFactory.getValueIsAdjusting()) { kite.I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA // handle js1 change events js1. if (!slider.setFeetCount(slider.setMinorTickSpacing(1).0f .setPaintLabels(true).addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent evt) { JSlider slider = (JSlider)evt.setPaintTicks(true). 5).

// add a little margin on right of panel add(Box.setVisible(true). // Next comment taken directly from PApplet class: /* ". // make frame visible jf. // assemble tools pane rtPanel.10))).EXIT_ON_CLOSE)..add(Box.createRigidArea(new rtPanel.setDefaultCloseOperation(JFrame.createRigidArea(new Dimension(4.pack().8)))."*/ kite. Dimension(0. Dimension(0.createRigidArea(new rtPanel.getContentPane().add(Box.8))).8))).ensures that the animation thread is started and that other internal variables are properly set.add(js1).createRigidArea(new rtPanel. Dimension(0.add(js3). rtPanel.setResizable(false). // keep window from being resized jf. // add panes to larger JPanel add(kite).add(Box.add(js0). } 32 . rtPanel.add(new KiteController()). // create some space between panes add(Box. rtPanel.createRigidArea(new rtPanel.init().P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T } } ).0))).add(jl).0))). } // create external JFrame private static void createGUI() { // create new JFrame JFrame jf = new JFrame("Kite Swing Application"). // size frame jf. // You add things to the contentPane in a JFrame jf. // this line allows program to exit jf.createRigidArea(new Dimension(4.. rtPanel. add(rtPanel).add(js2). Dimension(0.add(Box.

private Vect2D leadVel.core. private float[] springSpeed = new float[feetCount]. //NEW private int stringBaseX. } } ). private float damping = .h = h. private Point2D[] feet = new Point2D[feetCount]. package com.java class.*. private int stringBaseY. this. public class Kite extends PApplet { // instance properties private Point2D dummy. private Point2D lead. private Vect2D[] feetVel = new Vect2D[feetCount]. private Vect2D dummyVel. C // constructor public Kite(int w. private int w.05f. A screenshot of the final Swing GUI is shown in Figure C-8. } 33 . import processing. private float botRadius = 45.iragreenberg. private int feetCount = 4. private Vect2D[] feetAccel = new Vect2D[feetCount]. int h){ this.awt.9f. springSpdMax = .1f.w = w.*.invokeLater(new Runnable() { public void run() { createGUI(). import java.0f. private float springSpdMin = .I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA public static void main(String[] args) { // Recommended way to create a Swing GUI javax. } } Following is the updated Kite. h. private Vect2D[] feetDelta = new Vect2D[feetCount].SwingUtilities.swing. private float theta = 0.

feet[i]. i<feet. feet[0]. // NEW stringBaseX = width/2. height/2). 2. // set legs with some trig for (int i=0. dummyVel = new Vect2D(3.y + sin(theta)*botRadius). feet[i]. feet[i]. h-titleBarHt). // NEW dummy = new Point2D(width/2. i++){ feet[i] = new Point2D(dummy. feetVel[i] = new Vect2D(0. feet[i+1]. drawBot().y).x.y. 34 . size(w.y.length.x + cos(theta)*botRadius. springSpdMax).x. 0).x-dummy.y. } else { line(feet[i]. } public void drawBot(){ rectMode(CENTER).y). feet[i].04f. feetDelta[i] = new Vect2D(feet[i]. feet[0].x. 0).P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T public void setup(){ /* account for height of frame title bar. for (int i=0.y). fill(0). height/4).x. lead = new Point2D(width/2. ➥ dummy. stringBaseY = height. . width and height) */ int titleBarHt = getBounds(). } } public void draw(){ background(255). i++){ line(dummy. leadVel = new Vect2D(.y. i<feet. if (i<feet. feetAccel[i] = new Vect2D(0.y).y-dummy. dummy. getBounds() returns a Java Rectangle object that has 4 public properties: (x.length. feet[i+1].x.length.length-1){ line(feet[i].05f). theta += TWO_PI/feet. smooth(). springSpeed[i] = random(springSpdMin.0f). when sizing applet.x. frameRate(30). moveBot().65f. y.x. feet[i].

vy+= feetMotionDelta[i].y = feetVel[i].vy .vy += feetAccel[i].length. dummy.x-feet[i].x+ ➥ feetDelta[i]. feet[i]. float rotAng = atan2(mouseY-(height+100).vx+= feetMotionDelta[i]. feetVel[i].vx. feet = new Point2D[feetCount].vx += feetAccel[i]. feetAccel[i]. //NEW if (mousePressed){ dummy. C 35 . dummy. feetDelta = new Vect2D[feetCount]. feetVel = new Vect2D[feetCount]. } fill(255). feetAccel[i].y+feetDelta[i]. (dummy. i++){ feetMotionDelta[i] = new Vect2D((dummy. i<feet.vx)*springSpeed[i]. } } } // dynamically change kite parameters public void setFeetCount(int val){ // reinitialize arrays feetCount = val. feetVel[i].vy. feetAccel[i].vx . feetAccel[i].y). for (int i=0. dummy. } public void moveBot(){ Vect2D[] feetMotionDelta = new Vect2D[feetCount]. stringBaseY.y-feet[i].y = mouseY + sin(rotAng)*200.vy *= damping. springSpeed = new float[feetCount].I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA } } // NEW line(stringBaseX. stringBaseY = mouseY.vx *= damping. feetAccel = new Vect2D[feetCount].vy.x = feetVel[i]. feet[i]. if (mousePressed){ stringBaseX = mouseX.vy)*springSpeed[i]).x = mouseX + cos(rotAng)*200. mouseX-width/2).vx.x.

i++){ feet[i].y-dummy. for (int i=0. 0).P R O C E S S I N G : C R E AT I V E C O D I N G A N D C O M P U TAT I O N A L A R T // reset values float theta = 0.length.length.y = y.length.y-dummy.x. feet[i]. feetDelta[i]. ➥ dummy. i<feet.x = x.x. i<feet. } } 36 .vy = feet[i].y = dummy. Point2D(float x. feetVel[i] = new Vect2D(0. i++){ springSpeed[i] = random(springSpdMin. } } // NEW public void setRadius(int val){ botRadius = val.length.vx = feet[i]. feetDelta[i].length. springSpdMax). val).x + cos(theta)*botRadius. float y){ this. } /* two simple inner classes to help keep things semantically clear */ class Point2D{ float x. i<feet. feetDelta[i] = new Vect2D(feet[i]. i++){ feet[i] = new Point2D(dummy. this.y. 0). feet[i]. feetAccel[i] = new Vect2D(0.x-dummy. y.x-dummy.y + sin(theta)*botRadius. } } // NEW public void setSpringDamping(float val){ damping = val.y). theta += TWO_PI/feet. } } // NEW public void setSpringSpeed(float val){ for (int i=0.x + cos(theta)*botRadius. for (int i=0.x = dummy.y + sin(theta)*botRadius). theta += TWO_PI/feet. springSpeed[i] = random(springSpdMin.

this. Vect2D(float vx.vx = vx. float vy){ this. Swing application 37 .I N T E G R AT I N G P R O C E S S I N G W I T H I N J AVA class Vect2D{ float vx.vy = vy. } } } C Figure C-8. vy.