JavaFX:如何将Button属性绑定到线程状态?

时间:2017-08-17 04:17:10

标签: java multithreading javafx javafx-8 observable

我有一个javafx应用程序,可以在按钮点击时启动一个新线程。

以下是启动帖子的方法:

private void startTest() {
        String[] args = {};
        String threadId = TestRunner.class.getSimpleName();
        mainApp.setRunner(new Thread(() -> {
            try {
                TestRunner.main(args);
            } catch (Throwable e) {
                LOGGER.fatal(e.getMessage(), e);
            }
        }, threadId));
        mainApp.getRunner().start();
    }

我可以使用ThreadsetRunner()访问者从mainApp获取并设置getRunner()个对象。

这就是目前正在发生的事情:

  • 我启动了该应用程序
  • 点击按钮[START]
  • 点击后,系统会启动新主题,我会将[START]按钮的文字更改为[PAUSE]
  • 我知道线程会在某个时间点完成(当任务完成时)

    我想要实现的目标:

  • 我想在线程完成后/线程死亡时将现在[PAUSE]按钮的文本更改为[START]
  • 还有一些依赖于线程状态的事情

    我该怎么做?

    我目前正在玩可观察的布尔值,但我可以使用一些帮助来实现这一点。

    提前致谢!

  • 2 个答案:

    答案 0 :(得分:2)

    使用Service管理主应用程序中的后台线程(或您当前管理runner属性的任何位置)。类似的东西:

    public class MainApp {
    
        private final Service<Void> testService = new Service<Void>() {
            @Override
            protected Task<Void> createTask() {
                return new Task<Void>() {
                    @Override
                    protected Void call() throws Exception {
                        // code to execute on background thread here:
                        while (! isCancelled() ) {
                            // ...
                        }
                    }
                }
            }
        };
    
        public Service<Void> getTestService() {
            return testService();
        }
    
        // ...
    }
    

    然后在您的用户界面中,您需要做的就是

    Button startButton = new Button();
    startButton.textProperty().bind(Bindings.
        when(mainApp.getTestService().runningProperty()).
        then("Pause").
        otherwise("Start"));
    startButton.setOnAction(e -> {
        if (mainApp.getTestService().isRunning()) {
            mainApp.getTestService().cancel();
        } else {
            mainApp.getTestService().restart();
        }
    });
    

    Task documentation有大量信息和示例,说明如何实施Task Service方法返回的createTask()

    答案 1 :(得分:0)

    更改节点内线程的值:

    您有两种选择可以做您想做的事情,您可以使用Task类并通过更改任务值来绑定您的按钮,您有updateMessage(“”)和updateValue()或updateTitle,或者您可以使用Platform类在你的线程内部。

            Button StartButton=new Button("Start");
            Thread TestThread=new Thread(new Runnable(){
               @Override
               public void run()
                 {
                  Platform.runLater(new Runnable(){
               @Override
               public void run()
                 {
    
                 StartButton.setText("Pause");    
    
    
                 }
                 while(true)
                {
                  }
    
    
                }
             );
            StartButton.addEventHandler(event->{
                 if(StartButton.getText().equals("Start"))
                 {
                  StartThread.start();
                 }else{
                 StartThread.interrupt();  
                  }