Динамические действия кнопок JavaFX [дубликат]

Используя ES2017, вы должны иметь это как объявление функции

async function foo() {
    var response = await $.ajax({url: '...'})
    return response;
}

и выполнить его следующим образом.

(async function() {
    try {
        var result = await foo()
        console.log(result)
    } catch (e) {}
})()

Или синтаксис Promise

foo().then(response => {
    console.log(response)

}).catch(error => {
    console.log(error)

})
3
задан Uulamock 12 February 2015 в 19:39
поделиться

5 ответов

Как говорится в сообщении об ошибке, локальные переменные, на которые ссылается выражение lambda, должны быть окончательными или фактически окончательными («эффективно окончательный», что означает, что компилятор может сделать его окончательным для вас).

Простой обходной путь:

for(i = 0; i < 10; i++) {
    final int ii = i;
    button[i].setOnAction( ae -> { button[ii].setDisable(true) } );
}
5
ответ дан immibis 5 September 2018 в 07:48
поделиться

Лямбда-выражения эффективно похожи на анонимный метод, который работает в потоке. Чтобы избежать каких-либо небезопасных операций, Java сделала невозможным доступ к внешним переменным, которые можно изменить, в выражении лямбда.

Чтобы обойти это,

final int index = button [i]; И используйте индекс вместо i внутри вашего выражения лямбда.

0
ответ дан dark3viL 5 September 2018 в 07:48
поделиться

Поскольку вы используете lambdas, вы также можете воспользоваться другими функциями Java 8, например потоками.

Например, IntStream:

Последовательность примитивные значения элементов, поддерживающие последовательные и параллельные агрегированные операции. Это int-примитивная специализация Stream.

может использоваться для замены цикла for:

IntStream.range(0,10).forEach(i->{...});

, поэтому теперь у вас есть индекс, который можно использовать для ваша цель:

IntStream.range(0,10)
         .forEach(i->button[i].setOnAction(ea->button[i].setDisable(true)));

Также вы можете сгенерировать поток из массива:

 Stream.of(button).forEach(btn->{...});

В этом случае у вас не будет индекса, так как @shmosel предлагает, вы можете использовать источник события:

Stream.of(button)
          .forEach(btn->btn.setOnAction(ea->((Button)ea.getSource()).setDisable(true)));    

EDIT

Как указывает @James_D, здесь нет необходимости понижать прогноз:

Stream.of(button)
      .forEach(btn->btn.setOnAction(ea->btn.setDisable(true)));

В обоих случаях вы также можете воспользоваться параллельными операциями:

IntStream.range(0,10).parallel()
         .forEach(i->button[i].setOnAction(ea->button[i].setDisable(true)));

Stream.of(button).parallel()
          .forEach(btn->btn.setOnAction(ea->btn.setDisable(true)));
0
ответ дан José Pereda 5 September 2018 в 07:48
поделиться

Вы говорите, если кнопка нажата, но в вашем примере все кнопки в списке будут отключены. Попробуйте связать слушателя с каждой кнопкой, а не просто отключить его.

Для логики вы имеете в виду что-то вроде этого:

Arrays.asList(buttons).forEach(
        button -> button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                button.setEnabled(false);

            }
}));

Мне также нравится ответ Седрика, но у вас есть для добавления прослушивателя действий внутри цикла.

0
ответ дан Mahdi El Masaoudi 5 September 2018 в 07:48
поделиться

Используйте Event, чтобы получить источник Node.

for(int i = 0; i < button.length; i++)
{
     button[i].setOnAction(event ->{
         ((Button)event.getSource()).setDisable(true);
     });
}
0
ответ дан Sedrick 5 September 2018 в 07:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: