what I want to do is : When the program starts, user is required to input a number. When the number is 1, it will enter a loop of rectangle graphic. A graphic of rectangle stacks() will appear in screen. Then, the user needs to close the graphic(scene) and the program asks again for an input from user. If user answers 1, the rectangle graphic will appear again and so on until user gives answer other than 1. My problem is that the rectangle graphic will not appear when I insert input '1' and the window showing rectangle graphic is not responding. Also, when I give answer other than 1 at the first of the program, I thought the program would end with "Process finished with exit code 0", but it didn't. I could only force stop it with the 'stop' button. Can anyone help me? Thank you.
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);
}
}
There are 2 issues here:
Application.start
) need to return in a short time for the GUI to stay responsive. You need to use a seperate thread for the loop, if you want to keep using System.in
(which I do not recommend).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();
}