使用 JavaFX 在文本上“键入”动画

Rah*_* S. 2 java javafx

因此,我尝试起草一种方法,该方法需要一个字符串和一个文本,理论上会逐渐将字符串输出到该文本,就像有人正在输入它一样。然而,所发生的只是程序暂停不同的时间(由于每次添加字母之间的暂停使用了随机值),然后显示整个字符串。

public void keyboard(String string, Text tBox, Stage stage, Scene scene) {
    //generates a random number which later determines the amount of time the game pauses before
    //adding the next character
    Random number = new Random();

    //stores the length of a string (as an integer)
    int stringLen = string.length();

    //gets increased later
    int counter = 0;

    char[] chars = new char[(stringLen+1)];
    string.getChars(0, stringLen, chars, 0);

    String returnVal = "";

    do {
        returnVal += Character.toString(chars[counter]);
        counter += 1;
        tBox.setText(returnVal);
        pause((number.nextInt(3) + 1) * 100);
        stage.setScene(scene);
        stage.show();
    } while (returnVal != string);

}
Run Code Online (Sandbox Code Playgroud)

暂停方法如下。

private void pause(int milliseconds) {
    try {
        Thread.sleep(milliseconds);
    } catch (InterruptedException err) {
        System.err.println("Interrupted during pause.");
        System.exit(0);
    }
}
Run Code Online (Sandbox Code Playgroud)

请哈尔普。

编辑:

public void keyboard(String string, Text tBox) {
    final IntegerProperty counter = new SimpleIntegerProperty(0);
    Random number = new Random();
    int length = string.length();
    tBox.setFill(Color.WHITE);

    Timeline line = new Timeline();
    KeyFrame frame = new KeyFrame(Duration.seconds((number.nextInt(3) + 1) / 10),
        event -> { 
            if(counter.get() > length) {
                line.stop();
            } else {
                tBox.setText(string.substring(0, counter.get()));
                counter.set(counter.get() + 1);
            }
        });

    line.getKeyFrames().add(frame);
    line.setCycleCount(Animation.INDEFINITE);
    line.play();
}
Run Code Online (Sandbox Code Playgroud)

仅供参考,当您在 TextField 中键入内容时,键盘方法就会启动,然后检查输入是否有效,并据此启动动画。

Ita*_*iha 5

当您调用时,您正在阻塞 JavaFX 应用程序线程,Thread.sleep()这不是正确的方法。

如果您需要动画,您应该使用Timeline它。

时间轴在指定的时间间隔过去或之后处理单个关键帧

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main extends Application {
    private final String str ="Itachi";

    @Override
    public void start(Stage primaryStage) {
        Text text = new Text();
        VBox root = new VBox(text);
        root.setAlignment(Pos.CENTER);
        Scene scene = new Scene(root, 330, 120, Color.WHITE);
        primaryStage.setScene(scene);
        primaryStage.show();

        final IntegerProperty i = new SimpleIntegerProperty(0);
        Timeline timeline = new Timeline();
        KeyFrame keyFrame = new KeyFrame(
                Duration.seconds(1),
                event -> {
                    if (i.get() > str.length()) {
                        timeline.stop();
                    } else {
                        text.setText(str.substring(0, i.get()));
                        i.set(i.get() + 1);
                    }
                });
        timeline.getKeyFrames().add(keyFrame);
        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.play();
    }

    public static void main(String[] args) {
        Application.launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)