For something I'm doing, it would just make things so much easier, quicker, and cleaner to have C# style events. I've written a class I believe should replicate a C# style event using reflection. Since I've never actually used reflection before in any meaningful sense, I'm very much not happy using it without, at the very least, a second opinion.
I want to declare an event with:
public Event SomeEvent = new Event();
Raise the event (presumably within the declaring class) with (where SomeArguments is whatever class that may be specified in the Javadocs boxed in an Object):
SomeEvent.Raise(this, SomeArguments);
Add a method to be called when the event is raised with:
SomeEvent.AddListener(this, "onSomeEvent");
Stop a method being called when an event is raised with:
SomeEvent.RemoveListener(this, "onSomeEvent");
And cancel all listeners with:
SomeEvent.ClearListeners();
Methods to listen to the event should be formatted like:
public void onSomeEvent(object Sender, object SomeArguments)
{ }
And this is my class:
package puppy.hanii.library;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class Event
{
public Event()
{
Methods = new ArrayList<Method>();
DeclaringClasses = new ArrayList<Object>();
}
ArrayList<Method> Methods;
ArrayList<Object> DeclaringClasses;
public boolean AddListener(Object Class, String MethodName)
{
try
{
Method MTR = Class.getClass().getMethod(MethodName, Object.class, Object.class); // MTR = Method To Register.
if(Methods.contains(MTR))
return false;
else
{
Methods.add(MTR);
DeclaringClasses.add(Class);
return true;
}
}
catch (NoSuchMethodException error) { throw new RuntimeException("No such method, or correct overloads of method, exists."); }
}
public boolean RemoveListener(Object Class, String MethodName)
{
try
{
DeclaringClasses.remove(Class);
return Methods.remove(Class.getClass().getMethod(MethodName, Object.class, Object.class));
}
catch (NoSuchMethodException error) { throw new RuntimeException("No such method, or correct overload of method, exists."); }
}
public void ClearListeners()
{
Methods.clear();
DeclaringClasses.clear();
}
public void Raise(Object Sender, Object Arguments)
{
for(int i = 0; i < Methods.size(); i++)
{
try
{ Methods.get(i).invoke(DeclaringClasses.get(i), Sender, Arguments); }
catch(IllegalAccessException error)
{ }
catch(InvocationTargetException error)
{ throw new RuntimeException("Error in event handler"); }
}
}
}