Oh I understand, so you want to be able to take a method, that you would call later right?
try GetOutput(output);
i am confused this time
In here, the event name is unknown. For example, in App Inventor, you can track the user input, which is strings, and open another screen with that string because App Inventor opening screens accept strings. But in Java, they cannot do something like
"GetOutput"(output);
and it must be
GetOutput(output);
. Probably this.
Here I have simplified to working code. You can see GotOutput
is hard coded in GetFunction
and will therefore run the event. But i will have many simpleevents and simplefunctions, so i want to be able to substitute GotOutput
for whatever simpleevent is needed for the desired simplefunction. All simplefunctions will call GetFunction
.
@SimpleEvent(description = "Event raised when output returned")
public void GotOutput(final String output) {
EventDispatcher.dispatchEvent(this, "GotOutput", output);
}
@SimpleFunction(description = "set parameters to get output")
public void GetOutput() {
String parameters = "some parameters";
GetFunction(parameters);
}
private void GetFunction(String parameters) {
//do something
//output to event:
GotOutput(output);
}
only have one GotOutput event, which will fire for all those many simple functions
Taifun
Yes, I have done this, but it generates work elsewhere to identify which simplefunction was called. Could be the easiest route though
Probably you have to hard code the functions, like this.
You have these events
@SimpleEvent(description = "Event raised when output returned")
public void GotOutput(final String output) {
EventDispatcher.dispatchEvent(this, "GotOutput", output);
}
@SimpleEvent(description = "Event raised when output result")
public void GotResult(final String output) {
EventDispatcher.dispatchEvent(this, "GotOutput", output);
}
and you do this.
if (something == "GotOutput") {
GotOutput(output);
} else if (something == "GotResult") {
GotResult(result);
}
Yes I could build an if/else block or a switch-case statement to handle things.
just pass that name to GotOutput and use it in the event as output parameter
Taifun
Do you want to call a function / method by its name?
That is the idea, but to pass it as a parameter ....
Yes. Unfortunately in Java you cannot do
and you cannot do
TextView "myTextViewCreatedJustNow" = new TextView;
and Tim also wants to
as well. It would certainly have challenges.
You might try reflection?
Interesting.
This particularly comes in handy when we don't know their names at compile time.
Check this, call a function by its name and pass parameters:
I have been thinking about this for sometime (this is a joke)
I have seen reflection
being used for this on StackOverflow, but the application of the approach was way over my head.
You wont be able to simply pass the method in Java, you could use easy conditions instead.
But still, a similar thing can be done:
package xyz.kumaraswamy.test;
import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.ComponentContainer;
import com.google.appinventor.components.runtime.EventDispatcher;
public class Test extends AndroidNonvisibleComponent {
public Test(ComponentContainer container) {
super(container.$form());
}
@SimpleEvent
public void AppleFell(int apples) {
EventDispatcher.dispatchEvent(this, "AppleFell", apples);
}
@SimpleEvent
public void OrangeFell(int oranges) {
EventDispatcher.dispatchEvent(this, "OrangeFell", oranges);
}
@SimpleFunction
public void GetApples() throws Exception {
doSomething("...", "AppleFell");
}
@SimpleFunction
public void GetOranges() throws Exception {
doSomething("....", "OrangeFell");
}
private void doSomething(String parameters, String whatEvent) throws Exception {
int counts = parameters.length();
// call the event with the name
// that event has one arg int type
getClass().getMethod(whatEvent,
int.class).invoke(this, counts);
}
}
// second one is event name (any event name in the class)
// but you wont be able to pass method as a paramter
doSomething("....", "OrangeFell");
You might get an idea from dynamic components code it is made upon the principle of reflection
OK, it looks like it will be easier to either:
- Follow Taifun's suggestions in using one event, then select the correct event to run
- Build an if/else or switch/case statement to select the correct event to run
Thanks to all for your ideas and input, it helped me see the wood from the trees
@SimpleEvent(description = "Event raised when output returned")
public void GotOutput(final String output, String simpleFunction) {
EventDispatcher.dispatchEvent(this, "GotOutput", output, simpleFunction);
}
@SimpleFunction(description = "set parameters to get output")
public void GetOutput() {
String parameters = "some parameters";
GetFunction(parameters);
}
private void GetFunction(String parameters) {
//do something
//output to event:
GotOutput(output, "mySimpleFunction");
}
Taifun