当前位置: 首页 > 知识库问答 >
问题:

JavaFX在for循环中向anchorpane添加节点,但每次迭代都要等待几秒钟才能添加下一个节点[重复]

拓拔俊艾
2023-03-14

我在做一个游戏,应该发生的是,在一个for循环中,在一个arraylist上迭代。在每个循环中,我想向场景中添加一个节点,然后等待一段时间,再向场景中添加另一个节点。每次迭代之间的时间也在arraylist的项中定义,每次迭代可以不同。

我尝试过的:

    //Circle is my own class, other than these attributes along with getters it has nothing in it.
    //The last number is the time to wait.
    //Also for testing i used a static arraylist, normally the items come from a json file.
    ArrayList<Circle> lvlNodes = new ArrayList<>();
    lvlNodes.add(new Circle(50,50, Color.RED,250,100));
    lvlNodes.add(new Circle(200,100, Color.BLUE,500,250));
    lvlNodes.add(new Circle(900,500, Color.YELLOW,750,500));
    lvlNodes.add(new Circle(400,50, Color.GREEN,1000,500));

   //Iterating over the arraylist and adding the nodes.
   for (int i=0; i<lvlNodes.size(); i++) {
        Circle currentNode = lvlNodes.get(i);

        //Add the node the the anchor pane.
        view.addLvlNode(currentNode, diameter); //diameter is a final value, all nodes in the game are the same and thus only added once at the top of the json file

        //Wait and move on to the next one.
        try {
           Thread.sleep(currentNode.getTimeToNextNode())
        } catch (InterruptedException e) {
            System.out.println(e);
        }
        
    }



  //Adds the next node to the game.
  public void addLvlNode(Circle circle, double diameter) {
    //Create node.
    javafx.scene.shape.Circle lvlNode = new javafx.scene.shape.Circle(circle.getPosX(), 
          circle.getPosY(), diameter/2);

    //Anchor node the the anchorpane.
    AnchorPane.setTopAnchor(lvlNode, (double)circle.getPosY());
    AnchorPane.setLeftAnchor(lvlNode, (double)circle.getPosX());
    anchrLevel.getChildren().add(lvlNode);
    lvlNode.toBack();
  }//addLvlNode.

线。sleep()可以工作,for循环中的每个迭代都有一个时间间隔。但是在for循环完成迭代之前,不会添加节点。

有没有办法在for循环中添加节点,时间量介于两者之间?

共有1个答案

雷献
2023-03-14

您遇到的问题是,您所有的代码都在FXAT上运行,当FXAT忙于运行该代码时,它无法执行诸如更新屏幕以实际添加圆圈之类的操作。因此,当你的代码完成后,包括所有的Thread.sleep()调用,它会同时完成所有的屏幕绘制。

我没有构建自定义的Circle类,而是构建了一些数组来保存这些圆圈和等待时间。然后我把addLvlNode

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

import java.util.ArrayList;

public class CircleMaker extends Application {

    private Pane mainPain;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        ArrayList<Circle> circles = new ArrayList<>();
        ArrayList<Integer> waitTimes = new ArrayList<>();
        circles.add(new Circle(50, 50, 125, Color.RED));
        waitTimes.add(1000);
        circles.add(new Circle(200, 200, 250, Color.BLUE));
        waitTimes.add(2500);
        circles.add(new Circle(900, 500, 375, Color.YELLOW));
        waitTimes.add(5000);
        circles.add(new Circle(400, 50, 500, Color.GREEN));
        waitTimes.add(5000);
        Thread waitingThread = new Thread(() -> {
            for (int idx = 0; idx < 4; idx++) {
                Circle thisCircle = circles.get(idx);
                Platform.runLater(() -> addLvlNode(thisCircle));
                try {
                    Thread.sleep(waitTimes.get(idx));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        mainPain = new Pane();
        primaryStage.setScene(new Scene(mainPain, 1000, 800));
        primaryStage.show();
        waitingThread.start();
    }

    private void addLvlNode(Node circle) {
        mainPain.getChildren().add(circle);
        circle.toBack();
    }

}

我还将等待时间延长了10倍,这样就更容易看到每个圆圈都是依次绘制的,中间有一个停顿。

你可能可以使用Timeline来实现这一点,但因为你说Circle数据最终将是来自外部源的JSON,这对我来说意味着你可能已经有了某种非JavaFX机制,所以可能最好只使用后台线程来做你需要的事情。从这个例子可以看出基本框架是什么。

 类似资料:
  • 我在运行时无法将节点添加回。 我想做的是,当用户点击一个按钮时,当前节点存储在

  • 我正在尝试构建一个在JavaFX中实现群聊的聊天应用程序。我想在边框窗格内创建一个滚动窗格,该窗格将包含用户所属的所有组。当用户加入时,需要将组图标(ImageViews)动态添加(在场景生成器中无法完成)到滚动窗格(在HBox内)。 目前,我正在使用一个SceneController类,该类负责所有阶段和场景更改。 我已经创建了一个FXML文件(使用场景生成器),其中包含一个边框窗格和一个滚动窗

  • 我创建了一个简单的应用程序来模拟JAVAFX的动态节点创建。这个应用程序能够通过单击“新建”按钮在用户需要的时候创建一个新窗口。用户可以通过单击“添加任务”按钮,然后单击对话框窗口上的“添加”按钮,将标题窗格的新节点添加到窗口中。 我想修复一个意外行为。此应用程序仅将新节点(在本例中为TitledPane)添加到最后创建的窗口。并且上一个窗口上的所有节点都将消失。 你可以看下面的视频来更好地理解我

  • 我需要在XML中保留很少的值,并且需要通过XSLT添加新的节点。 价值需要保留,新的选项需要添加。 如何实现这一点。下面是我的代码。 有人能帮忙吗? 谢谢

  • 你能告诉我,我应该在哪里声明节点的事件侦听器,它们是在我的控制器类之外添加的? 最好的方法是用这个例子来解释: 我有我的控制器: 然后我有任务,它在初始化方法中启动: 我在这里做什么?我有一个FXML,根元素是锚烷。它具有id根。现在我开始了一个任务,在这个任务中,我向根节点添加了一个按钮。现在我想向按钮注册一个动作事件。我现在的问题是,我可以/应该在哪里注册听众。通常我在控制器中注册它们,但在这

  • 我正在做一个项目,以创建一个超过2个子节点的树。我明白在创建二叉树时,我们可以只创建一个左节点和一个右节点来充当子节点,但当我在网上寻找创建树的帮助时,我找到的每一个解决方案都谈到了创建二叉树。我明白创建树的部分意味着您需要创建子节点数组或arraylist,但我不明白如何将数据放入数组,或者如何将子节点数组“连接”到父节点? 这是我目前掌握的代码。我知道这不是很多,但我正在努力刚刚开始这个项目。