Stephane Grenier
Stephane Grenier

Reputation: 15925

Java Swing - How to handle generics in ActionListener

I have:

class CustomerActionListener implements ActionListener
{
  @Override
  public void actionPerformed(ActionEvent event)
  {
    JComboBox cb = (JComboBox)event.getSource();
    .. do something
  }
}

Which causes the following compiler warning in jdk7:

JComboBox is a raw type. References to generic type JComboBox should be parameterized

I've tried to parameterize it to such that:

JComboBox<String> cb = (JComboBox<String>)event.getSource();

But this still leaves the following compiler warning:

Type safety: Unchecked cast from Object to JComboBox

Therefore I'm not sure how to eliminate the compiler warnings...

Upvotes: 7

Views: 2765

Answers (4)

Jonathan E. Landrum
Jonathan E. Landrum

Reputation: 3182

Yet another solution

You can also use the Java Wildcard pattern:

class CustomerActionListener implements ActionListener
{
  @Override
  public void actionPerformed(ActionEvent event)
  {
    JComboBox<?> cb = (JComboBox<?>)event.getSource();
    .. do something
  }
}

Upvotes: 0

daniel
daniel

Reputation: 3174

I apreciate this approach. It avoids any Typecasts and is easy to read.

I improved my answer, now It doesn't give you Compiler Warnings. The Type of JComboBox is now set to String. To get the selected Item, you have to go through the ComboBoxModel.

class CustomerActionListener implements ActionListener
{
  private JComboBox<String> comboBox;
  public CustomerActionListener(JComboBox<String> comboBox){
    this.comboBox = comboBox;
  }
  @Override
  public void actionPerformed(ActionEvent event)
  {
    // Just use the comboBox
    ComboBoxModel<String> model = comboBox.getModel();
    int index = comboBox.getSelectedIndex();
    String choosen = model.getElementAt(index);
    System.out.println("Hey you choose "+choosen);
  }
}

Upvotes: 4

Guillaume Polet
Guillaume Polet

Reputation: 47607

The only way out here is to grab a typed reference to your JComboBox:

Either like this

JComboBox<String> myStringCb = new JComboBox<String>();
...
myStringCb.addActionListener(new CustomerActionListener(myStringCb);

and with you ActionListener:

class CustomerActionListener implements ActionListener {

  private JComboBox<String> cb;

  public CustomerActionListener(JComboBox<String> cb) {
    this.cb = cb;
  }

  @Override
  public void actionPerformed(ActionEvent event) {
    if(event.getSource()==cb) {
       // Here you can do something with the typed cb
    }
  }
}

Or, another solution is to use an anonymous ActionListener with a final reference:

final JComboBox<String> myStringCb = new JComboBox<String>();
myStringCb.addActionListener(new ActionListener(){

    public void actionPerformed(ActionEvent e) {
        // Here you can refer directly to myStringCb
    }

});

Upvotes: 1

Gianmarco
Gianmarco

Reputation: 2552

Try to check this:

A very useful link form StackOverflow

In few words, Java compiler don't know what object is the one you're trying to cast, so it don't like to do the cast without a word, it must advise you that you maybe are making a mistake (but you DO know what kind of Class is the Object you are casting, so don't mind about it) Add a @SuppressWarning("unchecked")

Upvotes: 0

Related Questions