我试图通过反射为swing组件赋值。我们以JCheckBox为例。我有以下课程:
public class JCheckBoxTest
{
private JCheckBox test;
public JCheckBoxTest()
{
this.test = new JCheckBox();
}
public reflectionTest()
{
Field field;
Method method;
field = this.getClass().getDeclaredField("test");
method = field.getType().getSuperclass().getDeclaredMethod("setSelected");
method.invoke(field, "true");
}
}
此代码在以下位置失败:
method = field.getType().getSuperclass().getDeclaredMethod("setSelected");
因为它无法找到指定的" setSelected"方法,因为它位于内部类" ToggleButtonModel"超类" JToggleButton"这是由" JCheckBox"类。
解决这个问题的最佳方法是什么?
感谢。
编辑:更正了代码中的拼写错误。
答案 0 :(得分:4)
Class#getMethod
和Class#getDeclaredMethod
都提供了提供方法名称和可选参数的方法
JCheckBox#setSelected
需要boolean
参数,所以你真的应该使用
method = field.getClass().getDeclaredMethod("setSelected", boolean.class);
但正如您所指出的,这不太可行,相反,您可以尝试
method = field.getClass().getMethod("setSelected", boolean.class);
现在,我也失败了,这就是为什么我倾向于使用类似的东西......
public static Method findMethod(Class parent, String name, Class... parameters) throws NoSuchMethodException {
Method method = null;
try {
method = parent.getDeclaredMethod(name, parameters);
} catch (NoSuchMethodException exp) {
try {
method = parent.getMethod(name, parameters);
} catch (NoSuchMethodException nsm) {
if (parent.getSuperclass() != null) {
method = findMethod(parent.getSuperclass(), name, parameters);
} else {
throw new NoSuchMethodException("Could not find " + name);
}
}
}
return method;
}
这是一种蛮力。
所以考虑到这一点......
JCheckBox cb = new JCheckBox();
try {
Method method = cb.getClass().getDeclaredMethod("setSelected", boolean.class);
System.out.println("1. " + method);
} catch (NoSuchMethodException | SecurityException ex) {
ex.printStackTrace();
}
try {
Method method = cb.getClass().getMethod("setSelected", boolean.class);
System.out.println("2. " + method);
} catch (NoSuchMethodException | SecurityException ex) {
ex.printStackTrace();
}
try {
Method method = findMethod(cb.getClass(), "setSelected", boolean.class);
System.out.println("3. " + method);
} catch (NoSuchMethodException ex) {
ex.printStackTrace();
}
其中输出类似......
java.lang.NoSuchMethodException: javax.swing.JCheckBox.setSelected(boolean)
2. public void javax.swing.AbstractButton.setSelected(boolean)
3. public void javax.swing.AbstractButton.setSelected(boolean)
at java.lang.Class.getDeclaredMethod(Class.java:2130)
at test.Test.main(Test.java:13)
这样的反思应该是最后的手段。它很慢且容易出现代码重构