首页 > 解决方案 > 如何在 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);
    }      
}

标签: javamultithreadingjavafx

解决方案


假设您不想使用 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();   }
    }
}

在此处输入图像描述


推荐阅读