在 JavaFX 中使用递增循环逐渐输出数组。不仅要显示完整数组,还要显示最终输出之前的每个数组增量

To gradually output an array with an increment loop in JavaFX. To show not only a full array but each array increment preceding the final output

试图在 JavaFX 项目中描述增量循环在具有整数数组的 TextField 和 TextArea 节点上的工作,我输出每个步骤 这个增量。

作为一个简短的例子,假设我们有一个由字符串 6、2、74、64 和 12 组成的微型数组。在我们的 for 循环中使用 AppendText 方法会立即显示最终的完整整数数组,而我需要的是是 来显示 我的数组如何逐渐增长以及 整数如何一个接一个地弹出, 首先是 6,然后是 2 等等,直到我们得到一个完整的数组。就像我们可以在控制台中那样做。

我正在寻找有关如何在 JavaFX 中实现这一点或要学习什么才能做到这一点的信息。

非常欢迎任何具体、友好和说明性的建议。


更新:我的问题被标记为可能与另一个问题重复。

关于这个主题,请注意我期望的是重现 JavaFX 数组的渐进显示,仅此而已,不更新单个元素数组,正如在另一个问题中所问的那样,我自己的线程被怀疑是重复的。更新一个元素和更新整个元素数组,这些事情对任何人来说听起来都一样吗(“duplicate”)?

所以:

A. 如上所述,我们的问题是不同的;

B. 将我的问题声明为重复是双重错误的,因为它的答案使用了与另一个问题的答案相同的概念(任务 class)问题,否则我们也可以将我的问题标记为与所有其他堆栈溢出线程重复,我曾经从这些评论中找到自己的问题解决方案(例如关于初始化的问题和在 Java 循环内外使用分配给数组的字符串,该线程的 link 可应要求提供)。

问题和答案很好理解是人类辩证法的独立部分,即答案的相似性(尤其是部分答案,我的答案是什么情况)决不会导致问题的相似性。

PS:请先理解问题,然后再将其标记为重复。

PS2:问题已经解决,但为了遵守本站规则,我会在接受答案前遵守 48 小时的限制。

此答案假定您要添加延迟,因为 appendText 可用于无延迟的文本输出。

如果您想在 ui 中显示 long-running 任务的更新,只需在 non-application 线程上 运行 该任务并使用 Platform.runLater 更新文本。

要在特定延迟后显示文本,可以使用 Timeline 更新 text 属性(为简单起见,我使用 List):

static void showListGradually(List<?> list, StringProperty outputProperty, Duration delay) {
    // timeline updates text property to non-empty sublists
    Timeline timeline = new Timeline(new KeyFrame(delay, new EventHandler<ActionEvent>() {

        int sublistSize = 1;

        @Override
        public void handle(ActionEvent event) {
            outputProperty.set(list.subList(0, sublistSize++).toString());
        }

    }));
    timeline.setCycleCount(list.size());

     // No need to use Platform.runLater here, if this is the application thread
    Platform.runLater(() -> {
        // set initial value from fx application thread
        outputProperty.set(Collections.EMPTY_LIST.toString());

        timeline.play();
    });
}

使用showListGradually方法,例如这样:

showListGradually(Arrays.asList(6, 2, 74, 64, 12), textField.textProperty(), Duration.seconds(1));

对于有类似问题的人:

我通过实施 任务 class.

想出了一个 解决方案 来解决我自己的问题

特别是,我:

  1. 在递增循环之前初始化了一个空字符串,然后
  2. Task class 中
  3. 的标准 updateMessage 方法中放置了一个循环
  4. 使用初始化的空字符串对其进行参数化,分配给自身并添加到我的数组的相应整数中。
  5. 设置线程暂停动作,让整数的渐进显示更慢,这样看起来更赏心悦目,更引人注目,
  6. 声明了一个任务messageProperty listener
  7. 将此侦听器设置为我的 TextField setText 方法的参数

这样,每次 循环 运行时,它都完全符合我的预期 - 它 实时向集合中添加新整数 已经存在和显示的。

下面是一个 link 的小屏幕视频,展示了应用程序的工作情况 - https://youtu.be/VVwcP2Xlo18 和 我的 代码 的一部分相对于 above-mentioned 描述:

    backgroundUpdate.setOnAction(event -> {
                    tf1.setText("");            
        // Declare a Task class
        Task<Void> task = new Task<Void>() {

            // Override (declare) call method
            @Override
            public Void call() throws Exception {

                // Instantiate an empty string
                String lineOfData = "";
                int[] array1 = { 6, 2, 74, 64, 12 };

                // Loop through your array of integers
                for (int i = 0; i <= array1.length; i++) {
                    // Pause the loop
                    Thread.sleep(500);

        // Parameterize the standard 'updateMessage' method of Task class
        // Do this by assigning the initialized-above empty string incremented
        // by an Integer from declared-above array of integers, previously
        // converted into String value
                    updateMessage(lineOfData = lineOfData + (String.valueOf(array1[i])) + " ");
                }
                return null;
            }
        };
        // Add a listener on messageProperty
        task.messageProperty().addListener((obs, oldMessage, newMessage) ->

        // Set the textfield's text to new message of your listener
        tf1.setText(newMessage));
        new Thread(task).start();
    });