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.