Skip to content

Instantly share code, notes, and snippets.

@Da9el00
Created June 3, 2021 17:50
Show Gist options
  • Save Da9el00/c482c89aede0f5ceff1a12b55ea65ed1 to your computer and use it in GitHub Desktop.
Save Da9el00/c482c89aede0f5ceff1a12b55ea65ed1 to your computer and use it in GitHub Desktop.
JavaFX and Scene Builder - Writing text animation with threads
import com.jfoenix.controls.JFXButton;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.text.Text;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
TextAnimator textAnimator;
@FXML
private Text text;
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
TextOutput textOutput = new TextOutput() {
@Override
public void writeText(String textOut) {
Platform.runLater(new Runnable() {
@Override
public void run() {
text.setText(textOut);
}
});
}
};
textAnimator = new TextAnimator("Hello World!",
100, textOutput);
}
@FXML
void start(ActionEvent event) {
Thread thread = new Thread(textAnimator);
thread.start();
}
}
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXButton?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: #4e586e;" xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
<Text fx:id="text" fill="WHITE" layoutX="70.0" layoutY="231.0" strokeType="OUTSIDE" strokeWidth="0.0">
<font>
<Font size="75.0" />
</font>
</Text>
<JFXButton buttonType="RAISED" layoutX="240.0" layoutY="339.0" onAction="#start" prefHeight="47.0" prefWidth="120.0" style="-fx-background-color: #ffffff;" text="Start" />
</children>
</AnchorPane>
import java.util.Random;
public class TextAnimator implements Runnable {
private String text;
private int animationTime;
private TextOutput textOutput;
private Random random = new Random();
public TextAnimator(String text, int animationTime, TextOutput textField) {
this.text = text;
this.animationTime = animationTime;
this.textOutput = textField;
}
@Override
public void run() {
try {
for (int i = 0; i <= text.length(); i++) {
String textAtThisPoint = text.substring(0,i);
textOutput.writeText(textAtThisPoint);
Thread.sleep(animationTime + random.nextInt(150));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public interface TextOutput {
void writeText(String text);
}
@Da9el00
Copy link
Author

Da9el00 commented Aug 4, 2021 via email

@Da9el00
Copy link
Author

Da9el00 commented Aug 5, 2021 via email

@khan5ula
Copy link

Good snippet. It works well with Swing with minor tweaks. With Swing, Platform should be replaced with SwingUtilities. Here's my implementation:

    TextOutput textOutput = new TextOutput() {
        @Override
        public void writeText(String textOut) {
            SwingUtilities.invokeLater(() -> questionTextArea.setText(textOut));
        }
    };

    this.textAnimator = new TextAnimator(game.getCurrentQuestion(), 10, textOutput);
    new Thread(textAnimator).start();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment