We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › Reflective Programming
Page Index Toggle Pages: 1
Reflective Programming? (Read 402 times)
Reflective Programming?
Mar 10th, 2008, 5:31pm
 
Has anyone done any reflection stuff using java.lang.reflect?  I have been trying some out, but can't get it to work, possibly because of the way Processing wraps the pure Java, and how that might affect scope & names(?)


This was taken & modified from a sun.com example, and throws an error:
Code:

import java.lang.reflect.*;

class Foo {
public float data;
Foo(){ data=22.22; }
}


void setup(){
size(100,100,P3D);
}


void draw(){

noLoop();
Foo testFoo;//=new Foo();

try {
//Class cls = Class.forName("Foo");
Class cls = Class.forName("testFoo");
Field fld = cls.getField("data");
Foo f2obj = new Foo();

println("data = " + f2obj.data);
fld.setFloat(f2obj, 12.34);

println("data = " + f2obj.data);
}
catch (Throwable e) {
System.err.println(e);
}

}



The reason for desiring reflective stuff is I want to be able to set variable values based on their names.  This way I can bind the variable to description, key, midiNote, clamp values, all at once with a custom ParameterControl object.

Hope this makes sense.  Thanks!
Re: Reflective Programming?
Reply #1 - Mar 10th, 2008, 7:26pm
 
In processing everything gets wrapped into a class that extends PApplet, so your Foo class is actually an inner class of another class, so there's no "Foo" class for it to find.

Re: Reflective Programming?
Reply #2 - Mar 10th, 2008, 11:02pm
 
@JohnG, I may have missed your point, but that didn't answer the question.

Inner classes can be tricky. The naming of them (I think) is determined by the JDK implementation & memory adresses.

But, there is a solution!

In Processing IDE, the classname of your papplet implementation is just the name of the sketch.

Code:

import java.lang.*;
class Foo{

}
void setup(){
try {
Class thisApplet = getClass();
Class[] innerClasses = thisApplet.getDeclaredClasses();
System.out.println(Arrays.toString(classes));
} catch (Exception e){
e.printStackTrace();
}
}


Worked for me, printed:
[class Temporary_9270_9023$Foo]
Re: Reflective Programming?
Reply #3 - Mar 10th, 2008, 11:48pm
 
OK, I can get a list of all the inner classes and fields.  Thanks for the example.  However, what I'm trying to do is actually SET main applet class fields (ie Processing "global" variables) whose names are known at run-time.  

But from what I can see, these fields always come up with a name like "Temporary_453_3285.data" where the numbers are always different.

So would there be a way to set these fields without having discover/generate "Temporary_xxx_xxxx."
Re: Reflective Programming?
Reply #4 - Mar 11th, 2008, 5:11am
 
Sorry, here's a better example.
(long story short, you want "getSimpleName()")

Code:

import java.lang.reflect.*;

static class Foo{
public static int MY_ID;
public String toString(){
return MY_ID+"";
}
}

//I realized I don't really understand your purpose, but this SHOULD help.

void setup(){
Class myC = getClass(); //Returns applet class
Class[] inner = myC.getDeclaredClasses(); //Contains Foo
for(Class c : inner){ //java 5.0 syntax, you can change.
if(c.getSimpleName().equals("Foo")){ //Not toString()!!!
InitializeParams(c);
break;
}
}
System.out.println(Foo.MY_ID);
}
void InitializeParams(Class fooClass){
try {
Field data = fooClass.getField("MY_ID");
data.setInt(null,3);
} catch (Exception e){
e.printStackTrace();
}
}


So, this takes static inner classes, and sets the field "MY ID" to 3. the 3 could be read from the applet getParameters that the webpage passes it.

However, the example I realized is ridiculous: if its an inner class, why can't you just set the field? like Foo.field = 3? I'm assuming you have a greater need for this, and I hope I helped.

night.


edit: By the way, there is always this neat little idea.

You have a "Note" object, and it has a pitch field. But you don't really care, much. You just know it has a field NAMED "pitch" and that it holds a float.

So,

public static void setPitch(Object note, float val){
   Class type = note.getClass();
   Field pitch = type.getField("pitch"); //We hope
   pitch.setFloat(note,val);
}

erm... you might have already known that though Tongue
Re: Reflective Programming?
Reply #5 - Mar 11th, 2008, 10:44pm
 
Nice!  Yes the last thing you added helped me get to exactly what I wanted.  Here is the code that demonstrates exactly what I'm trying to do:
Code:

import java.lang.*;
import java.lang.reflect.*;

class Foo{
public float data; //MUST BE PUBLIC
Foo(){ data=1.001;}
}


Foo f=new Foo();
public float data=100.1; //MUST BE PUBLIC

void setup(){
size(200,200,P3D);
}

void draw(){
noLoop();
println(data+" , "+f.data);
setField(this, "data", PI);
setField(f, "data", PI);
println(data+" , "+f.data);
}


public static void setField(Object o, String fieldName, float val){
Field anyField;
Class theClass=o.getClass();
try{
anyField = theClass.getField(fieldName); //We hope
anyField.setFloat(o,val);
}
catch (Exception e){
e.printStackTrace();
}

}



With this method, I can consolidate my code by hundreds of lines.  I can define a class like this:
Code:

class ParameterInfo{
//vars here
ParameterInfo(description, variableName, keyBoard, lowerLimit, upperLimit, incrementAmt, midiCC, includeInSave){
...

}

tmp=new ParameterInfo("any program variable", "var", 'x', 0, 1, .1, 33, false);

So I can use an array of these ParameterInfo objects for everything: keybd input, midi input, saving patches, generating on-screen key reference.  Or to randomize all parameters, I can just loop thru all ParameterInfo objects, setting their target field to a random value in their lower/upper range.  Etc..

And I only have to change values in 1 place to update the system.  

thanks!
Page Index Toggle Pages: 1