Кнопка отключения ваадина во время действия

Как я могу добиться этого на Ваадине.

// inside myButton click event
myButton.setEnabled(false);
doMyActionThatTakeSomeTime();
myButton.setEnabled(true);

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

Что было бы лучше всего сделать это в Ваадине 11 (или 10)?

  • принудительно обновить вид? (как?)
  • поместить мое действие в поток? (как ?)

Редактировать РЕШЕНИЕ - Как заставить его работать с потоком

Пока что пример с потоком (рабочий):

@Push 
@Route(value = "secured")
public class MainView extends VerticalLayout

[ ... ]

// inside click event
UI ui = UI.getCurrent();
new Thread(() -> {       
    ui.access(() -> {
      goButton.setEnabled(false);
      ui.push();
    });

    doMyActionThatTakeSomeTime();

    ui.access(() -> {
      goButton.setEnabled(true);
      ui.push();
    });
}).start();

person Tyvain    schedule 27.09.2018    source источник


Ответы (4)


Похоже, глава «Асинхронные обновления» в документации объясняет, что вы хотите: https://vaadin.com/docs/v11/flow/advanced/tutorial-push-access.html. В основном: запустите doMyActionThatTakeSomeTime() в отдельном фоновом потоке, затем снова включите кнопку после завершения потока, и Server Push обеспечит правильное обновление состояния пользовательского интерфейса.

Это часто задаваемая тема, здесь есть еще один ответ: Как закрыть диалоговое окно подтверждения Vaadin 8 при выполнении длительной операции Выполнение асинхронных обновлений работает в Vaadin 8 и Vaadin 10+ аналогичным образом.

person ollitietavainen    schedule 28.09.2018
comment
Проблема с этим решением все еще существует. Я теряю полосу ожидания, которая автоматически отображается вверху страницы, чтобы предупредить об ожидаемой операции. Как я могу отобразить его, когда поток запущен? - person Tyvain; 01.10.2018

В Vaadin 8 есть Button::setDisableOnClick() именно для этой цели.

Вероятно, это также следует вернуть в более новые версии.

person Jouni    schedule 28.09.2018
comment
Да, это обычная потребность, это должно быть легко реализовать. - person Tyvain; 01.10.2018
comment
Функция, запрошенная в проекте Vaadin Button Flow, выпуск GitHub № 27. - person Basil Bourque; 02.10.2018

Для меня самый простой способ:

    Button btnAction = new Button("Action");
    btnAction.setDisableOnClick(true);
    btnAction.addClickListener(e -> {
        try {
            for (int i = 0; i < 900000; i++) {
                System.out.println(i);
            }
        } finally {
            btnAction.setEnabled(true);
        }
    });
person Sergio Hilerio    schedule 09.04.2019

Лучший способ сделать это:

UI ui = UI.getCurrent();    
ui.access( () -> { 
    // disable button
    goButton.setEnabled(false);
    ui.push();

    doMyActionThatTakeSomeTime();

    // enable
    goButton.setEnabled(true);
    ui.push();
    }); 
person Tyvain    schedule 01.10.2018
comment
На самом деле то, что вы предлагаете, не является хорошим решением. У вас есть длинная операция doMyActionThatTakeSomeTime (); внутри access (), и это нехорошо. Это вызовет проблемы с заблокированными потоками. Операции, выполняемые в access (), должны быть ограничены только атомарными обновлениями пользовательского интерфейса. - person Tatu Lund; 02.10.2018
comment
Я думаю, это было лучше, потому что я также автоматически получаю отображение «ожидающей обработки». Которого я не получаю в другом решении (с потоком). Это вызывает проблемы с самим двигателем Vaadin? - person Tyvain; 03.10.2018
comment
В таких асинхронных задачах вы не должны зависеть от «ожидающей обработки» фреймворка. Это отображается во время длительных операций ожидания, например. когда пользовательский интерфейс загружает данные с сервера. В вашем случае он появляется, так как вы заблокировали пользовательский интерфейс. Это неправильный путь. Если ваша операция настолько длинная, что требуется индикация прогресса, вместо этого вы должны использовать какой-либо компонент пользовательского интерфейса, чтобы показывать прогресс и периодически обновлять его в access (), например vaadin.com/components/vaadin-progress-bar - person Tatu Lund; 03.10.2018