7

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...

Stephane Grenier
  • 15,527
  • 38
  • 117
  • 192
  • Does an instanceof check help? Even if you know you're always going to get a JComboBox at the end. – Rex Oct 05 '12 at 00:50
  • I don't think you "code" a solution to solve the problem. You can, how ever, suppress the warnings. Take a look at http://stackoverflow.com/questions/593996/how-to-suppress-java-compiler-warnings-for-specific-functions. The problem is the compiler looks at the `ActionEvent.getSource` and says "I have an Object and while in theory, you can cast me, what you are trying to cast me to might not work" – MadProgrammer Oct 05 '12 at 00:52
  • I understand that you can suppress the warning, but that's less than ideal for me. If I did that to all compiler warnings, well let's just say it wouldn't be good. It's always better to find out why and properly solve it if at all possible. – Stephane Grenier Oct 05 '12 at 00:55
  • generics in the ui ... are a nuisance, nothing more. Here you need to cast the source anyway, whether that's further typed or not doesn't really matter (as long as the do-stuff doesn't rely on a particular data type) – kleopatra Oct 05 '12 at 09:53

4 Answers4

4

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);
  }
}
daniel
  • 3,166
  • 2
  • 17
  • 18
  • 1
    And how will this help to get rid of the *JComboBox is a raw type. References to generic type JComboBox should be parameterized* warning. Your code has exactly the same problem – Robin Oct 05 '12 at 05:46
  • 1
    Try to compile that code with JDK7-->You still have the compiler warning! Your answer does not solve the problem as it stands. – Guillaume Polet Oct 05 '12 at 07:14
  • Thanks Robin and Guillaume. Made some changes. First I forgot to set the type on JComboBox. Next I thought a typed JComboBox could return a typed a Typed Result easier by just calling getSelectedItem(). But it can't. Now it should work just fine. Im not getting any compilerwarnings. – daniel Oct 05 '12 at 17:59
1

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
    }

});
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • ehh ... that's quite contradictory to the basic idea of an Action (which is one-to-many :-) – kleopatra Oct 05 '12 at 09:56
  • @kleopatra Nothing prevents you from making this one-to-many. In this example, I exposed the basic concept and a one-to-one relationship. But as you indicated in another post, the typing of the UI element is kind of pointless. It should not go further than the model. – Guillaume Polet Oct 05 '12 at 10:32
  • 1
    _Nothing prevents you from making this one-to-many._ Nothing except ... keeping a list of targets? I don't think that's a viable option, at the end we at least agree on the kind-of pointlessness of generics in the view realm :-) – kleopatra Oct 05 '12 at 10:54
0

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")

Community
  • 1
  • 1
Gianmarco
  • 2,536
  • 25
  • 57
  • @stephane (written by Meriton). So you don't need to add suppress warning ;) You can write: Class extends Action> c = ClientAction.class; Action action = c.newInstance(); This eliminates both the cast and the warning, at the price of introducing a non-generic type so you can use .class to get a sufficiently accurately typed Class object. – Gianmarco Oct 05 '12 at 01:03
0

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
  }
}
Jonathan E. Landrum
  • 2,748
  • 4
  • 30
  • 46