ratingS = new JSlider(1, 5, 3);
ratingS.setMajorTickSpacing(1);
ratingS.setPaintLabels(true);
int vote;
class SliderMoved implements ChangeListener {
public void stateChanged(ChangeEvent e) {
vote = ratingS.getValue();
}
}
ratingS.addChangeListener(new SliderMoved());
If i write the above code Eclipse tells me this:
Cannot refer to a non-final variable vote inside an inner class
defined in a different method
But if i add final before int vote it gives me this error:
The final local variable vote cannot be assigned, since it is defined in an enclosing type
So, how to solve?
Well, the standard trick is to use an int array of length one. Make the var final and write to var[0]
. It is very important to make sure you don't create a data race. Using your code as an example:
final int[] vote = {0};
class SliderMoved implements ChangeListener {
public void stateChanged(ChangeEvent e) {
vote[0] = ratingS.getValue();
}
}
Since all this will be happenenig on the EDT, including the callback invocation, you should be safe. You should also consider using the anonymous class:
ratingS.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) { vote[0] = ratingS.getValue(); }
});
Move vote
to SliderMoved
:
class SliderMoved implements ChangeListener {
private int vote;
public void stateChanged(ChangeEvent e) {
this.vote = ratingS.getValue();
// do something with the vote, you can even access
// methods and fields of the outer class
}
public int getVote() {
return this.vote;
}
}
SliderMoved sm = new SliderMoved();
ratingS.addChangeListener(sm);
// if you need access to the actual rating...
int value = rattingS.getValue();
// ...or
int value2 = sm.getVote();
EDIT
Or alternatively, pass a model class to the change listener
public class Person {
private String name;
private int vote;
public int getVote() {
return this.vote;
}
public void setVote(int vote) {
this.vote = vote;
}
// omitting other setter and getter
}
Person
is used as follows:
class SliderMoved implements ChangeListener {
private Person person;
public SliderMoved(Person person) {
this.person = person;
}
public void stateChanged(ChangeEvent e) {
this.person.setVote(ratingS.getValue());
}
public Person getPerson() {
return this.person;
}
}
Person person = new Person();
ratingS.addChangeListener(new SliderMoved(person));
// access the vote
int vote = person.getVote();
I finally solved declaring vote as instance variable (private) in the main class.
Setting the Compiler compliance level to 1.8 worked for me to solve a similar problem. I don't understand the reason but you may try this.
How it works:
Right click on the project --> Properties --> Java Compiler. And in java compiler properties window, set the compiler compliance level to 1.8.