Reputation: 1954
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();
}
}
Please let me know if there is anything wrong with what I am doing or is it a known bug?
Upvotes: 3
Views: 2859
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
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