javafx how to add several elements in one window? - javafx

I'm using eclipse with scene builder.
I have build a new fxml document with:
- 2 labels
- one table view
I want to add several of this element into other window (i.e. add several of this element into tilePane).
How can I do it ?
When I'm trying to do this:
Pane pane1 = (Pane)loader.load();
Pane pane2 = (Pane)loader.load();
tilePaneRootLayout.getChildren().add(pane1);
tilePaneRootLayout.getChildren().add(pane2);
I'm getting empty window.
1. why this happen ?
2. how can I solve it ?
Thanks

Create a new loader for each new Pane

Related

javafx load fxml into pane [duplicate]

I'm learning basic JavaFX right now, and I don't understand this statement from the book I'm reading: "No, a node such as a text field can be added to only one pane and once. Adding a node to a pane multiple times or to different panes will cause a runtime error." I can see from the UML diagram the book provides that it is a composition, but I don't understand why (library class code implementation) that is.
For instance, why does this result in a compile error? Isn't a new text field instantiated within the pane since it's a composition?
FlowPane pane = new FlowPane();
StackPane pane2 = new StackPane();
TextField tf = new TextField();
pane.getChildren().add(tf);
pane.getChildren().add(tf);
Also, why does the following run but not show the text field placed in pane?
FlowPane pane = new FlowPane();
StackPane pane2 = new StackPane();
TextField tf = new TextField();
pane.getChildren().add(tf);
pane2.getChildren().add(tf);
primaryStage.setScene(new Scene(pane));
primaryStage.show();
This is basically a (deliberate) consequence of the way the API is designed. Each Node has a collection of properties, including a parent property (the - one and only one - parent of the node in the scene graph), along with properties such as layoutX and layoutY which are the coordinates of the node in relation to its parent. Consequently, a node can only belong to one parent, and can only be added to a parent once (as it can only have one location in the parent). Organizing things this way enables a very efficient layout process.
Another way to think of this: suppose your first code block did what you wanted; so the text field tf appeared twice in the flow pane. What result would you expect to get from tf.getBoundsInParent()? Since tf appears twice in the parent, the API would not be able to give a sensible value for this call.
There are a couple of inaccuracies in statements you make in your question:
For instance, why does this result in a compile error? Isn't a new
text field instantiated within the pane since it's a composition?
First, technically, this is aggregation, not composition; though I'm not sure understanding the difference will aid your understanding of what is happening at this point.
Second, there is no compile error here; you get an error at runtime (the pane detects that the same node has been added twice; the complier has no way to check this).
Third, parents do not instantiate copies of the nodes you add to them. If so, you wouldn't be able to change the properties of nodes that were displayed. For example, if the FlowPane in your example instantiated a new TextField when you called pane.getChildren().add(tf);, and then displayed that new text field, then if you subsequently called tf.setText("new text"), it would have no effect, as it would not be changing the text of the text field that pane was displaying.
When you call pane.getChildren().add(...) you pass a reference to the node you want to be added; it is that node that is then displayed as a child of the pane. Any other implementation would produce pretty counter-intuitive behavior.
In your second code block:
pane.getChildren().add(tf);
pane2.getChildren().add(tf);
the second call implicitly sets the parent property of tf to pane2; consequently tf is no longer a child of pane. So this code has the effect of removing tf from the first parent, pane. As far as I am aware, this side-effect is not documented, so you probably should avoid writing code like this.
Try this:
TextField tf = new TextField();
TextField tf2 = new TextField();
pane.getChildren().add(tf);
pane.getChildren().add(tf2);
The reason you cannot add the same node twice is that only one node with the same specifications and dimensions can be viewable in the gui. It would be like copying an identical blue circle onto an original blue circle. To the user it looks the same, but it takes up more memory.

JavaFX - How to load a specific AnchorPane's contents from an FXML file?

I'm trying to make an application which switches between scenes back and forth however I need to load a specific AnchorPane's contents into another AnchorPane when the scene switches back. For Example:
In my FXML1, I have a hierarchy that looks like this:
AnchorPane0
----SplitPane
--------AnchorPane1
--------AnchorPane2
In FXML2 the hierarchy is just this:
AnchorPane0
So I load FXML1, then I have a button that switches scenes loading FXML2.AnchorPane0 into FXML1.AnchorPane2. I have a back button in FXML2.AnchorPane0 that needs to load the original scene of FXML1.AnchorPane2 into FXML1.AnchorPane2. Right now my back button loads all 4 containers of FXML1 into FXML1.AnchorPane2. So my questions is, how do I load a specific container's contents preferably without making FXML1.AnchorPane2 its own FXML? Do I need to write a get method for the FXML1.AnchorPane2 to access its contents or is there a way to return an AnchorPane with all of its contents in place already?
I found the solution as shown below:
AnchorPane loader = FXMLLoader.load(getClass().getResource("myFXML.fxml"));
SplitPane spane = (SplitPane) loader.getChildren().get(0);
AnchorPane pane = (AnchorPane) spane.getItems().get(1);
foregroundAnchorPane.getChildren().setAll(pane);

JavaFX Tabpane selects 2 Tabs at the same time

I just started using JavaFX.
In my little Project I got two views. The first is filled with a tabpane, while the second one contains a button to add new tabs to the tabpane. That means I need to switch between the first and the second view to add new Tabs.
The tabpane has one standart-tab wich is unable to close.
My Problem: If I add more than one new tab to my tabpane all tabs are painted over each other.
I already triedto prevent it like this:
Init everything:
private ArrayList<Tab> allTabs = new ArrayList<Tab>();
Tab tab = new Tab();
allTabs.add(tab);
TabPane tp = new TabPane();
tp.getTabs().add(tab);
To set the selection I tried a few things:
tp.getSelectionModel().clearSelection();
tp.getSelectionModel().select(allTabs.size());
_________________________________________________________________
tp.getSelectionModel().clearSelection();
tp.getSelectionModel().select(tp.getTabs().size);
_________________________________________________________________
tp.getSelectionModel().selectLast();
_________________________________________________________________
tp.getSelectionModel().selectNext();
_________________________________________________________________
tp.getSelectionModel().clearAndSelect(tp.getTabs().size());;
I want to select the newest tab. This is already working but the old ones aren't deselected. The Problem disappears if I select tabs with a mouseclick.
I'm thankfull for any idea.
Is it possible that your using different FXMLLoaders?
I had an simular problem while i was using the normal FXMLLoader and a coustom FXMLLoader. Just try to use the same in both cases. This is the way how it works for me.
If it doesn't fix your problem some pictures and some more code-fragments would be helpful to solve your problem.
Greetings
I had similar problem, i just removed the line
tabpane.getSelectionModel().clearSelection();
No idea why it works.
Just keep :
tb.getSelectionModel().select(index or tab);
or
tb.getSelectionModel().clearAndSelect(index or tab);
PS : tp.getSelectionModel().clearAndSelect(tp.getTabs().size());
this, will do nothing, tp.getTabs().size() is out of bound, so it will

How to create an inner popup in JavaFX styled with FXML

I have an FXML file that I'm using to allow user input when requested. Right now I just put it in a new stage and do Stage.show(). I would like to not have it appear in a new window and behave more like a ContextMenu.
Looking at ContextMenu class it doesn't appear that I can set the content based off an FXML file. Is there a way to do this either with ContextMenu or Popup or some other class I am unaware of?
Although that library is quite nice, I wanted something simple that didn't require 3rd party downloads. I came up with this:
Popup popup = new Popup();
CustomController controller = new CustomController();
FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlfile));
loader.setController(controller);
popup.getContent().add((Parent)loader.load());
The problem was I didn't realize that a Parent could be considered a Node for the method Popup#getContent#add
ControlsFX has a PopOver control you might like. That PopOver can use any Node for its content, so you can simply create a popover, load a node from FXML and set the content of the popover to that node.

AnchorPane scrollinh in javafx

In my application iam using table view it consists large table column iam unable to scroll anchorpane to view more table column at run time in javafx fxml.
I suppose you want to know how to add scrolling support to your table view.
Replace or wrap the AnchorPane in a ScrollPane.

Resources