繁体   English   中英

javafx如何在fxml控制器中使用线程

[英]javafx how to use thread in fxml controller

我想使用可以在简单程序中使用的线程,但是不能在fxml控制器中使用线程

简单程序:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package javafxapplication3;

import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFX_TimerTask extends Application {

    final int MAX = 100;

    Thread myTaskThread;
    Thread myRunnableThread;
    Timer myTimer;

    MyTask myTask;
    MyRunnable myRunnable;
    MyTimerTask myTimerTask;

    @Override
    public void start(Stage primaryStage) {

        myTask = new MyTask();
        ProgressBar progressBarTask = new ProgressBar();
        progressBarTask.setProgress(0);
        progressBarTask.progressProperty().bind(myTask.progressProperty());

        ProgressBar progressBarRunnable = new ProgressBar();
        progressBarRunnable.setProgress(0);
        myRunnable = new MyRunnable(progressBarRunnable);

        ProgressBar progressBarTimerTask = new ProgressBar();
        progressBarTimerTask.setProgress(0);
        myTimerTask = new MyTimerTask(progressBarTimerTask);

        Button btnStart = new Button("Start Task");
        btnStart.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent t) {
                myTaskThread = new Thread(myTask);
                myTaskThread.start();

                myRunnableThread = new Thread(myRunnable);
                myRunnableThread.start();

                myTimer = new Timer();
                myTimer.scheduleAtFixedRate(myTimerTask, 80, 100);
            }
        });

        VBox vBox = new VBox();
        vBox.setPadding(new Insets(5, 5, 5, 5));
        vBox.setSpacing(5);
        vBox.getChildren().addAll(
                new Label("Run in Thread(Task)"),
                progressBarTask,
                new Label("Run in Thread(Runnable)"),
                progressBarRunnable,
                new Label("Run in Timer and TimerTask"),
                progressBarTimerTask,
                btnStart);

        StackPane root = new StackPane();
        root.getChildren().add(vBox);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("java-buddy.blogspot.com");
        primaryStage.setScene(scene);
        primaryStage.show();

    }

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

    class MyTask extends Task<Void>{

        @Override
        protected Void call() throws Exception {
            for (int i = 1; i <= MAX; i++) {
                updateProgress(i, MAX);
                Thread.sleep(100);
            }
            return null;
        }

    }

    class MyRunnable implements Runnable{

        ProgressBar bar;

        public MyRunnable(ProgressBar b) {
            bar = b;
        }

        @Override
        public void run() {
            for (int i = 1; i <= MAX; i++) {

                final double update_i = i;

                //Not work if update JavaFX UI here!
                //bar.setProgress(i/MAX);

                //Update JavaFX UI with runLater() in UI thread
                Platform.runLater(new Runnable(){

                    @Override
                    public void run() {
                        bar.setProgress(update_i/MAX);
                    }
                });

                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                    Logger.getLogger(JavaFX_TimerTask.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }

    }

    class MyTimerTask extends TimerTask{

        ProgressBar bar;
        double count;

        public MyTimerTask(ProgressBar b) {
            bar = b;
            count = 0;
        }

        @Override
        public void run() {

            bar.setProgress(count++/MAX);

            if(count >= MAX){
                myTimer.cancel();
            }

        }

    }

}

现在,我想在fxml控制器中使用线程:

public class DashboardController implements Initializable {
     @Override
        public void initialize(URL url, ResourceBundle rb) {




        } 

   }

当我使用线程时,在初始化时它不会显示任何输出。

如何使用线程?

谢谢。

JavaFx已经运行线程-

  1. 用于GUI的JavaFx线程
  2. 启动后台服务线程。

如果您需要制作类似进度条的内容,并且希望在其中通过Javafx线程运行某些内容,那么我建议您使用Services而不是thread,因为它可以一次又一次地被使用,而线程却不能。

Service<Void> ser = new Service<Void>() {
        @Override protected Task createTask() {
            return new Task<Void>() {
            @Override protected Void call() throws InterruptedException {
                // You code you want to execute in service backgroundgoes here
                return null;
                }
            };
         }
};
ser.setOnSucceeded((WorkerStateEvent event) -> {
    // Anything which you want to update on javafx thread (GUI) after completion of background process.
});
ser.start();

您可以反复使用服务,例如循环/递归/切换-

ser.restart(); // Restart the service
ser.reset(); // Stops the service

您的控制器是否已初始化?

您是否设置了它(在fxml / FXMLoader中)?

如果加载了Controller,则应该可以正常工作。

public class DashboardController implements Initializable {
 @Override
    public void initialize(URL url, ResourceBundle rb) {
        myTask = new MyTask();
         myTaskThread = new Thread(myTask);
         myTaskThread.start();


    } 
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM