java - Как принимать ввод с консоли и при этом не усыпляя другие потоки
Мне надо ожидать вывод с консоли в одном потоке и обновлять окно в другом.
Java 21
Пример кода:
package com.example.test;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import java.util.Timer;
import java.util.TimerTask;
public class MainFile extends Application {
public static boolean ExitUpdate = false;
public static Label label = new Label("Hello, JavaFX!");
@Override
public void start(Stage primaryStage) {
// Создаем JavaFX окно
StackPane root = new StackPane();
root.getChildren().add(label);
Scene scene = new Scene(root, 300, 200);
primaryStage.setScene(scene);
primaryStage.show();
update(root, 0);
}
public void update(StackPane root, int c) {
if (c > 1) {
c = 0;
}
switch (c) {
case 0:
root.getChildren().addAll(new Rectangle(100,100, Color.BLUE));
break;
case 1:
root.getChildren().addAll(new Rectangle(110,110, Color.RED));
break;
default:
System.out.println("err");
}
int sendc = c+1;
TimerTask timerTask = new TimerTask() {
public void run() {
Platform.runLater(new Runnable() {
@Override
public void run() {
update(root, sendc);
}
});
}
};
Timer start = new Timer("test");
start.schedule(timerTask, 1000L);
}
public static void main (String[] args) {
launch(args);
}
}
К примеру как тут сделать ожидание ввода, чтобы квадраты не переставали появляться раз в секунду.
Если это невозможно, то какую альтернативу можно использовать?
Ответы (1 шт):
Автор решения: TaranenkoAnt
→ Ссылка
Можно сделать с помощью ExecutorService, внутри него отправлять сообщение в Fx-поток через Platform.runLater()
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MainFile extends Application {
private static Label label = new Label("Hello, JavaFX!");
private final ExecutorService executor = Executors.newSingleThreadExecutor();
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
root.getChildren().add(label);
Scene scene = new Scene(root, 300, 200);
primaryStage.setScene(scene);
primaryStage.show();
executor.submit(() -> {
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("Press Enter to continue...");
String s = scanner.nextLine();
if(s != null && !s.trim().isEmpty() && s.matches("[0-9]+")) {
Platform.runLater(() -> update(root, Integer.parseInt(s)));
}
}
});
update(root, 0);
}
public void update(StackPane root, int c) {
if (c > 1) {
c = 0;
}
switch (c) {
case 0:
root.getChildren().addAll(new Rectangle(100, 100, Color.BLUE));
break;
case 1:
root.getChildren().addAll(new Rectangle(110, 110, Color.RED));
break;
default:
System.out.println("err");
}
int sendc = c + 1;
executor.submit(() -> update(root, sendc));
}
public static void main(String[] args) {
launch(args);
}
}