Как решить локальные переменные в цикле for? - PullRequest
0 голосов
/ 04 января 2019

Я пишу приложение Swing и пытаюсь создать меню, в котором каждый пункт меню имеет свое действие :

Вот как я хотел это решить:

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);
    }
}

Однако я не могу использовать loadGame(i), потому что там написано, что i должно быть окончательным. Я понимаю причину этого, но я не знаю, как обойти это.

Ответы [ 3 ]

0 голосов
/ 04 января 2019

Быстрый трюк: определите конечную переменную на каждой итерации цикла, которая принимает (не окончательное) значение i, и используйте ее:

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);
  }
}
0 голосов
/ 04 января 2019

Да, локальные переменные внутри функции должны быть окончательными. Когда я подхожу к этой проблеме, я просто определяю фиктивную переменную внутри цикла 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();
        }
    });
}
0 голосов
/ 04 января 2019

Чтобы добавить пример к моему комментарию выше. Вы можете просто создать класс, реализующий AbstractAction, сохранить переменную i в экземпляре и предоставить ее через конструктор:

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();
    }
};

Предполагается, что игра и доска являются окончательными переменными в классе инкапсуляции, но, поскольку у вас просто проблема с i, я полагаю, что это так.

...