0

JavaFX プロジェクトで、整数の配列を持つ TextField ノードと TextArea ノードのインクリメント ループの動作を記述しようとして、このインクリメントの各ステップを出力する必要がありました。

簡単な例として、文字列 6、2、74、64、および 12 の小さな配列があるとします。for ループ内で使用される AppendText メソッドは、整数の最終的な完全な配列をすぐに表示しますが、必要なの、配列は徐々に大きくなり、完全な配列が得られるまで、最初は 6、次に 2 というように整数が 1 つずつポップアップします。コンソールでできるのと同じように。

JavaFXでこれを実現する方法、またはそれを行うために何を学ぶべきかについての情報を探しています。

具体的で親切で実例となるアドバイスは大歓迎です。


更新:私の質問は、別の質問と重複している可能性があるとマークされました。

この件に関して、私が期待していたのは、配列の1つの要素を更新するのではなく、JavaFX配列の段階的な表示を再現することであり、自分のスレッドの複製が疑われる別の質問で尋ねられた. 1 つの要素の更新と要素の配列全体の更新は、誰にとっても同じ (「重複」) に聞こえますか?

そう:

A.上で説明したように、私たちの質問は異なります。

B.私の質問を重複として宣言することは二重に間違っています。なぜなら、その回答は別の質問への回答と同じ概念 (Task クラス) を使用しているからです。そこから、私は自分の質問に対する解決策を見つけていました(たとえば、初期化に関するものと、Javaループ内外で配列に割り当てられた文字列の使用、そのスレッドへのリンクはリクエストに応じて利用できます)。

質問と回答は、人間の弁証法の独立した部分であることがよく理解されています。つまり、回答の類似性 (特に、私の回答の場合のように部分的なもののみ) は、質問の類似性には決してつながりません。

PS:重複としてマークする前に、質問を理解してください。

PS2: 質問は既に解決されていますが、このサイトのルールを遵守するために、回答を受け入れる前に 48 時間の制限を尊重します。

4

2 に答える 2

0

appendTextこの回答は、遅延なしのテキスト出力で機能するため、遅延を追加することを前提としています。

代わりに ui で実行時間の長いタスクの更新を表示したい場合は、そのタスクを非アプリケーション スレッドで実行しPlatform.runLater、テキストを更新するために使用します。

特定の遅延の後にテキストを表示するには、プロパティTimelineを更新するために a を使用できます (簡単にするために a を使用します)。textList

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));
于 2016-01-03T14:30:07.187 に答える
0

同様の質問がある人のために:

Task クラスを実装することで、自分の質問に対する解決策を思いつきました。

特に、私は:

  1. インクリメント ループの前に空の文字列を初期化し、次に
  2. Taskクラスの標準のupdateMessageメソッドをループに配置します。
  3. それ自体に割り当てられた初期化された空の文字列でパラメータ化すると、配列の対応する整数に追加されます。
  4. スレッドの一時停止アクションを設定して、整数の段階的な表示を遅くし、より見やすく、より目立つようにします。
  5. Task messageProperty リスナーを宣言し、
  6. このリスナーを TextField setText メソッドのパラメーターとして設定します

このようにして、ループが実行されるたびに、期待どおりの動作をします。新しい整数が、既存の表示された整数のセットにリアルタイムで追加されます。

以下は、アプリケーションの動作がどのように見えるかを示す小さなスクリーン キャッチ ビデオへのリンクです。https://youtu.be/VVwcP2Xlo18と、上記の説明に関連するコードの一部です。

    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();
    });
于 2016-01-05T00:22:03.007 に答える