Java 关于swing组件的思考
我试图通过反射为swing组件赋值。让我们以JCheckBox为例。我有以下课程:Java 关于swing组件的思考,java,swing,reflection,Java,Swing,Reflection,我试图通过反射为swing组件赋值。让我们以JCheckBox为例。我有以下课程: public class JCheckBoxTest { private JCheckBox test; public JCheckBoxTest() { this.test = new JCheckBox(); } public reflectionTest() { Field field; Method met
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”方法,因为它位于超类“JToggleButton”的内部类“ToggleButtonModel”中,该类由“JCheckBox”类扩展
解决这个问题的最佳方法是什么
谢谢
编辑:更正了代码中的输入错误。类#getMethod
和类#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;
}
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)
这是一种小小的暴力
所以考虑到这一点
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();
}
输出类似于
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;
}
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)
免责声明
像这样的思考应该是最后的选择。它很慢,而且容易进行代码重构类#getMethod
和类#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;
}
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)
这是一种小小的暴力
所以考虑到这一点
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();
}
输出类似于
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;
}
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)
免责声明
像这样的思考应该是最后的选择。它的速度很慢并且容易发生代码重构您也可以尝试
类#getMethod
,如果这两个方法都不返回方法
,您可能还需要使用类#getSuperclass
搜索它和它的super类(直到getSuperclass
返回的null
),setSelected
需要一个boolean
参数,所以您可能应该使用field.getClass().getDeclaredMethod(“setSelected”,boolean.class)
一旦解决了这个问题,您将运行到下一个,因为方法。invoke(字段,“true”)
将无法工作setSelected
需要一个boolean
参数,因此您不能将字符串传递给它。您也可以尝试Class#getMethod
,如果两者都不返回方法
,您可能需要使用Class#getSuperclass
并搜索它和它的超级类(直到getSuperclass
return的null
)而且,setSelected
需要一个boolean
参数,所以您可能应该使用field.getClass().getDeclaredMethod(“setSelected”,boolean.class);
一旦解决了这个问题,您将运行到下一个,如方法。invoke(field,“true”)
不起作用。setSelected
需要一个boolean
参数,因此无法向其传递字符串。