关于摆动部件的思考

时间:2015-12-01 03:18:22

标签: java swing reflection

我试图通过反射为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"类。

解决这个问题的最佳方法是什么?

感谢。

编辑:更正了代码中的拼写错误。

1 个答案:

答案 0 :(得分:4)

Class#getMethodClass#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)

声明

这样的反思应该是最后的手段。它很慢且容易出现代码重构