调用反射方法时参数数量未知

时间:2019-01-26 11:40:31

标签: java reflection

我正在创建一个GUI,该GUI根据所选的图像特征显示按钮。假设图片A具有特征1、2和3,因此将为特征1、2和3实现过滤器的选定按钮添加到我的面板中。

我希望过滤器是可以轻松添加到代码中的方法,所以我使用反射来处理特征,以便为每个图像获取正确的方法。

将按钮添加到GUI时,它需要一个动作侦听器,并在动作侦听器中调用其方法。

如果有用于过滤方法的参数,则还将一组文本字段添加到GUI,以便可以收集参数。

当该方法没有参数时,调用可以正常工作,添加文本字段以及通过这些TF捕获参数也很好。

问题是:使用未知大小的列表是否可以将此列表用作反射调用的参数?

图像1显示了未选择图像的GUI,选择图像后,添加了按钮,GUI看起来像2

No img selected Img selected, buttons added

public class Filters(){
    @Name("Decompose")  
    public void decompose() {
        ...decompose the image
    }

    @Name("Weighted Blur")
    public void blurImage(@ParamName("Weight") int weight, @ParamName("Radius") int radius) {
        ...blur the image
    }
}

public class Control(){
    public void addFilterFunctions(ArrayList<Method> applicableMethods) {
        for(Method m : applicableMethods) {
            addButton(m);
        }
    }   
}


public void addButton(Method m) {       
    JButton newButton = new JButton(m.getAnnotation(Name.class).value());
    newButton.addActionListener(genericListener(m, newButton, methodFields));
}

private ActionListener genericListener(Method m, JButton b, ArrayList<JTextField> methodFields) {
    return listener ->{
        try {           
            int[] params = new int[methodFields.size()];
            for(int i =0; i<methodFields.size();i++) {
                params[i] = Integer.parseInt(methodFields.get(i).getText());
            }   

            m.invoke(filters, params);
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    };
}

如您所见,我正在从添加到JPanel的textField中收集参数,并从中创建一个int []。

但是似乎该invoke方法将Object ... objs作为参数,据我的理解是一个列表,但是我遇到“ java.lang.IllegalArgumentException:错误的参数数目”错误。

2 个答案:

答案 0 :(得分:0)

Object...实际上与Object[]相同,因此您需要传递Object[]才能成功:

Object[] params = new Object[methodFields.size()];
for (int i = 0; i < methodFields.size(); i++) {
    params[i] = Integer.parseInt(methodFields.get(i).getText());
}

答案 1 :(得分:0)

尝试一下:

编写采用字符串数组并让它们调用您的过滤器方法的方法。

例如blurImageWrapper

public void blurImageWrapper(String[] params) {
    if (params.length == 2) {
        int weight = Integer.parseInt(params[0]);
        int radius = Integer.parseInt(params[1]);
        blurImage(weight, radius);
    }
}

@Name("Weighted Blur")
public void blurImage(@ParamName("Weight") int weight, @ParamName("Radius") int radius) {
    ...blur the image
}

您将使用反射调用包装方法,并向其传递String[]的单个参数。您有一个文本字段列表,因此可以轻松获得String[]。如果您认为更方便,也可以使用ArrayList<String>

如果所有过滤器都接受int参数,则可以将字符串数组更改为int数组,并传递解析后的int:

public void blurImageWrapper(int[] params) {
    if (params.length == 2) {
        blurImage(params[0], params[1]);
    }
}