Reputation: 148
import javax.swing.*;
import javax.swing.event.*;
public class NewGUIStuff{
public static void main(String args[]){
NewGUIStuff gui = new NewGUIStuff();
gui.go();
}
class handlesListListeners implements ListSelectionListener{
public void valueChanged(ListSelectionEvent lse){
list.setVisibleRowCount(4);
}
}
public void valueChanged(ListSelectionEvent lse){
}
public void go(){
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JList list;
String[] aList = {"alpha","beta","gamma","delta","epsilon","zeta","eta","theta"};
list = new JList(aList);
list.addListSelectionListener(new handlesListListeners());
JScrollPane scroller = new JScrollPane(list);
scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
frame.setContentPane(scroller);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300,300);
frame.setVisible(true);
}
}
So my question here is if inner classes can see their outer classes variables and objects, why can't the inner-class handlesListListeners
see the list
object I made in NewGUIStuff
outer class?
Upvotes: 1
Views: 726
Reputation: 13114
Your list
variable is local to the method go()
. If you want it to be visible you need to make it an instance field of NewGUIStuff
. Something like this:
public class NewGUIStuff {
private JList list = new JList(); // Member of outer class so in scope from handlesListListeners
public static void main(String args[]) {
NewGUIStuff gui = new NewGUIStuff();
gui.go();
}
class handlesListListeners implements ListSelectionListener {
public void valueChanged(ListSelectionEvent lse) {
list.setVisibleRowCount(4);
}
}
}
Upvotes: 1
Reputation: 6105
Non-static inner classes can see the outer class instance variables and those local variables they were enclosed around (think closures) if those were declared final
(in case of anonymous inner classes). Those non-static inner classes have an implicit reference to the outer this
inserted by the compiler and that's how they see the member variables of the outer class. The final local variables you enclose your anonymous class around will be implicitly passed into the a constructor that the compiler will generate for you and stored in the final member fields of the inner class itself.
In your case I see you expect to see a local variable defined in a whole different lexical context, the one your inner class has no knowledge about. Convert it into the outer class member variable and your inner class will see it.
Upvotes: 2
Reputation: 54446
It's because list
is a local variable in the go()
function. It is out of scope for the handlesListListeners
class.
If list
were an instance variable of the outer class then the inner class would be able to see it. Alternatively, you could make your inner class local to the go()
function, too, which would mean that list
is now in scope:
void go() {
final JList list = ...
list.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent event) {
// list is now in scope
list.setVisibleRowCount(4);
}
});
}
Note that list
must be declared to be final if it is used in this way.
Upvotes: 1
Reputation: 10150
Because the list object is inside the scope of the go() method, not the scope of the NewGUIStuff class. The list object can only be "seen" inside the that same method.
Upvotes: 2
Reputation: 20442
The answer is, "Your inner class can see the outer class", that isn't your problem.
Your problem is that the NewGUIStuff
class does not have any member fields for the inner class to see. The list
variable that you declared is local to the go
method.
public class NewGUIStuff {
JList list; //this is a member field
...
public void go() {
...
JList list; //this is a local variable
...
}
}
Upvotes: 2