5

So, what I want to do is, creating a custom element by using fxml and then add a couple of instances of that element into a container, like GridPane. The "new" operators does not work for me, because I would like to use the @fxml annotator to get access to the element. Cloning would be nice, but it does not work. The FXMLLoader is very slow, when using in a for() contruct to add many elements. It would be perfect, if I could write a reference into fxml parentnode, which could be called from the controller.

Sorry... here in pseudo...

public class Controller implements Initializable {

    @FXML
    private VBox stack;

    @FXML
    private Button button;

    @FXML
    private void Change(KeyEvent event) throws IOException {     
        for (int i=0; i<10; i++){
            stack.getChildren().add(button);   
        }
    }

}

It is no problem to add THE button to the VBox. But in a for-contruct (to add MORE THAN ONE Button) it fails. I could use the new operator in the for construct, but I want to know, if this is the only possiblity. I thought there must be another way e.g. to use the @FXML annotator to "get" the button and then duplicate it.

Flak DiNenno
  • 2,193
  • 4
  • 30
  • 57
user1562969
  • 155
  • 1
  • 2
  • 7

2 Answers2

7

I believe it fails because you are trying to add the same button over and over. In the for loop you need to create an instance of a button every time the code in the loop gets ran.

Something like:

@FXML
private void Change(KeyEvent event) throws IOException {     
    for (int i=0; i<10; i++){
        stack.getChildren().add(new Button("test")) ;   
    }   
}

Let me know if i have misunderstood you.

geert3
  • 7,086
  • 1
  • 33
  • 49
Yarrgh
  • 355
  • 1
  • 5
  • thank you, but this is not exactly what I am looking for. The "new" operator adds a new button from JavaFX class "button". But I want to add the FXML annotated button (from the fxml source) in the for construct. So Iam looking for a way to build instances from the fxml source – user1562969 Jul 30 '12 at 19:37
  • Man, when you use the @FXML Button button line you are already adding the button from FXML. Your code actually works the way you are expecting, but since you are using a StackPane it keeps putting the button over and over again (ten times) above the very same button. I believe what you are trying to do is create a custom component using fxml, if that's the case, open another thread just for this one – Bruno Vieira Jul 30 '12 at 21:39
  • The thing is, that FXML button was already added. All you are doing is adding the same button over and over. It will never create a new button. The FXML button variable declaration refers to that one button in your FXML file. The only way to add a new button is to actually create a new button object and then add it to your vbox – Yarrgh Jul 30 '12 at 23:03
1

If you want to access the button, just create the class variable for it.

private Button okButton = null;
private Button cancelButton = null;

In the initialize() method, init the Button and add to the container.

okButton = new Button("OK");
cancelButton = new Button("Cancel");
stack.getChildren().addAll(okButton, cancelButton) ;

Then you can handle button action event:

cancelButton.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent arg0) {
            try {                    
               //close screen
               ((Button)arg0.getSource()).getScene().getWindow().hide();
            } catch (Exception e) {

            }
        }
    });
Gravity Grave
  • 2,802
  • 1
  • 27
  • 39
Thinhbk
  • 2,194
  • 1
  • 23
  • 34