set data folder location for PApplet triggered through runSketch - java

I'm running a Processing sketch (a PApplet subclass, created by exporting from a Processing sketch) from Clojure. The basic process is
export sketch
locate jar files in exported application
install these jar files into local maven repo
load the libs in clojure using lein
The code is in this GH repo, including (reasonably) minimal instructions for how to get set up and reproduce the problem.
Loading basic sketches works, but when I create a sketch which calls e.g. loadImage() to load an image from my data folder, the sketch can't find it.
I know this is convoluted way to do this - this is partially a learning exercise for me and partially the fact that I'm a lisp guy but not a JVM guy.
Is there any way to dynamically tell the PApplet subclass where its data folder is? Or am I stuck putting absolute paths everywhere?
EDIT: Ugh, what a mess. It looks like the problem is that I'm actually wrapping each PApplet subclass in a clojure proxy (so that I can intercept certain methods and make the various sketches play nice together) but the way Processing finds the data path involves looking at the ProtectionDomain to find the root source path, so this won't work as I'm currentyly trying it. Back to the drawing board...

So you're using maven to link to jars you've exported from Processing, and those jars can't find the sketch directory?
If I were you, I would look int two places:
The Processing JavaDoc contains a detailed reference on every variable and function in Processing. Particularly check out the PApplet class and check out the following:
ARGS_SKETCH_FOLDER
selectInput()
selectOutput()
sketchFile()
sketchOutputPath() and sketchOutputStream()
sketchPath()
I would bet that by either setting the first variable or by overriding some of those functions, you can have Processing look wherever you want.
If you need more detail, the Processing source will tell you exactly how Processing uses all of the above.

Related

What are best practices for coding filepaths in java applications intended for distribution?

I've mostly only created application for personal use and the rare occasions where I have distributed my code have been in the form of uploading my source code on GitHub. I'm currently finishing up a project and plan on using launch4j to package it up as an exe. However, my application has a handful of png files that I coded in with the unique filepath of my computer. Obviously if my code were to run on any other computer in the world, those files would not be found.
I'm vaguely aware that java does not require the full filepath for a file (ie C:\Users...\file_name.ext) but I've never gotten a program to run correctly unless I write out the filepath like that, so that's been my default up until this point.
The resource system. Think about it: What's the difference between the many class files that comprise your application, and those png files, from an application distribution perspective?
The answer is, essentially, nothing. They are file-like concepts, they might prefer to be shipped in a packaged-up file (a jar file) instead of separately. They must be found at some point halfway through your app's existence (java does not pre-load all classes. It just loads your main class, and then loads whatever is needed the first time you mention any class).
You don't have to hardcode the absolute path to those class files in your app, so they clearly don't suffer from this 'coding filepaths' issue.
Thus, the answer is somewhat obvious: Simply stick those PNG files in the exact same place as your class files, and ask the VM to provide you with the data in them using whatever mechanism it is using itself, as it is doing that exact same job (find resource, obtain data in the resource) all the time, on your class files.
But, how?
You have 2 different methods, and these 2 methods take the same kind of argument, which comes in 2 forms: A grand total of 4 'modes' to choose from.
Pick a method
If the API you have that needs an image file so happens to have an overload that accepts a URL, this is very simple (ImageIcon is one such resource, that's probably what you're passing these PNG files to, so that's great):
URL loadIcon = ContextClass.class.getResource("/icons/load.png");
new ImageIcon(loadIcon);
Quite simple. Sometimes you want to read it yourself directly, and a URL object is rather unwieldy. Sometimes, you want to pass it to an API which does not have a URL overload, but it does have an InputStream overload. Then, you can fetch an InputStream. Given that this is a resource, like all resources, you must safely close it, thus, let's use try-with:
byte[] pngData;
try (var in = ContextClass.class.getResourceAsStream("/icons/load.png")) {
pngData = in.readAllBytes();
}
ContextClass.class is a somewhat exotic java syntax feature: It is an expression that resolves to the java.lang.Class instance of the so-named class. For example, Class<?> c = String.class; is legal java and gives you the class object that represents the class concept of all java.lang.String objects. The class object itself has these getResource methods. Thus, substitute some relevant class that you wrote as context here. Presumably, if you want to load an image in source file MyStatusWindow.java, you'd just use that class: MyStatusWindow.class.getResource.
These methods will look in the same location that the class itself was loaded from. If ContextClass is loaded from a jar, then the system will fetch PNGs from within that jar. If it's loaded from a build dir during development/debug, the png is loaded from there. If you've got some fancypants module system that is loading classes straight from the network, then the PNG will also be loaded from there.
resourceKey
A resourcekey is simply a path. It's not really a path, just - a string with slashes. You can't use .., for example, it's not really a path. You also, weirdly, can't use filenames that include more than a single dot in the name, for historic (read: silly) reasons.
You have 2 variants - classpackage relative and absolute.
.getResource("/icons/load.png") is absolute. .getResource("icons/load.png") is relative. The leading slash is the difference.
If you have:
package com.foo;
public class MyStatusWindow {
...
MyStatusWindow.class.getResource("icons/load.png");
}
And this is all in a jar file (i.e. /com/foo/MyStatusWindow.class is one of the entries listed if you execute jar tvf myapp.jar on the command line), then the above would look in that jar for /com/foo/icons/load.png - the relative form takes the context-class's package and sticks it in front. The absolute form would just look in /icons/load.png, still in the jar (so it's never C:\ - never the root of your disk - it's the root of the classpath entry).
Build systems
Maven, Gradle, and just about every other build system has a proscribed directory structure. The above example should go in src/main/java/com/foo/MyStatusWindow.java, relative to some 'root project dir'. Only java source files are supposed to go there. There's also a resources: src/main/resources/com/foo/icons/load.png, that's where your icon file would go. Then MyStatusWindow.getResource("icons/load.png") will just work, in your build system, and in your IDE, and when you ship it all as a jar file. If it doesn't, you've misconfigured your IDE or have a broken build configuration - and you should fix that. Out of the box, this just works.

How do you reference an OpenGL shader file that is located within a separate library jar file?

I am trying to build a game engine from scratch by following various tutorials using Java, LWJGL, and OpenGL. My current plan, is to follow each tutorial, generating the code they teach, until I have working code. Step 2 is to re-organize, rename, document, and otherwise move stuff around until it matches my specific coding style.
Each new subject, is then packaged up nice and neat in its own project, which is then turned into a library .jar file.
That way I can create a new program, add a few specific library .jar files for "2D Text" or "particle effects" to add new features to my game as needed without a ton of copy and pasting between projects, or importing a super large library into a program that isn't going to use all aspects of it.
Now, here is the part I can't figure out. Most OpenGL rendering with the programmable pipeline uses shaders. If I locate the shaders within my new program, everything is fine. I reference the shaders using the "src/Shaders/shaderEntity.vert" file path.
However, If I want everything nice and neat, and reusable, I should locate those shaders within the library .jar file with the rest of the classes for that feature.
How do I reference a shader file, within another .jar file? The library .jar file itself is located in "dist/lib/myJarFile.jar" and would be in the "/Shaders/shaderEntity.vert" location within the .jar file.
Or is this a bad idea and I should continue locating my shaders within the new programs?
A shader doesn't have to be read from a file. OpenGL, or more specifically glLoadShader takes the source code of your shader as a string.
I'm don't know much about .jar files (and have limited experience with the rest of Java) but the goal is to store it in the .jar in some way that you can read it out as a string to pass to OpenGL. That might mean changing your class to take in the source code string and loading that string from the .jar elsewhere, or taking in 2 paths (or one string with a divider, e.g. dist/lib/myJarFile.jar:/Shaders/shaderEntity.vert) that provide the exact path to the file, and the class will then open up the file within the .jar and read from it.

Use Processing PDE files within Java?

I have a working Java code that I would like to visualize using processing. I also found the tutorial on how to include processing within eclipse and am also already able to create a canvas, etc.
What I want to do now is to actually do the visualization. I found a nice project that is exactly what I need. However, the author provides PDE files.
How can I include PDE files in my java project? Is that even possible?
The PDE files that are available in that project are simply text files. You can either use them in your code directly, or better yet, try to understand what they're doing and adapt the code to your own purposes.
But to answer your question, you don't include PDE files in a Java project. You included the Processing library jars on your classpath, which give you access to things like the PApplet class. Then you can include a PApplet (which is just like a Processing sketch, in fact a Processing sketch is a PApplet) in your Java application and pass it whatever information you want.
More info here: http://processing.org/tutorials/eclipse/

Unable to import image resources into our GUI

I'm working on a project with some friends over Github for a University project. I've only just taken my friends code off the repository for the first time. For some reason, all references to images in the code don't seem to allow compilation due to a directory problem I think. I'm using Eclipse, my friend's using Netbeans(don't know if that affects it or not?). Anyway, all of the images referenced are either in a folder known as runone, on the same level as the Eclipse src, or within the package 'runone' within src. I don't know which.
Here's an example of some of the references:
jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/runone/OSTeeeennny.jpg")))
jLabel53.setIcon(new javax.swing.ImageIcon(getClass().getResource("/runone/clown_fishTIny.jpg")));
I guess what I'm wanting to know is, how can I make these resources work correctly, on any machine that we code this program on?
Hope that all made sense!
For the examples you have given your file structure might look like this
src/com/yourpackage/YourClass.java
src/runone/OSTeeeennny.jpg
src/runone/clown_fishTIny.jpg
For a more best practice way of organizing your resources you could do this
src/com/yourpackage/YourClass.java
src/com/yourpackage/resources/OSTeeeennny.jpg
src/com/yourpackage/resources/clown_fishTIny.jpg
and then use the following calls to load them
getClass().getResource("resources/OSTeeeennny.jpg")
getClass().getResource("resources/clown_fishTIny.jpg")

Flex Compiler Api: Adding images in Java

I have a very specific question.
I want to compile an ActionScript project within Java in-memory with the help of the Flex Compiler API ( http://livedocs.adobe.com/flex/3/compilerAPI_flex3.pdf ).
My last problem is to add images (jpg, png) that are embedded in the project to the compiler. I donĀ“t see a possibility to do this in-memory and my attempt to add them from disk was also unsuccessful.
Hope someone has a good hint for me.
Greets, Konsumierer
Invoking the flex compiler from java shouldn't be any different from invoking it from the eclipse plugin. I suppose you have the project located somewhere on the filesystem, so I suppose if the images are in the correct relative path, they should be embedded. How do you embed them, actually?
Another option is, in case when you use them in web-environment (and not AIR), to just write a relative server path to the image. For instance - the .swf is in /, you can poing the image to /images/myimage.jpg, and it will work.

Categories

Resources