I'm trying to set the text of a number of different components (JButton, JLabel, etc...) through reflection. I'm also using annotations in the fields that I want to change later on.
For example, I have the following code:
public class MainWindow {
@UsesTextChanger
private JButton btn1;
@UsesTextChanger
private JLabel lb1;
public void ChangeTexts() {
for (Field field: MainWindow.class.getDeclaredFields()) {
field.setAccessible(true);
UsesTextChanger usesTextChanger = field.getAnnotation(UsesTextChanger.class);
if (usesTextChanger != null){
try {
Method method = field.getType().getMethod("setText", new Class[]{String.class});
method.invoke(field, "my new text");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
I am getting the following exception:
java.lang.IllegalArgumentException: object is not an instance of declaring class
Is there a way to get the instance of this field so I can invoke the setText()
method properly?
I also tried to take another approach by making a loop through all my components (The code only works in the first layer for now though), and actually the setText() works, however I don't know how to check if the annotation is there:
for (Component component: this.frame.getContentPane().getComponents()) {
try {
boolean componentUsesTextChangerAnnotation = true; // Is there a way to check if an annotation exists in an instanced object?
if (componentUsesTextChangerAnnotation) {
Method method = component.getClass().getMethod("setText", new Class[]{String.class});
method.invoke(component, "my new text");
}
} catch (Exception e) {
e.printStackTrace();
}
}
Thanks!
You're trying to call the method on the Field
- whereas you actually want to call it on the value of the field within your object.
You want:
Method method = field.getType().getMethod("setText", String.class);
Object target = field.get(this);
method.invoke(target, "my new text");
(I've used the fact that Class.getMethod
has a varargs parameter to simplify the call to that, btw.)
See more on this question at Stackoverflow