java - 如何在 JavaFX 中实现多线程
问题描述
我创建了一个名为 threads 的类,它带有一个应该打印矩形的 run() 方法。我无法将此线程添加到窗格,因为 .add() 不接受线程。如何成功将此线程上传到我的 JavaFX 屏幕?(这背后的想法是生成的每个矩形都将像一个新怪物,这些怪物将在其中攻击障碍物,降低其生命值)。
public class Threads implements Runnable {
@Override
public void run(){
Rectangle rect = new Rectangle((int) (Math.random() * 1000), (int) (Math.random() * 1000),100,100);
rect.setFill(Color.color(Math.random(), Math.random(), Math.random()));
}
}
public class SquareThreads extends Application {
@Override
public void start(Stage primaryStage) {
Pane root = new Pane();
Thread t1 = new Thread(new Threads ());
t1.start();
root.getChildren().add(t1);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
解决方案
假设您不想使用 JavaFx 动画工具,就像您在上一个问题中所做的那样,您可以让线程在后台创建矩形,并在创建新矩形时让您的 gui 响应:
import java.util.concurrent.TimeUnit;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;
public class SquareThreads extends Application {
@Override
public void start(Stage primaryStage) {
Pane pane = new Pane(); //container for shapes
MakeRectangles mr = new MakeRectangles (); //make new shapes on other thread
mr.getShapes().addListener((ListChangeListener<Shape>) change -> { //respond to shapes added
while (change.next()) {
//if items are removed
for (Shape s : change.getRemoved()) {
Platform.runLater(()-> pane.getChildren().remove(s));
}
//if items are added
for (Shape s : change.getAddedSubList()) {
Platform.runLater(()-> pane.getChildren().add(s));
}
}
});
Scene scene = new Scene(pane,600,600);
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.sizeToScene();
mr.start(); //start making new rectangles
}
public static void main(String[] args) {
launch(args);
}
}
class MakeRectangles implements Runnable {
//store the shapes created in an observable list
private final ObservableList<Shape> shapes;
private boolean cancel;
private final Thread t;
public MakeRectangles() {
shapes = FXCollections.observableArrayList();
t= new Thread(this);
}
@Override
public void run(){
cancel = false;
while (! cancel){
Rectangle rect = new Rectangle((int) (Math.random() * 600), (int) (Math.random() * 600),100,100);
rect.setFill(Color.color(Math.random(), Math.random(), Math.random()));
shapes.add(rect);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException ex) { ex.printStackTrace(); }
}
}
ObservableList<Shape> getShapes(){
return shapes;
}
void start(){
stop(); //stop previous run if any
t.start();
}
void stop(){
cancel = true;
try {
t.join(); //wait for completion
} catch (InterruptedException ex) { ex.printStackTrace(); }
}
}
推荐阅读
- javascript - 在全屏模式下禁用 IOS Safari 中的捏合/缩放
- ruby - ruby 中 S3 Presigned url 中的文件名如何编码
- unity3d - 如何在 RTS 游戏中使用 Raycast NGUI?
- r - r中的图形创建
- python - 如何解决关于 CNN 训练的 Value Error
- java - 使用两个列表在 Stream 内流式传输
- sql-server - 在 Server 2008 R2 上禁用旧 SSL 时出现站点加载和 sql 连接问题
- reactjs - 加拿大省份未在反应谷歌图表的地理图中标记
- git - 如何设置 git submodule init 命令使用的默认远程?
- html - django 表单:CheckboxSelectMultiple 的 id_for_label 不起作用