java - Vaadin 按钮单击不会立即执行

标签 java vaadin vaadin7

我有带有过滤器表单、一些按钮和大网格的页面。我可以根据过滤器表单搜索数据,并在网格中显示数据。搜索数据提供线程,可能需要几秒到几分钟左右。当我想单击按钮停止搜索(基本上是停止线程)时,该操作始终在线程完成后执行。但我需要在线程工作时执行点击事件。有人知道怎么做吗? :)

UI 有 @Push(PushMode.MANUAL),并且推送工作正常

简化代码:

@SpringComponent
@UIScope
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DistraintSearchComponent extends CustomComponent {

    @Autowired
    private Service service
    private Button searchButton = new Button("Search");
    private Button stopButton = new Button("Stop");
    private Thread searchThread;

    public void init(){

        searchButton.addClickListener(new ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                searchThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        List<Results> results = service.findByFilter(filter); //this can take some time
                        refreshGrid(results);
                        getUI().push();
                    }
                });
                searchThread.start();
            }
        });

        stopButton.addClickListener(new ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                searchThread.interrupt();
            }
        });

    }
}

谢谢

最佳答案

searchThread.interrupt() 在没有线程合作的情况下不会停止线程。来自 documentation我们可以看到它的作用:

If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.

If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.

If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.

If none of the previous conditions hold then this thread's interrupt status will be set.

原因是你不能在任何地方停止执行,这会产生很多未定义的行为。相反,您应该以受控方式停止线程。

因此,在您的搜索线程中(在您的情况下,它可能位于 service.findByFilter(filter); 内),您应该反复检查线程是否应该结束:

 while (!Thread.currentThread().isInterrupted()) {
 // fetch another entry
}

文档还说您可以接收 InterruptedExceptionClosedByInterruptException,以便在处理此异常时可以停止处理。 ClosedByInterruptExceptionIOException,因此这两个异常都是必须处理的已检查异常,但也许您没有调用任何会引发此类异常的内容。

try {
    Thread.currentThread().sleep(123);
} catch (InterruptedException e) {
    return; // return from service.findByFilter(filter);
}

关于java - Vaadin 按钮单击不会立即执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51839402/

相关文章:

java - 在 ListSeries 的 Vaadin 图表中设置条形颜色(在 BasicColumn 上)

maven - 使用 Maven 和 Spring Boot 的 Vaadin 自定义组件/小部件

java - 在 Openshift 中部署 Vaadin 应用程序

java - 如何在 JavaFx 中设置 svgPath 的大小

Java 十进制格式解析问题

java - Tomcat 之战 - Spring Vaadin 应用程序

java - 包含换行符的文件中的字符串未在 TextArea 中设置

java - LibGdx 不缩放到整个屏幕

java - 在当前项目和插件组 org.codehaus.mojo 中找不到前缀为 'exec' 的插件

java - Apache 与 vaadin7 共用电子邮件吗?