samedi 26 janvier 2019

Unknown number of arguments when invoking a reflection method

I'm creating a GUI that shows buttons according to a selected image characteristics. Let's say image A has the characteristics 1, 2 and 3, so when selected buttons that implements filters for the characteristics 1, 2 and 3 are added to my pannel.

I want the filters to be methods that can be added easily to the code, so I'm using reflection to work with the characteristics in order to get the corret methods for each image.

When a button is added to the GUI it needs a action listener, and in the action listener its method is invoked.

If there are parameters for the filter method a set of textfields is added to the GUI too in order to be posible to collect the parameters.

When the method has no params the invoke is working just fine, the addition of textfields is fine too as well as the capture of the parameters via those TFs.

The question is: using a list of unknown size is it possible to use this list as arguments for the reflection invoke?

Image 1 shows the GUI with no image selected, when a image is selected the buttons are added and the GUI will look like 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();
        }
    };
}

As you can see I'm collecting the params from textFields that I add to the JPanel, and creating a int[] from it.

But it seems that the invoke methods takes Object... objs as parameters, which by my understanding is a list, but I'm getting a "java.lang.IllegalArgumentException: wrong number of arguments" error.





Aucun commentaire:

Enregistrer un commentaire