设置程序流以正确运行函数时出现问题

6pp0gazn  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(220)

我有一个类任务,它使用菜单布局处理多个任务,类任务通过设置后台检查应用程序流,用菜单场景列出所有单个任务。我想使用自己的类从可用列表中运行一些任务,如下所示:
任务.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() 总是立即返回,即使使用task1的事件处理程序分配的操作仍在运行且未生成退出事件。
我试图通过设置一个名为state的示例变量并将其设置为-1来解决这个问题,并放置一个while循环,直到这个状态变量没有被修改为止。但这完全停止了gui。
后来我通过谷歌搜索发现了原因,但无法确定该用哪种方法来解决这个问题。
在某些地方,建议使用线程(不确定如何使用,我不希望在程序中运行多个进程),在某些地方,还建议设置另一个事件处理程序(但是,它们在程序中运行不同的进程) start() 函数(从应用程序继承)本身,它更多的是传递流,而不是向后返回)。
我应该如何编写代码以仅保持运行 runTask1() 直到它还没有完成,回到 launchTask1() 按顺序?

oewdyzsn

oewdyzsn1#

无限 while 循环输入法 runTask1() 在课堂上 Task1 正在冻结javafx应用程序线程。把它取下来。
基本上是你的 Task1 上课是另一回事 Scene 所以当你点击按钮 newTask1Button 在课堂上 Tasks 你只需要设置一个新的 Scene .
这是上课时间 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应用程序的工作方式是对用户操作做出React。你要上课吗 Tasks 上课时要通知“状态” Task1 ,并且当用户单击 pauseButton 或者 exitButton 在课堂上 Task1 . 根据你发布的代码,你可以回调到类 Tasks 从的事件处理程序 pauseButton .
班级 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 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;
    }
}

班级 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.
    }
}

相关问题