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 › Dynamic class naming
Pages: 1 2 
Dynamic class naming (Read 6145 times)
Dynamic class naming
Jan 5th, 2010, 10:35pm
 
hi there

i'm looking for a way to dynamically call a bunch of classes.
the classes are all differently named, and extending a base class. eg myClass1, myClass2, etc. would extend a Main class in order for me to use polymorphism.

so i can't use an array object.

based on a specific variable i want to dynamically load in that class.
in old Flash days i could do something like eval("myClass"+x)

so i've got something like this:

dynamicClass Main;
dynamicClass = new myClass1(); // myClass extends Main

...then later i want to swap it out with
dynamicClass = new myClass2();
dynamicClass = new myClass3();
etc. where the class number is being generated according to certain conditions, x=n; so i would want to call:
dynamicClass = new "myClass"+x(); which is obviously not going to work.

the classes need to be differently named because they all sit in the same directory, among other reasons.

any ideas?

cheers

Re: Dynamic class naming
Reply #1 - Jan 5th, 2010, 11:17pm
 
I suggest reading this whole topic: http://processing.org/discourse/yabb2/?num=1262409635
Re: Dynamic class naming
Reply #2 - Jan 6th, 2010, 12:21am
 
What differentiates the classes?  What you refer to in Flash was something commonly done with MovieClips; but there may be a better way in this instance, depending on what your multiple classes are meant to be doing...
Re: Dynamic class naming
Reply #3 - Jan 6th, 2010, 1:43am
 
A possible solution is to use a good old switch()...
You can also use reflection, but that's using a hammer to push in a pin.
Re: Dynamic class naming
Reply #4 - Jan 7th, 2010, 1:13am
 
hi
thanks for the answers.

but still nowhere near what i my mind should be a simple thing to accomplish.

what i'm actually looking for is a way of building dynamic variables

let me explain more.
there's a folder of classes - maybe 100s, that each do specific mostly unrelated things.
The Main class is the interface, and holds a bunch of common methods.

i don't want to load all the classes in at the start because among other reasons there are too many.

The App chooses a class and loads it in.
In the flash paradigm this would be the equivalent of loading in an external .swf

but.... the name of the class called is dependent on input (lets for arguments sake say the person presses a key).

so say someone presses the letter 'A' then i want to load in myClass65
or 'B' and then i want to load in myClass65, etc.

so classToLoadIn = new "myClass"+x(); // where x is the keypress value

so what i'm really looking for not only a classLoader solution but also a way of dynamic class/variable naming

been reading and seems in Java it is something like this:
Class c = Class.forName("Test" + className);

but forName doesn't work in Processing

hope this makes sense. any help much appreciated


 
Re: Dynamic class naming
Reply #5 - Jan 7th, 2010, 1:35am
 
Quote:
i don't want to load all the classes in at the start because among other reasons there are too many. [...] the equivalent of loading in an external .swf

This should not be a problem. You can have hundred, or even thousand of classes loaded, it shouldn't make a difference for Java. Unless it is huge, a class is rarely more than a few dozen of KB, and they are compressed in the jar file.
You would have to hard time to make 1MB of (uncompressed) classes, and that's still not much by modern standards, even for an applet.
So, no need for loading a separate file.

If by "load" you mean "make an instance", indeed you don't need to do that.
As I wrote, you can use switch:
Code:
Object classToGet = null;
switch (keyCode)
{
case 'A': classToGet = new Class65(); break;
case 'B': classToGet = new Class66(); break;
case '/': classToGet = new Class65(someParam); break;
}
Re: Dynamic class naming
Reply #6 - Jan 7th, 2010, 2:00am
 
I've been doing a lot of Flash programming myself, so I know what you are talking about, when you talk about dynamic naming. I do think, though, that you need to explain better what you want to achieve, and not so much how you could have done that it Flash, since Flash has a totally different way of handling those things, at least it used to do. So when you talk about 'a bunch of classes' and "The App chooses a class and loads it in" ... what do you intend these classes to do? As far as I know, a 'class' doesn't do anything, but they will let you create objects (movie clips if you like), and these objects can be called dynamically, typically through the use of arrays. For example, say you make a class called cars. Then you make an array called myCars[]. This array can hold any number of cars, and each car can hold different properties/values like speed, price, color, etc, etc, ... (To be honest, this is maybe one of the harder concepts to grasp, coming from the Action Script side of town, going over to Processing/Java/OOP). Each of these cars can in turn be 'called' individually by saying myCars[10].speed = 100; ...or myCars[3].drive(); So you see, the dot syntax that works in AS, also works here. It is generally preferred, I believe, to use methods over dot syntax though, so instead of myCars[10].speed = x, you would have a method, and say myCars[10].setSpeed(10). If you want to have something else, rather than a car, then you should make another class, maybe called vehicles, where you define different types of vehicles. I think processing/java is more than capable of giving you what you want, but you need to define better what you want to accomplish, and not think too much about how you did it in Flash, because that will make things a lot harder. I have a suspicion you will not be too happy with this answer either, but please keep asking, and I am sure we will get closer to what you need. Have you read any tutorials on classes, methods, objects, inheritance, OOP, method overriding, encapsulation? If not, you should. Sun has tutorials on this on their site. Apart from that, the Processing book, by Fry and Reas, is really, really good. You find it on the first page of Processing.org
Smiley
Re: Dynamic class naming
Reply #7 - Jan 7th, 2010, 2:17am
 
radarboy wrote on Jan 7th, 2010, 1:13am:
forName doesn't work in Processing

Sounds like a challenge!
I haven't played much with reflection, so it was an opportunity to try it again.
Code:
void setup()
{
 int p = 1;
 String className = this.getClass().getName() + "$Test" + p;
 Class cl = null;
 try
 {
   cl = Class.forName(className);
 }
 catch (ClassNotFoundException e)
 {
   println("Unknown class: " + className);
 }
 Object ocl = null;
 if (cl != null)
 {
   try
   {
// Alas, this doesn't work for inner classes!
// Will work if you put classes in separate .java files
ocl = cl.newInstance();
   }
   catch (InstantiationException e)
   {
println("Cannot create an instance of " + className);
   }
   catch (IllegalAccessException e)
   {
println("Cannot access " + className + ": " + e.getMessage());
   }
   // Internet to the rescue!
   try
   {
// Get the constructor(s)
java.lang.reflect.Constructor[] ctors = cl.getDeclaredConstructors();
// Create an instance with the parent object as parameter (needed for inner classes)
ocl = ctors[0].newInstance(new Object[] { this });
   }
   catch (InstantiationException e)
   {
println("Cannot create an instance of " + className);
   }
   catch (IllegalAccessException e)
   {
println("Cannot access " + className + ": " + e.getMessage());
   }
   catch (Exception e) // Lot of stuff can go wrong...
   {
e.printStackTrace();
   }
 }
}

public class Test1
{
 public Test1() { println("Constructor of " + this.getClass().getName() + " called"); }
}

Quote:
there's a folder of classes - maybe 100s, that each do specific mostly unrelated things

Now, there might be a problem.
It is hard to call methods in unrelated classes: unless using further more reflection, which is rather inefficient, there is no easy dynamic discovering of methods at runtime.
In Java, you make the classes to relate by extending a parent class or implementing an interface: both ensure there are at least a common set of methods to call.
A bit like a Processing sketch will (nearly) always have a setup() and a draw() method.

Come to think of it, I am wondering if what you want is not to have classes (in the sense of small bricks to get together to make a program) but full sketches. I have seen several requests to load dynamically complete sketches, switching them at regular intervals or on user input, as you said.
I have shown at least one way to do that: Sequencing, display update, and functions.
Re: Dynamic class naming
Reply #8 - Jan 7th, 2010, 6:27am
 
hey @Philho thanks. reflection's exactly what i wanted

with your example, how would i then reference the methods inside that class in the main draw():
tried a whole lot of things cl.doSomething(); doesn't work

Code:

int p = 1;
String className;
Class cl = null;
Object ocl;

void setup(){
size(800,600);
loadInClass();
}

void draw(){
background(0);
cl.doSomething(); // !!! this is the part that doesn't work
}

public void loadInClass(){
className = this.getClass().getName() + "$Test" + p;

try
{ cl = Class.forName(className); }
catch (ClassNotFoundException e) {
// println("Unknown class: " + className);
}
ocl = null;
if (cl != null) {
try {
// Alas, this doesn't work for inner classes!
// Will work if you put classes in separate .java files
ocl = cl.newInstance();
}
catch (InstantiationException e){
//println("Cannot create an instance of " + className);
}
catch (IllegalAccessException e) {
println("Cannot access " + className + ": " + e.getMessage());
}
// Internet to the rescue!
try
{
// Get the constructor(s)
java.lang.reflect.Constructor[] ctors = cl.getDeclaredConstructors();
// Create an instance with the parent object as parameter (needed for inner classes)
ocl = ctors[0].newInstance(new Object[] { this });
}
catch (InstantiationException e) {
//println("Cannot create an instance of " + className);
}
catch (IllegalAccessException e) {
//println("Cannot access " + className + ": " + e.getMessage());
}
catch (Exception e) // Lot of stuff can go wrong...
{
e.printStackTrace();
}
}

}

void keyPressed(){
p++;
loadInClass();
}



I don't need to discover methods at runtime, they'll all be standardised

On a side note, I don't want to load all the classes all at the beginning because i want to be able to add to the directory of classes while the app is running. so switch definitely won't cut it - and not so keen on writing a couple of hundred switch statements.

Dynamically loading whole sketches would work, but that would be second prize. I think reflection is the way to go.

@knutEinar: yea they essentially are objects - basically different animations. The objects are all different though share some characteristics, ie. the extend another main class. i know about OOP and have read pretty much all the Processing books out there. I'm just puzzled because it seems like a simple thing I am trying to do which is easily achieved in actionscript or javascript, but here seems quite difficult. perhaps i misnamed the subject header. this is more a question of how to dynamically name variables, i suppose. and then reference them. in AS2 you would've done something like:
x=3;
this["newObject" +x] = new myObject();
then be able to reference it simply as newObject3, as in:
newObject3.doSomething();


thanks again all for taking the time to help me out.
Re: Dynamic class naming
Reply #9 - Jan 7th, 2010, 6:59am
 
Maybe I'm missing something here, but couldn't you use a hashmap?  When dealing with multiple objects I'd normally just store them in a container, probably an ArrayList, but since you want to be able to reference the objects by name couldn't you add each object to the hashmap with the dynamically generated name as the key?  I guess it would be something like:

Code:
myHasmap.put("newObject" +x, new myObject()); 


Though I guess in this case you'd then be lumbered with the extra code required to retrieve and cast the object:

Code:
myObject foo = (myObject) myHasmap.get("newObject" +x);
foo.doSomething();

[above code is untested!  I've never used a HashMap:  just thinking aloud...]
Re: Dynamic class naming
Reply #10 - Jan 7th, 2010, 7:30am
 
Quote:
(blindfish) myHasmap.put("newObject" +x, new myObject());

The problem here is that you create an instance of each object. You should store the class info instead...

Quote:
not so keen on writing a couple of hundred switch statements

Yes, I thought that too, that's why I explored the reflection way.

Quote:
I don't need to discover methods at runtime, they'll all be standardised

Ah, so after all your classes have some common relation... Smiley

In the code above, cl is a class (and a generic one!), so you cannot call a method on it (unless the method is static). So you are more looking to do ocl.doSomething().
But it won't work because ocl is seen by the compiler as a generic Object, so it won't have doSomething() method.

You can still use reflection to explore the list of methods, but here, the best way is to define an interface holding all your standardized methods, that will be called by the main applet.
Then you make all your classes to implement that interface, thus requiring them to implement all these methods (they can be empty!).
Then you declare MyStunningInterface ocl; and, I think (untested), create it with ocl = (MyStunningInterface) xxx.newInstance(...);

You should be able to call ocl.doSomething() later.

A problem remains: how to dynamically load the designated jar holding the classes to get. I think it is possible (that's the idea of plug ins, after all), it probably involves classloaders, but I never done that...
Re: Dynamic class naming
Reply #11 - Jan 7th, 2010, 7:42am
 
Rather than using an interface and having to implement all methods in all classes wouldn't it be simpler to ensure that the class at the top of the inheritance tree contains all these as empty methods?  Again just thinking aloud...
Re: Dynamic class naming
Reply #12 - Jan 7th, 2010, 8:24am
 
Yes, that's a common scheme. For example, Java has the MouseListener interface defining 5 methods, but often users want only one or two of them, so it is annoying to add empty methods. So Sun added the MouseAdapter abstract class which just does that: creating empty methods, so that user just have to override those they want.
But still MouseAdapter implements the MouseListener interface... So users can choose either.

One problem with abstract classes is that Java allows to extend only one class. So if you want to use MouseAdapter, and thus make your class to extend it, it cannot extend a more significant class. While you can implement as much interfaces as you want.

To apply the idea to a classical class hierarchy, the LivingBeing, Animal, Dog.
Imagine you have a Sentient interface defining listen(), smell(), taste(), touch(), see().
Some creatures can be blind, deaf, etc.
Let say you make the SentientAdapter abstract class, to avoid implementing all methods.
If you make Dog to extend SentientAdapter, it can no longer be an Animal... It breaks the hierarchy.
So adapters can be convenient, but with an impact on the design.

Also, if all the standard methods of radarboy are actually used by the classes in the pool, it still makes sense to implement the interface.
Re: Dynamic class naming
Reply #13 - Jan 8th, 2010, 11:19pm
 
guy thanks a million.
this is exactly what i need.


in case someone else can use it sometime, here's some working code. this will just cycle through the available classes:
Code:


int p = 1;
String className;
Class cl = null;
gCore ocl;

void setup(){
size (800,600);
loadInClass();
}

void draw(){
background(0);
ocl.doSomething();
}

void keyPressed(){
p++;
loadInClass();
}


public void loadInClass(){
  className = this.getClass().getName() + "$c" + p;

 try
 { cl = Class.forName(className); }
 catch (ClassNotFoundException e) {
   // println("Unknown class: " + className);
}
  ocl = null;
 if (cl != null) {
   try {
// Alas, this doesn't work for inner classes!
// Will work if you put classes in separate .java files
ocl = (gCore) cl.newInstance();
   }
   catch (InstantiationException e){
//println("Cannot create an instance of " + className);
   }
   catch (IllegalAccessException e) {
println("Cannot access " + className + ": " + e.getMessage());
   }
   // Internet to the rescue!
   try
   {
// Get the constructor(s)
java.lang.reflect.Constructor[] ctors = cl.getDeclaredConstructors();
// Create an instance with the parent object as parameter (needed for inner classes)
ocl = (gCore) ctors[0].newInstance(new Object[] { this });

 }
   catch (InstantiationException e) {
//println("Cannot create an instance of " + className);
   }
   catch (IllegalAccessException e) {
//println("Cannot access " + className + ": " + e.getMessage());
   }
   catch (Exception e) // Lot of stuff can go wrong...
   {
e.printStackTrace();
   }
 }
}

/////////// here's the interface
/// this will hold the main mechanics

interface gCore {

public int x=0;

public void doSomething();

}

////////////////////// some classes

class c1 implements gCore {

 public int x;
 c1(){
//x=10;
  println("this is class c1");
 }
 
    public void doSomething(){
   x--;
   print(x);
 }


}



class c2 implements gCore {

 public int x;
 c2(){

   println("this is class c2");
 }

 public void doSomething(){
   x--;
 }
}


class c3 implements gCore {
  public int x;
 c3(){

  println("this is class c3");
 }
 
   public void doSomething(){
   x--;
 }
}



not that it's needed, but was just wondering if there's some kind of way to make it neater and implement this like a library, so then you just need to pass a variable to it a the classsname, and then have all is methods exposed. like one would do with PImage for example;

thanks again for all the help.
peace.
Re: Dynamic class naming
Reply #14 - Jan 9th, 2010, 2:11am
 
Note: the code I gave explore two scenarios, the classes being inner (small sketch) or at top level (probable if they are loaded dynamically).
No need to put the two scenarios in the same sketch, I did that only to show one of the them fails... Smiley
Pages: 1 2