Проблема создания сцены в цикле while в Java - PullRequest
0 голосов
/ 18 октября 2018

что я хочу сделать: при запуске программы пользователь должен ввести число.Когда число равно 1, оно войдет в цикл прямоугольной графики.На экране появится изображение стеков прямоугольников ().Затем пользователь должен закрыть графику (сцену), и программа снова запрашивает ввод от пользователя.Если пользователь отвечает 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 голосов
/ 18 октября 2018

Как только вы войдете в цикл с xx==1, ваш экран должен быть виден.Тем не менее, вы получаете экран not responding, потому что внутри цикла вы запрашиваете ввод данных пользователем снова.Так что после того, как ваши прямоугольники нарисованы, ваш экран зависает.Если вы снова введете 1 на экране, то же самое происходит, потому что выполняется тот же цикл и возвращается к той же строке с запросом ввода.Для ясности добавьте Enter another number при запросе nextInt внутри цикла.

Одним из возможных решений является предоставление способа разорвать цикл и запросить nextInt внешний цикл.

Чтобы проверить это, когда ваш экран зависает после первого ввода 1 (затемзапрашивает другую запись из цикла), вы можете ввести что-либо, кроме 1, что прерывает цикл (например, 0).Теперь ваш экран должен ответить, и ваше приложение закрывается.

0 голосов
/ 18 октября 2018

Здесь есть 2 проблемы:

  1. Вы не должны блокировать поток приложения JavaFX.Методы, которые выполняются в этом потоке (например, Application.start), должны возвращаться за короткое время, чтобы графический интерфейс оставался отзывчивым.Вам нужно использовать отдельный поток для цикла, если вы хотите продолжать использовать System.in (что я не рекомендую).
  2. Закрытие последнего этапа автоматически отключит JavaFX по умолчанию.Это можно исправить с помощью Platform.setImplicitExit()
@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();
}
0 голосов
/ 18 октября 2018

Вы пытались использовать Platform.exit () для завершения программы, когда вам нужно это сделать?

...