Aspirant
Aspirant

Reputation: 1954

JavaFX: Issue with setting same Node to multiple tabs

I am trying to set a particular node to more than one tabs on a tab pane. The problem is that only the last tab has the node when the application is launched but the rest of the tabs are shown empty.

I am attaching the code and a few screen shots to explain the problem:

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class TabExample extends Application
{

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

@Override
public void start(Stage primaryStage)
{
    primaryStage.setTitle("Tabs");
    Group root = new Group();
    Scene scene = new Scene(root, 400, 250, Color.WHITE);

    TabPane tabPane = new TabPane();

    BorderPane borderPane = new BorderPane();

    Text myText = new Text("Hello");

    for (int i = 0; i < 5; i++)
    {
        Tab tab = new Tab();
        tab.setText("Tab"
            + i);
        HBox hbox = new HBox();
        hbox.getChildren().add(new Label("Tab"
            + i));
        hbox.setAlignment(Pos.CENTER);
        tab.setContent(myText);
        tab.setClosable(false);
        tabPane.getTabs().add(tab);
    }
    tabPane.setSide(Side.BOTTOM);

    // bind to take available space
    borderPane.prefHeightProperty().bind(scene.heightProperty());
    borderPane.prefWidthProperty().bind(scene.widthProperty());

    borderPane.setCenter(tabPane);
    root.getChildren().add(borderPane);
    primaryStage.setScene(scene);
    primaryStage.show();
}
}

enter image description here

Please let me know if there is anything wrong with what I am doing or is it a known bug?

Upvotes: 3

Views: 2859

Answers (2)

sherif mohamed
sherif mohamed

Reputation: 1

It is true that in JavaFx each node must have a single parent at any instant and that is the problem that you are facing. However, there is a possible workaround using the onSelectionChanged() event of the tab to set the node as the child of this tab using setContent(), however make sure to check that the tab has changed to prevent duplicate child error here is a code snippet:

Tab currentTab;
Label label = new Label("Hello");
for(int i = 0;i < tabsNumber; i++){
 Tab tab = new Tab();
 currentTab = tab;
 tab.setOnSelectionChanged(new EventHandler<Event>() {
 @Override
    public void handle(Event event) {
       if (currentTab.equals(tab)) {
          currentTab = tab;
          currentTab.setContent(label);
       }
    }
});
tabPane.getTabs().add(tab);
}

Also if you are using scene builder or some other drag and drop tool you can do the same using a controller class just remember to keep track when the tab really changes.

Upvotes: 0

denhackl
denhackl

Reputation: 1115

In JavaFX, each Node can have exactly one (1) Parent. See the Node Class Page in the JavaFX API. If you add a Node to another Parent, the Node looses its "connection" with the old Parent, which means it will not be displayed or accessable under the old Parent. The method which causes this in your source code is tab.setContent(myText);.

To solve your problem, you have to create five different (=separate) objects and set each one of them to exactly one TabPane as child // content .

Upvotes: 7

Related Questions