(Javafx) Why does adding content to HBox by clicking a button display, but not to VBox?

372 Views Asked by At

I'm completely new to JavaFX and just trying to get a feel going for the basics. I created a simple content layout, made of 2 tabs in a tab pane. The second tab is empty, I'm currently focusing on the first tab. It has a VBox made of a Text object above an HBox. The HBox consists of 3 simple buttons.

Experimenting with setOnAction on the buttons, nothing I add to the VBox actually displays when clicking the button. But any content added to the HBox does display.

I searched extensively and can't find anybody else experiencing the same issue.

Here's what it looks like:

(tabpane created)

Tab t1 = new Tab("test1");
Tab t2 = new Tab("test2");  // Empty for now

Text test = new Text("test");

HBox buttons = new HBox();
Button button1 = new Button("button1");
Button button2 = new Button("button2");
buttons.getChildren().addAll(button1, button2);

VBox outer = new VBox();
outer.getChildren().addAll(test, buttons);

t1.setContent(outer);

button2.setOnAction(new EventHandler<ActionEvent>(){
   @Override
   public void handle(ActionEvent e){
      buttons.getChildren().add(new Button("This button does appear next to the other 2"));
      outer.getChildren().add(new Button("This button does not appear at all"));
   }
);

The button added to the HBox appears, but not the one to the VBox. Nothing I add to the VBox appears.

I tried several different things:

  • Using outer.clear(), then re-adding the 2 buttons and also the new, third button. No difference.

  • After adding to the VBox, making a call again to t1.setContent(outer). No difference.

  • Manually creating a button, textfield, etc. and then adding it to the vbox, all in the setOnAction block also does not make it display.

  • Inversing the layout by making the HBox the outer container that contains a VBox inside of it, to see if it's related to setContent(). However, it is not the cause. Even with this inverse layout, adding to the HBox works and the new content displays, while the newly added content to the VBox does not display.

  • If I add content to the VBox in separate statements outside any setOnAction block, that works.

  • vbox.getChildren().clear() works inside the setOnAction block (just like outside the block). So it's really specifically the adding of content to the vbox that is not displaying for some reason.

What am I missing? Should this be done in a different way?

1

There are 1 best solutions below

0
On BEST ANSWER

Your code works for me. The below code is the code in your question with additions in order to make it a SSCCE.

I initially make the Scene large so that when I click on button2, there is room on the Scene that allows you to see the added Nodes.

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class TabPane2 extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Tab t1 = new Tab("test1");
        Tab t2 = new Tab("test2");  // Empty for now
        Text test = new Text("test");
        HBox buttons = new HBox();
        Button button1 = new Button("button1");
        Button button2 = new Button("button2");
        buttons.getChildren().addAll(button1, button2);
        VBox outer = new VBox();
        outer.getChildren().addAll(test, buttons);
        t1.setContent(outer);
        button2.setOnAction(new EventHandler<ActionEvent>(){
           @Override
           public void handle(ActionEvent e){
              buttons.getChildren().add(new Button("This button does appear next to the other 2"));
              outer.getChildren().add(new Button("This button does not appear at all"));
           }
        });
        TabPane tabPane = new TabPane(t1, t2);
        Scene scene = new Scene(tabPane, 450, 300);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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