ActionListeners for an array of JComboBoxes...

Hi,

In my program, each user has a JComboBox. However, the number of users varies depending on how many users are specified at the start of the game.

As a result I decided to make an array of JComboBoxes:
private JComboBox[] characterBox;

Then, later I specify the size of the JComboBox:
characterBox=new JComboBox[size];

I have no problem creating the JComboBoxes or adding them to the JPanel.

The problem occurs when I try to make actionlisteners. The following code is in a for loop that runs the number of users in the game.

characterBox[x].addActionListener(

                 new ActionListener() 
                 {
                          public void actionPerformed( ActionEvent event )
                        {
                                       
                                  String picNum = (String)characterBox[x].getSelectedItem();
                                  
                 
                         }
                      }
                  );//END Listener 

The problem is that the compiler tells me x must be final. However I can’t have it final because I am looping the creating of the Listeners. I know the actionlistener code works but I can’t figure out how to create all of the listeners in a for loop. Any thoughts? Thanks.

I would parameterize the JComboBox into the constructor. Here is an example with an explicit class implementing ActionListener:


class MyActionListener implements ActionListener
{
   private JComboBox comboBox;

   public MyActionListener(JComboBox comboBox)
   {
      this.comboBox=comboBox;
   }

   public void actionPerformed(ActionEvent e)
   {
      String picNum=(String)comboBox.getSelectedItem();
      // ... do something ...
   }
}

The problem with your approach is that x is not known at compile-time, and whereas x is in the scope of the executed code at run-time, for the implicit ActionListener implementation it is not (as it will be created at compile-time, not at run-time). The compiler wants it to be final, because then it would be possible to get the actual integer value at compile-time.

Instead of having a reference to the JComboBox for each listener instance, you could also have a class member integer which is assigned the value of x; however, I would prefer the JComboBox as it makes it clear what the stored value is about.

Another (better) way (in my opinion) :

use jcombobox.putClientProperty(key, value) to store user information into each combobox. (for example an integer, a UserInfo object…) and retrieve it with getClientProperty(key)

write only one ActionListener, like this :

ActionListener comboListener = new ActionListener(){
public void actionPerformed(ActionEvent e){
JComboBox cbx = (JComboBox) e.getSource();
UserInfo ui = (UserInfo) cbx.getClientProperty(“user.info”);
// do something depending on the user info
}
};

add this listener to every user combos.

Lilian

You can cheat the compiler. ;D

In the for loop:

final JComboBox finalCB = characterBox[x];
finalCB.addActionListener(new ActionListener()  
{
   public void actionPerformed( ActionEvent event )
   {          
      String picNum = (String)finalCB.getSelectedItem();  
   }
});