JavaFX Running a large amount of countdown timers at once?

前端 未结 4 1113
面向向阳花
面向向阳花 2021-01-28 10:04

So I can see a couple different ways to do what I need and I\'ve done a bunch of google/stack overflow searching but can\'t find really what I\'m looking for. I need to run mult

4条回答
  •  囚心锁ツ
    2021-01-28 10:53

    To add to the good answer posted by Jai, you could test different implementations for performance and find out if they use separate threads by a simple printout:

    import java.io.IOException;
    import javafx.animation.Animation;
    import javafx.animation.KeyFrame;
    import javafx.animation.PauseTransition;
    import javafx.animation.Timeline;
    import javafx.application.Application;
    import javafx.application.Platform;
    import javafx.concurrent.Task;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    import javafx.util.Duration;
    
    public class TimersTest extends Application {
    
        @Override public void start(Stage stage) throws IOException {
    
            System.out.println("Fx thread id "+ Thread.currentThread().getId());
    
            VBox root = new VBox(new TimeLineCounter(), new PauseTransitionCounter(), new TaskCounter());
            stage.setScene(new Scene(root));
            stage.show();
        }
    
        public static void main(String[] args) { launch(args); }
    }
    
    abstract class Counter extends Label {
    
        protected int count = 0;
        public Counter() {
            setAlignment(Pos.CENTER); setPrefSize(25, 25);
            count();
        }
    
        abstract void count();
    }
    
    class TimeLineCounter extends Counter {
    
        @Override
        void count() {
    
            Timeline timeline = new Timeline();
            timeline.setCycleCount(Animation.INDEFINITE);
            KeyFrame keyFrame = new KeyFrame(
                    Duration.seconds(1),
                    event -> {  setText(String.valueOf(count++) );  }
            );
            timeline.getKeyFrames().add(keyFrame);
            System.out.println("TimeLine thread id "+ Thread.currentThread().getId());
            timeline.play();
        }
    }
    
    class PauseTransitionCounter extends Counter {
    
        @Override
        void count() {
    
            PauseTransition pauseTransition = new PauseTransition(Duration.seconds(1));
            pauseTransition.setOnFinished(event ->{
                setText(String.valueOf(count++) );
                pauseTransition.play();
            });
            System.out.println("PauseTransition thread id "+ Thread.currentThread().getId());
            pauseTransition.play();
        }
    }
    
    class TaskCounter extends Counter {
    
        @Override
        void count() { count(this); }
    
        void count(final Label label) {
    
             Task counterTask = new Task<>() {
                    @Override
                    protected Void call() throws Exception {
                        try {
                            System.out.println("Task counter thread id "+ Thread.currentThread().getId());
                            while(true){
                                Platform.runLater(() -> label.setText(String.valueOf(count++)));
                                Thread.sleep(1000);
                            }
                        } catch (InterruptedException e) {e.printStackTrace();     }
                        return null;
                    }
                };
    
                Thread th = new Thread(counterTask);   th.setDaemon(true);    th.start();
        }
    }
    

    The printout shows, as expected, that Timeline and PauseTransition are on the FX thread, while Task is not:

    Fx thread id 15
    TimeLine thread id 15
    PauseTransition thread id 15
    Task counter thread id 19

提交回复
热议问题