Javafx:如何定位嵌套视图中的对象?

Javafx: How do you target objects in nested views?

我知道每次加载嵌套的 fxml 和控制器时,我都可以使用该控制器来操作嵌套的 fxml。例如,我可以将每隔一行设为紫色,但我不明白的是,在加载所有内容后,我如何才能针对特定的对象进行操作。

这是我能做的最简单的最小可复制示例,从这里减少的任何内容都不符合嵌套 fxml 和子项的标准。我在这里要做的是获取第一个分数,文本为“Score0”,并在按下 10 按钮时将其更改为“10”。我有一种感觉,我很接近,分数框应该是分数[0]。应该也嵌套在row[0],但是我好像无法获取scoreEntry方法来找到框来改变它。

Main.java:

public class Main extends Application {
@Override
public void start(Stage stage) throws IOException {
    FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("view1.fxml"));
    Scene scene = new Scene(fxmlLoader.load(), 400, 300);
    stage.setScene(scene);
    stage.show();
}

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

view1.fxml:

<AnchorPane prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.nested.Ctrl1">
<children>
  <VBox fx:id="rowHolder" prefHeight="260.0" prefWidth="400.0" />
  <Button mnemonicParsing="false" onAction="#scoreEntry" prefHeight="40.0" prefWidth="40.0" text="10" AnchorPane.leftAnchor="70.0" AnchorPane.topAnchor="260.0" />
  <Button mnemonicParsing="false" onAction="#scoreEntry" prefHeight="40.0" prefWidth="40.0" text="0" AnchorPane.topAnchor="260.0" />
</children>
</AnchorPane>

Ctrl1.java:

public class Ctrl1 {
@FXML
private VBox rowHolder;

@FXML
void initialize() {
    addRows();
}

public void addRows() {
    int rounds = 2;
    HBox row[];
    row = new HBox[rounds];
    String ctrlArray[];
    ctrlArray = new String[rounds];

    for (int i = 0; i < row.length; i++) {
        row[i] = new HBox();
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/nested/view2.fxml"));
            row[i] = loader.load();
            rowHolder.getChildren().add(row[i]);
            Ctrl2 ctrl2 = loader.getController();
            ctrlArray[i] = String.valueOf(ctrl2);

            ctrl2.setRoundNum(String.valueOf(i));
            System.out.println(row[i]);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    for (int i = 0; i < ctrlArray.length; i++) {
        System.out.println("Controller: " + ctrlArray[i]);
    }
}

private BigDecimal scoreInput;

private boolean numberInput;

@FXML
public void scoreEntry(ActionEvent event) {
    Button button = (Button) event.getSource();
    String buttonText = button.getText();

    if (buttonText.matches("[0-10\.]")) {
        if (!numberInput) {
            numberInput = true;

            //TODO: find Label for input text

            //I think it should be something like "row[0].getChildren().score[0].clear();"
        }

        //And then I would append it with something like "score[0].appendText(buttonText);"
        return;
    }
}

}

view2.fxml

<HBox prefHeight="30.0" prefWidth="400.0" style="-fx-background-color: #77e77e;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.nested.Ctrl2">
<children>
  <Label fx:id="rowNum" text="Row Number" />
  <HBox fx:id="scoresHolder" prefHeight="100.0" prefWidth="200.0" />
  <Label fx:id="subTotal" text="Sub Total" />
  <Label fx:id="total" text="Total" />
</children>
</HBox>

Ctrl2.java

public class Ctrl2 {

@FXML
private Label rowNum;

@FXML
private Label subTotal;

@FXML
private HBox scoresHolder;

@FXML
private Label total;

public void setRoundNum(String strRnd) {
    rowNum.setText(strRnd);
}

public void setSubTotal(String strRnd) {
    subTotal.setText(strRnd);
}

public void setTotal(String strRnd) {
    total.setText(strRnd);
}

@FXML
void initialize() {
    int plays = 1;
    Label score[];
    score = new Label[plays];
    for (int i = 0; i < score.length; i++) {
        score[i] = new Label("Score" + i);
        scoresHolder.getChildren().add(score[i]);
        System.out.println(score[i]);
    }
}

}

我采纳了@James_D的建议,将我的控制器和单元封装在数组中。

 //This is the array for the controllers. It's outside the method to be accessed by other methods.
public static Ctrl2[] ctrlArray = new Ctrl2[2];

public void addRows() {
    int rounds = 2;
    HBox row = null;
    for (int i = 0; i < rounds; i++) {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/nested/view2.fxml"));
            row = loader.load();
            rowHolder.getChildren().add(row);
            ctrlArray[i] = loader.getController();

            ctrlArray[i].setRoundNum(String.valueOf(i));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    for (int i = 0; i < ctrlArray.length; i++) {
        System.out.println("Controller: " + ctrlArray[i]);
    }
}

我遇到的问题是范围。如果我在方法之外创建数组持有者,我可以从其他方法访问它。

private Label[] score;

public void addScores() {
    int plays = 2;
    //Moved array holder from here to outside
    score = new Label[plays];
    for (int i = 0; i < score.length; i++) {
        score[i] = new Label("Score" + i);
        scoresHolder.getChildren().add(score[i]);
        System.out.println(score[i]);
    }
}