I'm creating an app in which I use nested FXML nodes. They are connected to parent nodes in the parent controllers using constructs like
#FXML
private AnchorPane nestedNodeConnector;
, to which I attach the child like this:
AnchorPane child = createNestedAnchorPaneWithTableViewInside();
nestedNodeConnector.getChildren().setAll((AnchorPane)child);
The code is a bit simplified, but I hopefully explained myself enough. Now my problem is that I am trying to load (as the child node) an as-large-as-possible AnchorPane with an anchored TableView inside. However I can't get this to work as the TableView dimension never sticks to the parent node (in order to grow with the window size).
I was able to get it working without nesting the child, but I really have to load the TableView in a separate FXML file. Any suggestions? I think that my approach creates an AnchorPane "child" within an AnchorPane "nestedNodeConnector", which messes up the anchor properties.
All I had to do was anchor the child AnchorPane (to the parent AnchorPane):
AnchorPane child = createNestedAnchorPaneWithTableViewInside();
AnchorPane.setTopAnchor(child, 10.0);
AnchorPane.setBottomAnchor(child, 10.0);
AnchorPane.setLeftAnchor(child, 10.0);
AnchorPane.setRightAnchor(child, 10.0);
nestedNodeConnector.getChildren().setAll((AnchorPane)child);
Related
I have a program where i have a rootLayout made from a BorderPane. When i press a button in this rootLayout i place a new fxml view into the center of the the borderPane using .setCenter(). The view i am placing into the borderPane consists of an AnchorPane that has a scrollPane as it's child element and when i run this view by itself the scrolling works. However after placing the view into the borderPane it stops working. The area in the scrollPane doesnt move at all when i scroll down or up. I am guessing this has to do with the size that is given in the borderPane but the whole point of having the scrollPane is so that i can show all of the information in 1/3 of the space.
Any tips or Ideas on how to make this work in either javafx, fxml or scenebuilder?
Can't make comments yet ... correct me if I'm wrong but don't you have to use the AnchorPane as the child of the ScrollPane? I always have my TextAres as child of the ScrollPanes!
I have an Hbox which contains Vboxes and each Vbox itself contains other Elements which can be added or removed and some control Buttons. Now I want to add or remove those flexible Elements in my Model and I need to know in which Vbox this is happening.
My attempt was to get the Children of the Hbox and check where the Vbox, where something happend/changed, is located in this List. And work with this Index afterwards.
public int getId (Action event){
Button button= event.getSource();
Vbox vbox= button.getParent();
Hbox hbox= vbox.getParent();
hbox.getChildrenUnmodifiable();
....//TODO
}
The Problem is that if I Print hbox.getChildrenUnmodifiable(); it shows me that:
[VBox#1402dd44, Separator#4eaff333[styleClass=separator], Grid hgap=0.0, vgap=0.0, alignment=TOP_LEFT]
and after I add an other Vbox it just adds the
Grid hgap=0.0, vgap=0.0, alignment=TOP_LEFT]
part again and again and doesen't show me any more information of the Vboxes which have been added.
I load the Vboxes from an other .fxml file with hbox.getChildren().add(FXMLLoader.load(getClass().getResource("/VBoxElement.fxml")));
Now I wonder if that looks like an proper way to get the Indexnumber of my Vbox where I am working on? And if anyone has any advice how to get a working Index of my Hbox?
This is my first JavaFX project and if I miss understood something feel free to correct me.
As James_D sayd:
ObservableList is just a subinterface of java.util.List, so you can
just call all the usual methods: indexOf(...), add(..), remove(...),
etc – James_D May 14 at 15:41
Thx, worked fine. As I expected it as first but I messed up my fxml structure and my added fxml did not contain a VBox as root element it contained a Grid. The toString() from the Grid produces the Grid hgap=0.0, vgap=0.0, alignment=TOP_LEFT in the output
I can add elements to an AnchorPane that is inside a ScrollPane. However they come in temporarily hidden. The second I click on the AnchorPane, the elements show up. I tried to do thing like element.toFront(), but with no success. Any ideas how to get elements to show up right away?
Sample code would like:
AnchorPane host= new AnchorPae();
ScrollPane sp = new ScrollPane(host);
AnchorPane node = new AnchorPane();
host.getChildren().add(node);
I tried things like requestFocus() on each of these nodes, but without success. I also tried to mimic a mouse click event but it did not work. everything shows once I physically click on the AnchorPane.
I have a JavaFX 2.2 TilePane with several items (children). I've added css so that on mouse hover, the scale of the item is set to 1.2. By default, the order of children defines what node is drawn first and what last. Is there a way to make hovering item be above all others, without resorting to toFront() and making it be the last item (moving it to the end). This question is similar to https://stackoverflow.com/questions/13893514/scaling-children-in-a-flowpane-makes-the-children-clip-eachother (still unanswered).
Screenshot of the issue is located at: http://vladeck.files.wordpress.com/2013/03/javafx_tilepane.png?w=640
Solution / Workaround
Use a GridPane instead of a TilePane.
When the user clicks on an item in the grid, call toFront on the item.
Sample Code
I added the following code to a calculator which is based on a grid layout which looks similar to the tiled layout in your sample screenshot. With the modified application, I experienced no overlapping of buttons of the calculator. Surprising to me, though they looked a little weird, the scaled buttons made the calculator easier to use...
button.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
button.toFront();
button.setScaleX(1.6); button.setScaleY(1.6);
}
});
button.setOnMouseExited(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
button.setScaleX(1); button.setScaleY(1);
}
});
Background
As you note, the overlapping issue is unresolvable in some stock Panes like TilePane. This is because the z-order as well as the relative layout position of a node are both defined by the relative position of the node in the TilePane's child list. In such Panes, you cannot change the z-order and bring it to the front without also moving the node to the last layout position in the TilePane.
A GridPane does not suffer from the same issues as a TilePane because it's child node list order only defines the z-order of it's child nodes, not the layout positioning of those child nodes.
Is there a way (a hack?) to implement my own code of retrieving the children order for drawing when JavaFX repaints TilePanel?
Yes, you could hack the TilePane code if you have the skills.
I have an HBox displaying a series of canvases. I am removing a child of a canvas and adding it to the rawChildren of the containing HBox, so I can position it, and make it appear to shift outside the bounds of the canvas.
Here is the code from the canvas:
private function onMouseOver(e:MouseEvent):void
{
(this.parent as HBox).rawChildren.addChild(dateLabel);
dateLabel.x = (this.parent as HBox).localToGlobal(new Point(this.x,0)).x - 18;
}
private function onMouseOut(e:MouseEvent):void
{
addChild(dateLabel);
dateLabel.x = 0;
}
It works, but if the containing HBox.horizontalAlign is set to "right", when I add the child back to the Canvas, the HBox stops displaying correctly and puts all the child canvases overlapping on the right. There is no issue if the HBox is aligned "left" tho.
Is this a bug? Is there a work around?
Thanks!!
Is this a bug? Is there a work around?
- John Isaacks
This isn't a bug as such, it's more that you are using a container in an unusual way.
When you use an HBox you are making a decision that all children are laid out in a linear, horizontal arrangement according to the rules of the HBox component.
Explicitly positioning a child is not what HBoxes are about - it's not in their job description.
I would recommend that you have an HBox inside a Canvas. You can add the dateLabel to the HBox when it should be laid out horizontally or move it to the Canvas when you need to set its position and make it look like it's outside the HBox.
When you use rawChildren, you simply bypass the layout mechanism.
You should use addChild or addChildAt directly on the component.