How to make a Text content disappear after some time in JavaFX?

TomJ picture TomJ · Apr 21, 2014 · Viewed 7.4k times · Source
b1.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent e) {
            try {
                Class.forName("com.mysql.jdbc.Driver");
                connect = DriverManager
                        .getConnection("jdbc:mysql://localhost:3306/project?"
                                + "user=root&password=virus");
                statement = connect.createStatement();

                preparedStatement = connect
                        .prepareStatement("select * from mark where clsnum = " + txt1.getText() + "");
                rs = preparedStatement.executeQuery();
                if (rs.next()) {
                    delete();
                } else {
                    msg.setText("Student Not Found...!");
                }
            } catch (ClassNotFoundException | SQLException ex) {
                Logger.getLogger(DeleteMark.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    });

This is my code to display a message if the query not worked(I mean if no row is returned to ResultSet rs). msg is an object of Text and its declaration and other details are -

Text msg = new Text();
msg.setFont(Font.font("Calibri", FontWeight.THIN, 18));
msg.setFill(Color.RED);

I want to make the Text disappear after sometime, like 3 or 4 seconds. Is it possible to do it in JavaFX (with the help of timer or something else you know) ? If yes, how ?

Answer

jewelsea picture jewelsea · Apr 21, 2014

Use Timelines and/or Transitions.

This answer is for a previous iteration of the question.

Sample solution code

import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;

public class BlinkingAndFading extends Application {
    @Override
    public void start(Stage stage) {
        Label label = new Label("Blinking");
        label.setStyle("-fx-text-fill: red; -fx-padding: 10px;");

        Timeline blinker = createBlinker(label);
        blinker.setOnFinished(event -> label.setText("Fading"));
        FadeTransition fader = createFader(label);

        SequentialTransition blinkThenFade = new SequentialTransition(
                label,
                blinker,
                fader
        );

        stage.setScene(new Scene(new StackPane(label), 100, 50));
        stage.show();

        blinkThenFade.play();
    }

    private Timeline createBlinker(Node node) {
        Timeline blink = new Timeline(
                new KeyFrame(
                        Duration.seconds(0),
                        new KeyValue(
                                node.opacityProperty(), 
                                1, 
                                Interpolator.DISCRETE
                        )
                ),
                new KeyFrame(
                        Duration.seconds(0.5),
                        new KeyValue(
                                node.opacityProperty(), 
                                0, 
                                Interpolator.DISCRETE
                        )
                ),
                new KeyFrame(
                        Duration.seconds(1),
                        new KeyValue(
                                node.opacityProperty(), 
                                1, 
                                Interpolator.DISCRETE
                        )
                )
        );
        blink.setCycleCount(3);

        return blink;
    }

    private FadeTransition createFader(Node node) {
        FadeTransition fade = new FadeTransition(Duration.seconds(2), node);
        fade.setFromValue(1);
        fade.setToValue(0);

        return fade;
    }

    public static void main(String[] args) {
        launch(args);
    }
}  

Answers to additional questions

lambda expression not expected here lambda expressions are not supported in -source 1.7 (use -source 8 or higher to enable lambda expressions)

You should use Java 8 and not set -source 1.7. If you wish to stick with Java 7 (which I don't advise for JavaFX work), you can replace the Lambda:

blinker.setOnFinished(event -> label.setText("Fading"));

with:

blinker.setOnFinished(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
        label.setText("Fading");
    }
});

actual and formal argument lists differ in length

Again, you should use Java 8. But if you wish to use Java 7, replace:

stage.setScene(new Scene(new StackPane(label), 100, 50));

with:

StackPane layout = new StackPane();
layout.getChildren().add(label);
stage.setScene(new Scene(layout, 100, 50));

Further recommendations

Good call on not having the text both blink and fade. Blinking text makes for pretty distracting UI, but just fading is fine.

I don't think I'd recommend fading an error message, at least until the user clicks on it or something like that. What if the user didn't see the error message before it faded away?