Question

I am trying to add an anonymous actionListener to a JCheckBox but having some difficulty in accessing the object I want to update the value with. I keep getting errors about non final, and then when i change them to be final it complains about other things.
what im trying to do is below (i've removed some of the gui code to make it easier to read):

for (FunctionDataObject fdo : wdo.getFunctionDataList())
{
    JLabel inputTypesLabel = new JLabel("Input Types: ");
    inputsBox.add(inputTypesLabel);
    for (int i = 0; i < fdo.getNumberOfInputs(); i++)
    {
        JLabel inputLabel = new JLabel(fdo.getInputNames().get(i));
        JComboBox inputTypeComboBox = new JComboBox(getTypes());
        inputTypeComboBox.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) 
             {
                 fdo.getInputTypes().set(i, (String) inputTypeComboBox.getSelectedItem());
             }
        });
     }
}    
Was it helpful?

Solution

You can't access a non final variable in an anonymous class. You could slightly modify your code to work around that restriction (I have made fdo and inputTypeComboBox final and I've also made a final copy of i):

    for (final FunctionDataObject fdo : wdo.getFunctionDataList()) {
        JLabel inputTypesLabel = new JLabel("Input Types: ");
        inputsBox.add(inputTypesLabel);
        for (int i = 0; i < fdo.getNumberOfInputs(); i++) {
            final int final_i = i;
            JLabel inputLabel = new JLabel(fdo.getInputNames().get(i));
            final JComboBox inputTypeComboBox = new JComboBox(getTypes());
            inputTypeComboBox.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    fdo.getInputTypes().set(final_i, (String) inputTypeComboBox.getSelectedItem());
                }
            });
        }
    }

OTHER TIPS

Update your code from

 inputTypeComboBox.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) 
         {
             fdo.getInputTypes().set(i, (String) inputTypeComboBox.getSelectedItem());
         }
    });

to

final counter = i;
final JComboBox inputTypeComboBox = new JComboBox(getTypes());
final FunctionDataObject finalFDO = fdo;
inputTypeComboBox.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) 
         {
             finalFDO.getInputTypes().set(counter, (String) inputTypeComboBox.getSelectedItem());
         }
    });

This link explains why you can only access final variables in inner class

This will work:

    for (final FunctionDataObject fdo : wdo.getFunctionDataList()) {
        JLabel inputTypesLabel = new JLabel("Input Types: ");
        inputsBox.add(inputTypesLabel);
        for (int i = 0; i < fdo.getNumberOfInputs(); i++) {
            JLabel inputLabel = new JLabel(fdo.getInputNames().get(i));
            final JComboBox inputTypeComboBox = new JComboBox(getTypes());
            final int index = i;
            inputTypeComboBox.addActionListener(new ActionListener() {
                 public void actionPerformed(ActionEvent e) {
                     fdo.getInputTypes().set(index, (String) inputTypeComboBox.getSelectedItem());
                 }
            });
         }
    }    
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top