JavaFX 更新屏幕
JavaFX update screen
我试图在屏幕上显示迷宫生成的过程,但在过程完成之前屏幕永远不会更新。我正在使用消费者通知 JavaFX 方面。我尝试使用 Platform.runLater()
无济于事。
以下是正在使用的文件:
"你好-view.fxml"
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.StackPane?>
<StackPane onMouseClicked="#randomize" fx:id="sp" xmlns:fx="http://javafx.com/fxml" fx:controller="com.example.demo2.HelloController">
</StackPane>
这是迷宫生成器的 t运行 版本,“BasicMaze.java”:
package com.example.demo2;
import java.util.*;
import java.util.function.Consumer;
public class BasicMaze {
public int width;
public int height;
private transient List<Consumer<BasicMaze>> consumers = new ArrayList<>();
public void reset(int w, int h) {
width = w;
height = h;
alertConsumers();
}
public void addConsumer(Consumer<BasicMaze> l) {
if (consumers == null) consumers = new ArrayList<>();
consumers.add(l);
}
public void alertConsumers() {
consumers.forEach(c -> c.accept(this));
}
public void generate() {
int slots = width * height;
do {
if (Math.random() * 10 < 1) {
alertConsumers(); //Platform.runLater tried here
slots--;
}
} while (slots > 1);
System.out.println("DONE!");
}
}
这是控制器,“HelloController.java”:
package com.example.demo2;
import javafx.fxml.FXML;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
public class HelloController {
@FXML
StackPane sp;
final Canvas canvas = new Canvas(250,250);
BasicMaze maze = new BasicMaze();
@FXML
public void initialize() {
sp.getChildren().add(canvas);
maze.addConsumer(basicMaze -> this.draw()); //platform.runLater tried here.
}
public void randomize() {
maze.reset(5, 5);
maze.generate();
}
public void draw() {
GraphicsContext gc = canvas.getGraphicsContext2D() ;
gc.setLineWidth(1.0);
gc.setFill(Color.BLACK);
for (int j = 0; j < maze.height; j++) {
for (int i = 0; i < maze.width; i++) {
gc.moveTo(Math.random()*250, Math.random()*250);
gc.lineTo(Math.random()*250, Math.random()*250);
gc.stroke();
}
}
}
}
这是主要函数存根:
package com.example.demo2;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
如果您 运行 并点击屏幕,“完成!”会出现在控制台上,会有卡顿,然后屏幕会出现一堆黑线。我正在尝试让屏幕随着每条线的绘制而更新。
好吧,这实际上非常简单(几乎没有带来不便!),这是我从 Sergey Grinev's posts 中得出的结论。所有需要改变的(几乎)是 运行 后台任务在它自己的线程上。
因此,我们将 maze.generate()
包装在一个线程中:
public void randomize() {
maze.reset(500, 500);
new Thread(maze::generate).start();
}
现在 运行稍后的初始化工作!
@FXML
public void initialize() {
sp.getChildren().add(canvas);
maze.addConsumer(basicMaze -> Platform.runLater(this::draw));
}
底层对象根本不需要改变。
我试图在屏幕上显示迷宫生成的过程,但在过程完成之前屏幕永远不会更新。我正在使用消费者通知 JavaFX 方面。我尝试使用 Platform.runLater()
无济于事。
以下是正在使用的文件:
"你好-view.fxml"
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.StackPane?>
<StackPane onMouseClicked="#randomize" fx:id="sp" xmlns:fx="http://javafx.com/fxml" fx:controller="com.example.demo2.HelloController">
</StackPane>
这是迷宫生成器的 t运行 版本,“BasicMaze.java”:
package com.example.demo2;
import java.util.*;
import java.util.function.Consumer;
public class BasicMaze {
public int width;
public int height;
private transient List<Consumer<BasicMaze>> consumers = new ArrayList<>();
public void reset(int w, int h) {
width = w;
height = h;
alertConsumers();
}
public void addConsumer(Consumer<BasicMaze> l) {
if (consumers == null) consumers = new ArrayList<>();
consumers.add(l);
}
public void alertConsumers() {
consumers.forEach(c -> c.accept(this));
}
public void generate() {
int slots = width * height;
do {
if (Math.random() * 10 < 1) {
alertConsumers(); //Platform.runLater tried here
slots--;
}
} while (slots > 1);
System.out.println("DONE!");
}
}
这是控制器,“HelloController.java”:
package com.example.demo2;
import javafx.fxml.FXML;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
public class HelloController {
@FXML
StackPane sp;
final Canvas canvas = new Canvas(250,250);
BasicMaze maze = new BasicMaze();
@FXML
public void initialize() {
sp.getChildren().add(canvas);
maze.addConsumer(basicMaze -> this.draw()); //platform.runLater tried here.
}
public void randomize() {
maze.reset(5, 5);
maze.generate();
}
public void draw() {
GraphicsContext gc = canvas.getGraphicsContext2D() ;
gc.setLineWidth(1.0);
gc.setFill(Color.BLACK);
for (int j = 0; j < maze.height; j++) {
for (int i = 0; i < maze.width; i++) {
gc.moveTo(Math.random()*250, Math.random()*250);
gc.lineTo(Math.random()*250, Math.random()*250);
gc.stroke();
}
}
}
}
这是主要函数存根:
package com.example.demo2;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
如果您 运行 并点击屏幕,“完成!”会出现在控制台上,会有卡顿,然后屏幕会出现一堆黑线。我正在尝试让屏幕随着每条线的绘制而更新。
好吧,这实际上非常简单(几乎没有带来不便!),这是我从 Sergey Grinev's posts 中得出的结论。所有需要改变的(几乎)是 运行 后台任务在它自己的线程上。
因此,我们将 maze.generate()
包装在一个线程中:
public void randomize() {
maze.reset(500, 500);
new Thread(maze::generate).start();
}
现在 运行稍后的初始化工作!
@FXML
public void initialize() {
sp.getChildren().add(canvas);
maze.addConsumer(basicMaze -> Platform.runLater(this::draw));
}
底层对象根本不需要改变。