-2

So, I want to start manipulating elements in a VBox. I'm adding them procedurally with a for loop that loads in fxml rows.

public void scoreRows() {
    AtomicInteger rows = new AtomicInteger(1);
    for (int i = 0; i <= 10; i++) {
        if (rows.get() <=10) {
            HBox scoreCellRow = null;
            try {
                scoreCellRow = FXMLLoader.load(getClass().getResource("/views/score_cell.fxml"));
                rowHolder.getChildren().add(scoreCellRow);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("No more rows");
        }
    }
}

As I understand it, each time a row is added a new controller is instantiated. So I'm wondering how do I find these elements to target them. For example, what if I wanted to change the background color of every other row by changing the HBox fx:id cellHolder? Or what if I wanted to change the text in the first box of each row to be sequential Label fx:id roundNum?

Score sheet example

horribly_n00bie
  • 79
  • 1
  • 11
  • Are you referring to the `fx:id`? – James_D Apr 06 '22 at 18:26
  • Yes. How does java handle having multiples of the same thing? – horribly_n00bie Apr 06 '22 at 18:29
  • The `fx:id` is just used to initialize a field in the controller. Each time you load the FXML file, you get a different controller; the label will be used to initialize the field `rowLabel` in that specific controller. It's not really clear what you're asking, to be honest. – James_D Apr 06 '22 at 18:30
  • I'm using a for loop to add rows by placing another fxml view in the main one: for (int i = 0; i <= 10; i++) { if (rows.get() <=10) { HBox scoreCellRow = null; try { scoreCellRow = FXMLLoader.load(getClass().getResource("/views/score_cell.fxml")); rowHolder.getChildren().add(scoreCellRow); } catch (IOException e) { e.printStackTrace(); } } – horribly_n00bie Apr 06 '22 at 18:32
  • 2
    Please [edit] your question to include code updates; your [mre] will likely answer the question. – trashgod Apr 06 '22 at 18:34
  • @horribly_n00bie Yes, exactly. You load the FXML 10 times. So you get 10 different controllers, each (presumably) with a `Label rowLabel` reference. (So there are 10 different label references.) Each reference refers to the corresponding label created when you load the FXML. – James_D Apr 06 '22 at 18:36
  • So when I'm viewing it with the 10 rows added it instantiates 10 controllers that are all separate? – horribly_n00bie Apr 06 '22 at 18:40
  • @horribly_n00bie *”So when I’m viewing it with the 10 rows added it instantiates 10 controllers that are all separate.”*. Yes. It’s hard to see what else it would do. – James_D Apr 06 '22 at 18:49
  • I'm just fascinated that now I have all of these controllers. So do they receive different naming conventions? If they don't how would I change the text in the label on the third row? – horribly_n00bie Apr 06 '22 at 18:51
  • Okay. I'll make a small example in a new question. – horribly_n00bie Apr 06 '22 at 19:01
  • 1
    @horribly_n00bie Just edit this question. There is no need for a new one. – James_D Apr 06 '22 at 19:07
  • Why does it make any difference if they're created in a loop? Just communicate with the controllers in the [usual way](https://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml). – James_D Apr 06 '22 at 19:28
  • Wouldn't that act like a batch and change every Label to the same number? – horribly_n00bie Apr 06 '22 at 19:31
  • I can't see why you think it would do that. You call a method on one specific controller. It will change the label, background, whatever you define the method to do, for the component referenced by that specific controller. Why don't you actually try it and see? – James_D Apr 06 '22 at 19:34
  • I keep getting that they Label is null. Do you have an example of how to change the text in roundNum? – horribly_n00bie Apr 06 '22 at 20:09
  • 1
    Just do it the same way as the question I linked. If you can’t make it work, update your question to make a [mre] (a complete example reproducing what does wrong). – James_D Apr 06 '22 at 20:49

1 Answers1

0

It turns out there are only 3 things you really need for this.

  1. A place to put the object

  2. A FXMLLoader and to get the directory

  3. The object and it's controller together

    //This is the place to put the object HBox scoreCellRow = null;

            try {
                //This is the FXMLLoader pointing to the directory
                FXMLLoader loader = new FXMLLoader(getClass().getResource("/views/score_cell.fxml"));
    
                //Now we can use the Loader that I named "loader" to load the fxml and get the controller
                scoreCellRow = loader.load();
                rowHolder.getChildren().add(scoreCellRow);
                ScoreCellCtrl scoreCellCtrl = loader.getController();
    
                //Once it's set up changing things as they are added is easy
                scoreCellCtrl.setRoundNum(String.valueOf(adjustedRnd));
                if (adjustedRnd % 2 == 0) {
                    scoreCellCtrl.getCellHolder().setStyle("-fx-background-color:#ffe89e;");
    
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    

**the adjustedRnd is an int that I used with a for loop to label the rows correctly, adjusting for anything I wanted to insert between the rounds.

horribly_n00bie
  • 79
  • 1
  • 11