javafx开关箱控制台,当进入选项时窗口会冻结吗?

6xfqseft  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(392)

所以这只是基本的控制台结构,我遵循我的gui程序,然而,我注意到每当我输入一个选项来提示一个屏幕,它最终会冻结,我知道这显然是因为无限while循环,但我没有其他方法期待控制台重新提示,只要窗口关闭。这就是为什么我依赖while循环,请有人能为我提供一个解决方案。

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.util.Scanner;

public class testGuiConsole extends Application {
        public static void main(String[] args) {
            launch();
        }

        @Override
        public void start(Stage primaryStage) throws Exception {

            BorderPane borderPane = new BorderPane();
            labelStatement:
            while (true) {
                System.out.println("Press a for method a");
                System.out.println("Press b for method b");
                System.out.println("Enter q to end program!");

                Scanner sc = new Scanner(System.in);
                String input = sc.nextLine().toLowerCase();
                switch (input) {
                    case "a":
                        optionA(borderPane, primaryStage);
                        primaryStage.show();
                        break;
                    case "b":
                        optionB(borderPane, primaryStage);
                        primaryStage.show();
                        break;
                    case "q":
                        break labelStatement;
                    default:
                        System.out.println("wrong option!");
                }
            }
        }

    private void optionA(BorderPane borderPane, Stage primaryStage) {
            primaryStage.setScene(new Scene(borderPane, 1000, 500));
        }

    private void optionB(BorderPane borderPane, Stage primaryStage) {
        primaryStage.setScene(new Scene(borderPane, 1000, 500));

    }

}
p1iqtdky

p1iqtdky1#

您不应该在fxthread中执行长时间的计算,而阻塞方法(如scanner#nextline)可能非常长。。。
您必须在单独的线程上请求该选项。根据所选的选项,您可能需要执行一些操作来修改gui。在这种情况下,您必须使用platform#runlater方法在fxthread中执行此操作。
下面是一个使用java 8的快速示例:

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

import java.lang.annotation.Native;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.function.BooleanSupplier;

public class TestGuiConsole extends Application {
    public static void main(String[] args) {
        launch();
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        final BorderPane borderPane = new BorderPane();
        borderPane.setCenter(new Label("Select an Option"));

        final Map<String, BooleanSupplier> actionMap = new HashMap<>();
        actionMap.put("a", () -> {
            optionA(borderPane);
            return false;
        });
        actionMap.put("b", () -> {
            optionB(borderPane);
            return false;
        });
        actionMap.put("q", () -> {
            closeGui(primaryStage);
            return true;
        });

        final Thread askOptionThread = new Thread(() -> askOption(actionMap));
        askOptionThread.setDaemon(true);
        askOptionThread.start();

        System.out.println("SHOW");
        primaryStage.setTitle("Options");
        primaryStage.setScene(new Scene(borderPane, 600, 400));
        primaryStage.centerOnScreen();
        primaryStage.show();
    }

    private void closeGui(Stage primaryStage) {
        Platform.runLater(primaryStage::hide);
    }

    private void optionA(BorderPane borderPane) {
        Platform.runLater(() -> {
            borderPane.setCenter(new Label("Option A selected"));
        });
    }

    private void optionB(BorderPane borderPane) {
        Platform.runLater(() -> {
            borderPane.setCenter(new Label("Option B selected"));
        });
    }

    private static void askOption(Map<String, BooleanSupplier> actionMap) {
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println("Press a for method a");
            System.out.println("Press b for method b");
            System.out.println("Enter q to end program!");

            Scanner sc = new Scanner(System.in);
            String input = sc.nextLine().toLowerCase();
            final BooleanSupplier action = actionMap.get(input);
            if (action != null) {
                boolean shouldQuit = action.getAsBoolean();
                if (shouldQuit) {
                    break;
                }
            } else {
                System.out.println("wrong option!");
            }
        }

    }

}

以下是@genesis\u kitty评论后的一个示例(可以对更好的代码进行一些优化):

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class TestGuiConsole extends Application {
    public static void main(String[] args) {
        launch();
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        final Map<String, Runnable> actionMap = new HashMap<>();
        actionMap.put("a", () -> optionA(primaryStage));
        actionMap.put("b", () -> optionB(primaryStage));
        actionMap.put("q", Platform::exit);

        Platform.setImplicitExit(false); //needed or your application will exit
        primaryStage.setTitle("Options");
        primaryStage.showingProperty().addListener((l,o,s) -> {if (!s) { launchAskOption(actionMap);}});
        launchAskOption(actionMap);
    }

    private void launchAskOption(Map<String, Runnable> actionMap) {
        final Thread askOptionThread = new Thread(() -> askOption(actionMap));
        askOptionThread.start();
    }

    private void optionA(Stage primaryStage) {
        final BorderPane borderPane = new BorderPane();
        borderPane.setCenter(new Label("Option A selected"));
        primaryStage.setScene(new Scene(borderPane, 600,400));
        primaryStage.centerOnScreen();
        primaryStage.show();
    }

    private void optionB(Stage primaryStage) {
        final BorderPane borderPane = new BorderPane();
        borderPane.setCenter(new Label("Option B selected"));
        primaryStage.setScene(new Scene(borderPane, 600,400));
        primaryStage.centerOnScreen();
        primaryStage.show();
    }

    private static void askOption(Map<String, Runnable> actionMap) {
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println("Press a for method a");
            System.out.println("Press b for method b");
            System.out.println("Enter q to end program!");

            Scanner sc = new Scanner(System.in);
            String input = sc.nextLine().toLowerCase();
            final Runnable action = actionMap.get(input);
            if (action != null) {
                Platform.runLater(action);
                break;
            } else {
                System.out.println("wrong option!");
            }
        }
    }

}

相关问题