在Java中的while循环中创建场景时出现问题

时间:2018-10-18 14:08:00

标签: java javafx scene

我想要做的是:程序启动时,要求用户输入数字。当数字为1时,它将进入一个矩形图形循环。屏幕上将出现一个矩形stacks()的图形。然后,用户需要关闭图形(场景),然后程序再次要求用户输入。如果用户回答1,则矩形图形将再次出现,依此类推,直到用户给出除1以外的其他答案。我的问题是,当我插入输入“ 1”时,矩形图形将不会出现,并且显示矩形图形的窗口没有响应。另外,当我在程序的第一个给出除1之外的其他答案时,我以为程序将以“退出代码为0的处理完成”结束,但没有。我只能使用“停止”按钮强制停止它。谁能帮我?谢谢。

  package sample;

import java.io.*;
import java.util.*;
import javafx.application.Application;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.scene.Scene;

import static javafx.scene.paint.Color.BLUE;
import static javafx.scene.paint.Color.RED;

public class Main extends Application{
    @Override
    public void start (Stage primaryStage) throws Exception
    {
        System.out.println("Enter a number: ");
        Scanner scanner = new Scanner(System. in);
        int xx = scanner.nextInt();
        while(xx==1)
        {
            Rectangle rectangle;
            ArrayList<Boolean> bool = new ArrayList<Boolean>();
            AnchorPane root = new AnchorPane();
            for(int i=0; i<10; i++)
            {
                if(i%2 ==0)
                    bool.add(true);
                else
                    bool.add(false);
            }
            //Coordinate variables
            int y=50;
            //Rectangle loop
            for(int i=0; i<10; i++)
            {
                rectangle = new Rectangle();
                if(bool.get(i))
                {
                    rectangle.setX(50);
                    rectangle.setY(y);
                    rectangle.setWidth(150.0);
                    rectangle.setHeight(50.0);
                    rectangle.setFill(RED);
                }
                else
                {
                    rectangle.setX(50);
                    rectangle.setY(y);
                    rectangle.setWidth(150.0);
                    rectangle.setHeight(50.0);
                    rectangle.setFill(BLUE);
                }
                y+=50;
                root.getChildren().add(rectangle);
            }
            primaryStage.setTitle("Rectangle");
            Scene scene = new Scene(root ,600, 700);
            primaryStage.setScene(scene);
            primaryStage.show();
            primaryStage.setResizable(false);
            xx=scanner.nextInt();
        }
    }

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

3 个答案:

答案 0 :(得分:1)

这里有2个问题:

  1. 您不得阻止JavaFX应用程序线程。在该线程上执行的方法(例如Application.start)需要在短时间内返回,以使GUI保持响应。如果要继续使用System.in(我不建议这样做),则需要为循环使用一个单独的线程。
  2. 关闭最后一个阶段将默认自动关闭JavaFX。可以使用Platform.setImplicitExit()
  3. 修复此问题
@Override
public void start(Stage primaryStage) throws Exception {
    // don't automatically shutdown toolkit on window close
    Platform.setImplicitExit(false);

    primaryStage.setTitle("Rectangle");
    AnchorPane root = new AnchorPane();
    Scene scene = new Scene(root, 600, 700);
    primaryStage.setScene(scene);
    primaryStage.setResizable(false);

    // semaphore for synchronizing the closing 
    final Semaphore semaphore = new Semaphore(1);

    // notify loop of window being closed
    primaryStage.setOnHidden(evt -> semaphore.release());

    final Scanner scanner = new Scanner(System.in);
    System.out.println("Enter a number: ");

    Runnable runnable = () -> {

        while (true) {
            // wait for window to be closed
            try {
                semaphore.acquire();
            } catch (InterruptedException ex) {
                return;
            }

            // read number
            int xx = scanner.nextInt();

            if (xx == 1) {
                ArrayList<Boolean> bool = new ArrayList<>();
                for (int i = 0; i < 10; i++) {
                    if (i % 2 == 0) {
                        bool.add(true);
                    } else {
                        bool.add(false);
                    }
                }
                //Coordinate variables
                int y = 50;

                Node[] children = new Node[bool.size()];

                //Rectangle loop
                for (int i = 0; i < children.length; i++) {
                    Rectangle rectangle = new Rectangle(50, y, 150.0, 50.0);
                    rectangle.setFill(bool.get(i) ? RED : BLUE);
                    y += 50;
                    children[i] = rectangle;
                }

                // update gui
                Platform.runLater(() -> {
                    root.getChildren().setAll(children);
                    primaryStage.show();
                });
            } else {
                // shutdown javafx
                Platform.exit();
                break;
            }
        }
    };
    new Thread(runnable).start();
}

答案 1 :(得分:0)

您是否在需要时尝试使用Platform.exit()完成该程序?

答案 2 :(得分:0)

使用xx==1进入循环后,屏幕应该可见。但是,您得到not responding屏幕,因为在循环内,您正在要求用户再次提供输入。因此,在绘制矩形之后,屏幕将冻结。如果再次在屏幕上输入1,则会发生相同的事情,因为执行了相同的循环并返回到同一行以请求输入。为了清楚起见,在循环内询问Enter another number时添加nextInt

一种可能的解决方案是提供一种打破循环并要求nextInt外循环的方法。

要验证这一点,当屏幕上的1第一次输入后冻结(然后它要求从循环中再输入一次)时,您可以输入1以外的任何东西来中断循环(例如0) 。因此,您的屏幕现在应该会响应,并且您的应用程序会终止。