I'm developing a utility class to handle Actions from Java Swing components; I would like to know if there is a way of checking if a given method name (that will be accessed by reflections) exists in compile time, and show a compiler error if not?
--update
Ok, looks like I was not clear, lets talk about the details:
I have a class called TomAction that I use to simplify simple actions declarations in my project. Instead of write something like:
class MyClass {
public MyClass() {
Icon icon = null; // putting null to simplify the example
JButton btn = new JButton(new AbstractAction("Click to go!", icon) {
public void actionPerformed(ActionEvent ev) {
try {
go();
} catch (Exception e) {
e.printStackTrace();
String msg = "Fail to execute 'go' task.";
JOptionPane.showMessageDialog(null, msg, "Fail", JOptionPane.ERROR_MESSAGE);
}
}
});
}
private void go() {
// do task
}
}
..I just write:
class MyClass {
public MyClass() {
String msg = "Fail to execute 'go' task.";
Icon icon = null; // putting null to simplify the example
TomAction act = new TomAction("go", this, "Click to go!", msg, icon);
JButton btn = new JButton(act);
}
private void go() {
// do task
}
}
..and the program have the same behaviour.
The problem is that if I type a wrong method name as argument to TomAction, I will see it just in runtime. I would like to see it in compile time. Got it? :)
By the way, this class is working very fine, I just want to do this enhancement.
--update
studing the Annotations approach
You could use annotation instead of string literal to denote the invoked action and then use APT to verify that the method exists. APT is invoked automatically by the javac.
http://java.sun.com/javase/6/docs/technotes/tools/windows/javac.html#processing http://java.sun.com/j2se/1.5.0/docs/guide/apt/GettingStarted.html http://java.sun.com/j2se/1.5.0/docs/guide/apt/mirror/overview-summary.html
By taking your example, I would suggest design as follows - you put a binding annotation in code and add the action instantiation code in the annotation processor. The actions in that case need to be class members which is a good practice anyway. Make sure you use resource bundles for icons and text and you'll save a lot of grief in the long run:
class MyClass {
// the keys should be looked up from resource bundle
@TomActionBinding("go", "text-key", "msg-key", "icon-key");
Action act;
public MyClass() {
JButton btn = new JButton(act);
}
private void go() {
// do task
}
}