如何为动态添加的 JavaFX 组件设置顺序?

How to set order for dynamically added JavaFX components?

我有一个按钮,每次单击它时都会生成另一个按钮。问题之一是生成的按钮放置在错误的位置。按钮应该从 window 的左上角开始,但按钮的位置在 window 的左下角。我无法使用 function setAlignment(Pos.TOP_LEFT) 更改位置,因为生成的按钮是 AnchorPane 对象的子项。

我也不能使用 Scenebuilder 之类的东西,因为生成的按钮仅在单击按钮后才存在。

如果我将按钮设置为 VBox 对象的子对象,并将函数 `vbox.getChildren().add(0, new Button( " New Entry "+button1ClickCount )) 中的参数更改为a 1 而不是 0,按钮按升序创建,从 window 的顶部开始,但生成按钮下方的所有子项都被推到屏幕下方 + 第一个生成的按钮不会停留在屏幕上方较新生成的按钮。

如何在 Java 中为运行前不存在的按钮或其他组件设置位置?并让它们按升序排列,而不是降序排列,而不将 FXML 组件推出到新生成的组件下方?

图像中 window 底部的按钮应该出现在蓝色文件夹的右下方和左侧。

我的Main.Javaclass

import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.*;

import javafx.stage.Screen;
import javafx.stage.Stage;

import java.net.URL;
import java.lang.*;

public class Main extends Application {

    @FXML
    public static VBox vbox = new VBox();
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        ButtonFXMLController controller = new ButtonFXMLController();

        FXMLLoader loader = new FXMLLoader();
        loader.setController(controller);

       String ProjectPath = System.getProperty("user.dir")+"/MyFXML.fxml";
       //Sets the value of a String to be the working directory path + the path of the file "MyFXML.fxml"

        loader.setLocation(new URL(   "file:///"+ProjectPath));
        vbox = loader.<VBox>load();
        Scene scene = new Scene(vbox);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

按钮 FXML 控制器 Class

import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;

public class ButtonFXMLController {

    @FXML
    private int   button1ClickCount = 0;
// the ID of each generated buttons, starts with 0

    @FXML
    public void buttonClicked(Event e){

        System.out.println(8);
     
        AnchorPane anchorpane = new AnchorPane();
      Main.vbox.getChildren().add(anchorpane);

 anchorpane.getChildren().add(0, new Button( " New Entry "+button1ClickCount ));


        button1ClickCount++;

        String text = "Button1 clicked " +button1ClickCount + " times";

        System.out.println(text);

    }
}

我的 FXML 文件

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.shape.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.image.*?>

<VBox prefHeight="871.0" prefWidth="1425.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
        <children>
          <AnchorPane maxHeight="-1.0" maxWidth="-1.0" VBox.vgrow="ALWAYS">
            <children>
                  <TextField layoutX="307.0" layoutY="59.0" opacity="0.59" prefHeight="31.0" prefWidth="1154.0" text="  Search..." />
                  <Button fx:id="TitelButton" layoutX="311.0" layoutY="174.0" mnemonicParsing="false" onAction="#buttonClicked" prefHeight="31.0" prefWidth="119.0" text="Titel" />
                  <TextField layoutX="311.0" layoutY="208.0" prefHeight="31.0" prefWidth="119.0" />

                  <Button fx:id="Entity" contentDisplay="GRAPHIC_ONLY" layoutX="68.0" layoutY="174.0" mnemonicParsing="false" prefHeight="31.0" prefWidth="119.0" style="-fx-background-color: transparent;" text="General">
                      <graphic>
                          <ImageView fitHeight="49.0" fitWidth="48.0" pickOnBounds="true" preserveRatio="true">
                              <image>
                                  <Image url="@folder.png" />
                              </image>
                          </ImageView>
                      </graphic>
              </Button>
            <AnchorPane fx:id="anchorpane" layoutX="73.0" layoutY="232.0" prefHeight="200.0" prefWidth="200.0">
            </AnchorPane>
            </children>
          </AnchorPane>
        </children>
      </VBox>

您可以在 ButtonFXMLController 中使用 setLayoutXsetLayoutY 并增加 y 以确保不会在同一位置创建按钮:

public class ButtonFXMLController {

@FXML
private int   button1ClickCount = 0;
private int   y = 250;
// the ID of each generated buttons, starts with 0

@FXML
public void buttonClicked(Event e){

    System.out.println(8);
  Button b = new Button(" New Entry "+button1ClickCount);
    // set the place here :
    b.setLayoutX(250);
    b.setLayoutY(y+=20);
    AnchorPane anchorpane = new AnchorPane();
  Main.vbox.getChildren().add(anchorpane);

  anchorpane.getChildren().add(0, b);

    Main.vbox.setAlignment(Pos.TOP_CENTER);

    button1ClickCount++;

    String text = "Button1 clicked " +button1ClickCount + " times";

    System.out.println(text);

}
}