【问题标题】:javafx how to use thread in fxml controllerjavafx如何在fxml控制器中使用线程
【发布时间】:2014-07-06 13:42:59
【问题描述】:

我想使用可以在简单程序中使用的线程,但我不能在 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) {




        } 

   }

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

如何使用线程?

谢谢。

【问题讨论】:

  • 我没有看到您在 start(Stage) 方法中加载 fxml 控制器的位置
  • 您说“当我在初始化时使用线程时,它不会显示任何输出”,但您的 initialize 方法不包含任何尝试使用线程的代码。其实方法是空的。

标签: java multithreading javafx javafx-2 javafx-8


【解决方案1】:

JavaFx 已经运行线程 -

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

如果您需要制作进度条之类的东西,希望在其中通过 javafx 线程运行某些东西,那么我建议使用服务而不是线程,因为它可以一次又一次地使用,而线程不能。

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

【讨论】:

    【解决方案2】:

    你的控制器初始化了吗?

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

    如果你的控制器已加载,这应该可以工作。

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

    【讨论】:

      猜你喜欢
      • 2013-12-25
      • 1970-01-01
      • 2014-11-07
      • 2016-08-20
      • 1970-01-01
      • 2015-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多