如何在 java 中不使用 thread.sleep 进行图像幻灯片放映

How to NOT use thread.sleep for an image slide show in java

我正在尝试创建类似信息屏幕的东西,它只滚动浏览使用我编写的小型管理应用程序上传的图像(也许有一天的 pdf)。

经过一些阅读,我想我明白为什么我应该 NOT 在我的 for 循环中有 Thread.sleep。我在 Whosebug 和其他页面上阅读了一些教我不要这样做的帖子。

显然我应该为这样的事情使用 ExecutorService,但我无法理解它。

所以在准备好我的 GUI 和其他一切之后,我终于调用了我的 showImages 并留在这个 while 循环中。 每次循环后,我都会从文件系统重新加载记录,因此任何更改都会显示在屏幕上。

我创建了一个图元文件,其中包含每个图像的首选延迟,并只休眠一段时间。

private void showImages() {
        //noinspection InfiniteLoopStatement
        while (true) {
            loadRecords();
            for (ImageRecord record : records) {
                System.out.println("Showing: " + record.getFilename());
                imageLabel.setIcon(record.getIconForInfoScreen(screenWidth, screenHeight));
                int delay = record.getDurationAsInt();
                System.out.println("Waiting for " + delay + " milliseconds");
                try {
                    Thread.sleep(delay);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

所以如果我理解正确的话我可以使用类似

的东西
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(showImage(),0, delay, TimeUnit.MILLISECONDS);

但这会每隔“延迟”毫秒触发一次 showImage(),我仍然需要增加一些计数器,以获取记录中的下一张图像。

有人能把我推向正确的方向吗?我现在有点迷路了。

对我的问题的所有评论都可以被认为是好主意,其中之一也引导我得出最终结果。但最终,问题是我不明白如何在我的循环中实现计时器。

或者换句话说,循环必须消失,而是使用计数器并在定时器循环内设置后续记录的延迟。

    private void loopImages() {
        loadRecords();
        recordSize = records.size();
        int delay = records.get(1).getDurationAsInt();
        timer = new Timer(delay, e -> showImages());
        timer.start();
    }

    private void showImages() {
        if (recordIndex == recordSize) {
            loadRecords();
            recordSize = records.size();
            recordIndex = 0;
        }

        ImageRecord record = records.get(recordIndex);

        imageLabel.setIcon(record.getIconForInfoScreen(screenWidth, screenHeight));

        recordIndex++;
        if (recordIndex < recordSize) {
            record = records.get(recordIndex);
            int delay = record.getDurationAsInt();
            timer.setDelay(delay);
        }
    }