Reputation: 1728
So, I'm trying to define a set of methods for a large set of buttons, and I figured I could do it in a for loop, but I'm getting a syntax error which I can't decipher... Here's a simplified version of the code I want to use... The error is: "Syntax error on token(s), misplaced construct(s)"
JMenu blocks = new JMenu("Block");
menuBar.add(blocks);
for (int i=0; i < 9; i++){
public void action() {
System.out.println(i+"");
}
JMenuItem blockName = new JMenuItem(i+"");
blockName.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
action();
}
});
blocks.add(blockName);
}
Upvotes: 2
Views: 5082
Reputation: 4847
You can also do this
for (int i = 0; i < 9; i++) {
JMenuItem blockName = new JMenuItem(i + "");
blockName.setAction(new MyAction(i));
blocks.add(blockName);
}
}
class MyAction extends AbstractAction {
int param;
public MyAction(int myParameter) {
param = myParameter;
}
public void actionPerformed(ActionEvent e) {
System.out.println(String.valueOf(param));
}
}
Upvotes: 1
Reputation: 4597
Delete your action
method and place your code inside the ActionListener
public void actionPerformed(ActionEvent arg0) {
System.out.println(i+"");
// ... etc.
}
As others have mentioned in their answers, i
will not be accessible from within actionPerformed
. Specifically, see @dasblinkenlight's answer for a more thorough response.
Upvotes: 3
Reputation: 22817
You can'd define nested methods, just nested classes [inner classes], or a class nested in a method [local classes].
If you want your ActionListener
to be aware of the i
, you can't directly, or you will stumble upon such error:
local variable i is accessed from within inner class; needs to be declared final
so you should extend your JMenuItem
, or better design your application in order to decouple UI from current model status.
Upvotes: 0
Reputation: 30875
You can not have a method declartion insede for loop. The loop must be in a method body.
private void init(JMenu blocks) {
for (int i=0; i < 9; i++){
JMenuItem blockName = new JMenuItem(i+"");
blockName.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
handleAction(arg0);
}
});
blocks.add(blockName);
}
}
public void handleAction(ActionEvent event) {
Object source = event.getSource();
if(source instanceof JMenuItem) {
JMenuItem item = (JMenuItem) source;
System.out.println(item.getName());
)
}
Upvotes: 1
Reputation: 726699
Java methods are not first-class objects (or second or third-class objects; in fact, methods are not objects at all). You need to move the method into one of the classes - either your top class, or the anonymous inner class that you defined, like this:
for (int i=0; i < 9; i++) {
// You cannot access i from methods of the anonymous inner class
// because it is not final, but you can make a final copy
final int iCopy = i;
JMenuItem blockName = new JMenuItem(i+"");
blockName.addActionListener(new ActionListener() {
// It is OK to define additional methods here:
public void action() {
System.out.println(iCopy+"");
}
public void actionPerformed(ActionEvent arg0) {
action();
}
});
blocks.add(blockName);
}
Upvotes: 2
Reputation: 36611
That is simply not valid Java
. Consider creating an Action
instance in your for loop and use that action to back the JMenuItem
, e.g.
JMenu blocks = new JMenu("Block");
menuBar.add(blocks);
for (int i=0; i < 9; i++){
Action action = new AbstractAction(){
public void actionPerformed( ActionEvent e ){
System.out.println( "Whatever but not i as that cannot be accessed" );
System.out.println( "or you need to introduce a final variable" );
}
};
JMenuItem blockName = new JMenuItem(i+"");
blockName.setAction( action );
blocks.add(blockName);
}
Upvotes: 1
Reputation: 26753
You are defining a new method inside another method:
public void action() {
System.out.println(i+"");
}
You need to extract this outside of the current method.
Upvotes: 2