Question

Hello!

I'm not even sure if this is possible, but hopefully it is in Java. I know I've done it in PHP by using variable variables and accessing a variable dynamically, but I read this isn't possible in Java in a different question.

I have an array of strings which contains the state of checkboxes in my JSF GUI. If all checkboxes are set the array will then be filled with strings containing the value of different checkboxes.

The labels and values of the checkboxes are built by looping through an array that looks like this:

private static final String[][] OVERVIEW_FIELDS = {{"ID", "requestid"},
    {"Date added", "dob"}, {"Title", "requestTitle"}, {"Process", "processId"},
..., ..., ...};

Then I iterate through the array and make JSF SelectItems out of it:

for (int i = 0; i < OVERVIEW_FIELDS.length; i++) {
    SelectItem item = new SelectItem(OVERVIEW_FIELDS[i][0], OVERVIEW_FIELDS[i][1]);
    getFields().add(item);
}

The problem and current solution (hopefully someone can help me refactor it into something better:

for (String item : getVisibleFields()) {
           if (item.equals("dob")) {
                setDob(true);
            }
            if (item.equals("requestTitle")) {
                setRequestTitle(true);
            }
            if (item.equals("processId")) {
                setProcessId(true);
            }
            if (...) {
            }
}

And so on it continues for 11 booleans. I don't like this solution, and I see similar patterns in other beans in my system.

Does anyone know if there's a better solution to this? The booleans control columns where I set their rendered field to true/false according to what the checkbox array contains.

I was hoping in the JSF EL I could access the visibleFields variable and the contains method, thus returning either true or false if the object exist in array. This doesn't seem to work though and the EL doesn't give me access to the contains method.

I'm currently using:

rendered="#{overviewFilterBean.dob}"

And I tried with this code:

rendered="#{overviewFilterBean.visibleFields.contains['dob']}">

Now this led me to try to use my final array and set the booleans according to getFields().contains(OVERVIEW_FIELDS[i][1]), but how can I make this possible?

Part real and part pseudo code follows (the solution I was aiming for now):

for (int i = 0; i < OVERVIEW_FIELDS.length; i++) {
    if (item.equals(OVERVIEW_FIELDS[i][1])) {
           setOVERVIEW_FIELDS[i][1](true);
       }
    }

The big question:

Is there a way for me to use the value from OVERVIEW_FIELDS[i][1] to set the correct boolean variable or can I turn this into a Map maybe and use the JSF EL to check if key exists in the map?

Thank you for your time, and sorry for writing such a lengthy question to get to a small point :/

EDIT:

The reflection method resulted in 5 exceptions, big block of code handling them and also people said that its an expensive method. This leads me to believe that either my old solution or by using maps is the best way of doing it. Im gonna try the map solution =)

Was it helpful?

Solution

You could always store the values in a map rather. However if you want to invoke methods based on the methodname as a string, use reflection. See http://java.sun.com/developer/technicalArticles/ALT/Reflection/

OTHER TIPS

With reflection, you can do:

for (String item : getVisibleFields()) {
    getClass().getMethod("get" + capitalize(item)).invoke(this, true);
}

Exception handling and the capitalize method are left as an exercise to the reader (invoke throws a lot of exceptions).

You can use the Java reflection API to look up the field dynamically and set it, as in this example. Note that there will be a performance hit to this method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top