J'écris une application Swing et j'essaie de créer un menu où chaque élément de menu a son propre action :
Voici comment je voulais Résolvez ceci:
private void createGameLevelMenuItems(JMenu menu){
for (int i = 0; i<10; i++) {
JMenuItem item = new JMenuItem(new AbstractAction("Level-" + i) {
@Override
public void actionPerformed(ActionEvent e) {
game.loadGame(i);
board.refresh();
pack();
}
});
menu.add(item);
}
}
Cependant, je ne peux pas utiliser loadGame (i) , car il dit que i devrait être final. J'en comprends la raison, mais je ne sais pas comment contourner ce problème.
3 Réponses :
Pour ajouter un exemple à mon commentaire ci-dessus. Vous pouvez simplement créer une classe implémentant AbstractAction, stocker la variable i in instance et la fournir via le constructeur:
private void createGameLevelMenuItems(JMenu menu){
for (int i = 0; i<10; i++) {
JMenuItem item = new JMenuItem(new LoadAction(i));
menu.add(item);
}
}
private class LoadAction extends AbstractAction {
private int i;
public LoadAction(int i) {
super("Level-" + i);
this.i = i;
}
@Override
public void actionPerformed(ActionEvent e) {
game.loadGame(i);
board.refresh();
pack();
}
};
Cela suppose que le jeu et le plateau sont des variables finales dans la classe d'encapsulation, mais puisque vous avez juste un problème avec i , je suppose que c'est le cas.
Petite astuce: définissez une variable finale à chaque itération de la boucle qui prend la valeur (non finale) de i et utilisez-la:
private void createGameLevelMenuItems(JMenu menu){
for (int i = 0; i<10; i++) {
final int j = i; // <--- this line do the thing
JMenuItem item = new JMenuItem(new AbstractAction("Level-" + j) {
@Override
public void actionPerformed(ActionEvent e) {
game.loadGame(j);
board.refresh();
pack();
}
});
menu.add(item);
}
}
Oui, les variables locales dans une fonction doivent être définitives. Quand j'arrive à ce problème, je définis simplement une variable factice dans la boucle for:
for (int i=0;i<10;i++) {
int useI = i;
JMenuItem item = new JMenuItem(new AbstractAction("Level-" + i) {
@Override
public void actionPerformed(ActionEvent e) {
game.loadGame(useI);
board.refresh();
pack();
}
});
}
Vous pouvez simplement créer une classe implémentant AbstractAction, stocker la variable i in instance et la fournir via le constructeur.