无法正确设置程序流程 运行 函数

Trouble setting program flow to correctly run a function

我有一个 class tasks,它使用菜单布局处理多个任务,class tasks 通过设置舞台检查应用程序流程,用菜单场景列出所有单独的任务。我想 运行 使用自己的 classes 从可用列表中执行一些任务,如下所示:

Tasks.java:

    package tasks;
    
    import javafx.application.Application;
    import javafx.stage.Stage;
    import javafx.scene.Scene;
    import javafx.scene.layout.VBox;
    import javafx.scene.control.Button;
    
    public class Tasks extends Application
    {
        private Stage window;
        private Scene menuScene;
        private Task1 task1;
    
        public Tasks()
        {
            this.window=null;
            this.menuScene=null;
            this.task1=null;
        }
    
        private void setMenu()
        {
            VBox menu=new VBox();
    
            Button newTask1Button=new Button("New Task 1");
            newTask1Button.setOnAction(clickEvent -> this.startNewTask1());
            menu.getChildren().add(newTask1Button);
    
            //More buttons
    
            this.menuScene=new Scene(menu,400,600);
        
            this.window.setScene(this.menuScene);
        }
    
        private void startNewTask1()
        {
            this.task1=new Task1(this.window);
            this.launchTask1();
        }
    
        private void launchTask1()
        {
            if(this.task1!=null)
            {
                int task1State=1;
                //while(task1State==1) //To re-run for pause state
                //{
                    task1State=this.task1.runTask1();
                    System.out.println("Task1 is in state "+task1State); //In no way part of program, just for debugging. Always give state=-1
                    //If 1-Paused, then display pause Menu for task1, by calling this.task1.paused(); and then again based on user input re-run runTask1
                    //If 0-Exit, then change the scene back to menuScene and quit the function
                //}
            }
        }
    
        @Override
        public void start(Stage primaryStage)
        {
            this.window=primaryStage;
            this.window.setTitle("Tasks");
    
            this.setMenu();
    
            this.window.show();
        }
    
        public static void main(String[] args)
        {
            Application.launch(args);
        }
    }

Task1.java:

    package tasks;
    
    import javafx.stage.Stage;
    import javafx.stage.Stage;
    import javafx.scene.Scene;
    import javafx.scene.layout.HBox;
    import javafx.scene.control.Button;
    
    class Task1
    {
        private Stage window;
        private Scene task1Scene;
        private boolean intialised;
    
        private int state;
    
        public Task1()
        {
        }
        public Task1(Stage _window)
        {
            this.window=_window;
            this.task1Scene=null; //Will be set later
            this.intialised=false;
            this.state=-1;
        }
    
        private Scene createScene()
        {
            //Creates some GUI to interact
            
            //Buttons in End, to control exit
            HBox menu=new HBox();
    
            Button pauseButton=new Button("Pause");
            pauseButton.setOnAction(clickEvent -> this.state=1);
            menu.getChildren().add(pauseButton);
            
            Button exitButton=new Button("Exit");
            exitButton.setOnAction(clickEvent -> this.state=0);
            menu.getChildren().add(exitButton);
    
            Scene scene=new Scene(menu,400,600);
    
            return scene;
        }
    
        private void setupControls()
        {
            //To assign event handlers to interact with GUI
        }
    
        public int runTask1()
        {
            if(!this.intialised)
                this.task1Scene=this.createScene();
            this.window.setScene(this.task1Scene);
    
            this.setupControls();

            //while(this.state==-1);
        
            return this.state;
        }
    }

我面临的问题是,函数 runTask1() 总是立即 returning,即使使用 Task1 的事件处理程序分配的操作仍然 运行ning 并且没有事件已生成出口。

我试图通过设置一个名为 state 的实例变量并将其设置为 -1 并放置一个 while 循环来解决这个问题,直到这个状态变量不被修改。但这完全停止了 GUI。

后来google了一下才知道是什么原因,但是一直没能确定用什么方法解决。

在某些地方,建议使用线程(不确定如何,我不想在程序中使用多个进程运行),在某些地方,还建议设置另一个事件处理程序(但是,他们 运行 在 start() 函数(继承自应用程序)本身中 运行 处理不同的进程,它更多的是转移流程而不是 return 倒退)。

我应该如何编写代码以保持 运行ning 仅 runTask1() 直到未完成,然后 return 到 launchTask1() 顺序?

class Task1 中的方法 runTask1() 中的无限 while 循环正在冻结 JavaFX application thread。删除它即可。

基本上你的 Task1 class 是另一个 Scene 所以当你点击 class Tasks 中的按钮 newTask1Button 你只是想设置一个新的 Scene.

这里是 class Task1 并进行了必要的更改。

package tasks;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.control.Button;

public class Task1 {
    private Stage window;
    private Scene task1Scene;
    private boolean intialised;

    private int state;

    public Task1() {
    }

    public Task1(Stage _window) {
        this.window = _window;
        this.task1Scene = null; // Will be set later
        this.intialised = false;
        this.state = -1;
    }

    private Scene createScene() {
        // Creates some GUI to interact

        // Buttons in End, to control exit
        HBox menu = new HBox();

        Button pauseButton = new Button("Pause");
        pauseButton.setOnAction(clickEvent -> this.state = 1);
        menu.getChildren().add(pauseButton);

        Button exitButton = new Button("Exit");
        exitButton.setOnAction(clickEvent -> this.state = 0);
        menu.getChildren().add(exitButton);

        Scene scene = new Scene(menu, 400, 600);

        return scene;
    }

    private void setupControls() {
        // To assign event handlers to interact with GUI
    }

    public int runTask1() {
        if (!this.intialised)
            this.task1Scene = this.createScene();
        this.window.setScene(this.task1Scene);

        this.setupControls();

//        while (this.state == -1)
//            ;

        return this.state;
    }
}

如您所见,我只是简单地注释掉了 while 循环。 JavaFX 应用程序线程包含一个循环,该循环等待用户操作发生,例如移动鼠标或在键盘上键入一个键。您不必在代码中处理它。

编辑

由于您问题中的代码有错字,您在对我的回答的评论中提到了这个错误,并且您在随后的编辑中更正了您的问题,我正在编辑我的答案。

JavaFX 应用程序的工作方式是它对用户操作做出反应。您希望 class Tasks 在 class Task1 中的“状态”发生变化时收到通知,并且当用户单击 [= class Task1 中的 pauseButtonexitButton。根据您发布的代码,您可以从 pauseButton.

的事件处理程序回调到 class Tasks

Class Task1.
(注意评论 CHANGE HERE 和构造函数中的额外参数。)

package tasks;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.control.Button;

public class Task1 {
    private Tasks tasks;
    private Stage window;
    private Scene task1Scene;
    private boolean intialised;

    private int state;

    public Task1(Stage _window, Tasks tasks) {
        this.tasks = tasks;
        this.window = _window;
        this.task1Scene = null; // Will be set later
        this.intialised = false;
        this.state = -1;
    }

    private Scene createScene() {
        HBox menu = new HBox();
        Button pauseButton = new Button("Pause");
        pauseButton.setOnAction(clickEvent -> tasks.setState(this.state = 1)); // CHANGE HERE
        menu.getChildren().add(pauseButton);
        Button exitButton = new Button("Exit");
        exitButton.setOnAction(clickEvent -> this.state = 0);
        menu.getChildren().add(exitButton);
        Scene scene = new Scene(menu, 400, 600);
        return scene;
    }

    private void setupControls() {
        // To assign event handlers to interact with GUI
    }

    public int runTask1() {
        if (!this.intialised) {
            this.task1Scene = this.createScene();
        }
        this.window.setScene(this.task1Scene);
        this.setupControls();
        return this.state;
    }
}

Class Tasks
(添加方法 setState(int)。)

package tasks;

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.control.Button;

public class Tasks extends Application {
    private Stage window;
    private Scene menuScene;
    private Task1 task1;

    public Tasks() {
        this.window = null;
        this.menuScene = null;
        this.task1 = null;
    }

    private void setMenu() {
        VBox menu = new VBox();
        Button newTask1Button = new Button("New Task 1");
        newTask1Button.setOnAction(clickEvent -> this.startNewTask1());
        menu.getChildren().add(newTask1Button);
        this.menuScene = new Scene(menu, 400, 600);
        this.window.setScene(this.menuScene);
    }

    private void startNewTask1() {
        this.task1 = new Task1(this.window, this);
        this.launchTask1();
    }

    private void launchTask1() {
        if (this.task1 != null) {
            this.task1.runTask1();
        }
    }

    @Override
    public void start(Stage primaryStage) {
        this.window = primaryStage;
        this.window.setTitle("Tasks");
        this.setMenu();
        this.window.show();
    }

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

    public void setState(int task1State) {
        System.out.println("Task1 is in state " + task1State); // In no way part of program,
                                                               // just for debugging.
    }
}