I am trying to create a line on top of a circle.
Things that i have tried :
I added the circle to the StackPane, and then the StackPane and line to a group which i sent to the scene constructor got some undesired results like stackpane not spreading fully over the stage
adding the line after the circle puts it automatically above that but i need more control over it.
e.g., i have 10 shapes and i want to declare them all and then decide what goes over what and i don't want to worry about adding them in order
How JavaFX paints
JavaFX uses a Painter's algorithm, painting the children of a Parent node in order from first to last, so that the last nodes will be painted over the first nodes.
This is done in a retained mode on every pulse rather than an immediate mode. So items are not painted until you relinquish control of logic to the JavaFX graphics system. That means that you can add the items to the scene graph and then reorder or move them around in the scene graph as you wish, before they are painted.
3D painting in JavaFX can also use Z-buffering, but this answer relates just to 2D painting of elements with the same z co-ordinate value, without Z-buffering.
How to set the paint order for nodes
By adding nodes to the children list of a parent, you can place your nodes in a Group parent or a Pane parent. The nodes will be painted in the order in which you added them to the children list.
A Pane is good if you wish to use CSS, otherwise a Group will usually do. Also a Pane has a resizable range, which a group does not. For these reasons, I usually prefer to use a Pane over a Group.
To change the order in which the children are painted, you can move nodes around in position within the children list.
For example, the following code will change the paint order of the first and fifth items in the parent pane children list:
Collections.swap(parentPane.getChildren(), 0, 4)
In addition, Node has toFront and toBack convenience methods to move a node to the back or front of the node's parent's child list.
Advice on layout pane usage
Don't use layout panes such as StackPane for holding nodes that you wish to explicitly position. Managed layout panes such as StackPane are designed to handle the layout of nodes automatically for you, according to an internal algorithm for the layout pane. For example, by default, every node you add to a StackPane will be centered in the middle of the StackPane.
Related
How to change order of children in JavaFX
Related
I need to extract all elements visible inside a scrolling panel. I have a long list of elements inside, and their positions respectively to the scrolling panel. I wish to retrieve all elements visible in O(1). I wondered what data structure I should use to store the list of elements, all I know is their relative positions inside the scrolling panel {top, bottom, left, right}.
code is in java (GWT for wep app)
See drawing
I have dynamically created a bunch of buttons. I gave a fixed width to each of them. I want it to be added until space is available to its parents and when it overlaps with some other nodes, it will automatically go to the next line in order to avoid collision. I want it to be responsive at different screen sizes.
for(Data i:datas){
Button btn=new Button(i.getName());
anchorPane.getChildren().addAll(btn);
}
I want to arrange the buttons in a new line only when the buttons in the first line have covered its total width. How can I accomplish it? Any help is appreciated.
James_D provided a great resource—there's a built in layout for anything you need and FlowPane has what you want here.
Using your example, just swap out your AnchorPane for FlowPane:
FlowPane flowPane = new FlowPane();
for(Data i:datas){
Button btn=new Button(i.getName());
flowPane.getChildren().addAll(btn);
}
To make it responsive (i.e. expand and contract with the parent container/stage), bind the FlowPane's width and height to those of its parent:
flowPane.prefWidthProperty().bind(stage.widthProperty());
flowPane.prefHeightProperty().bind(stage.heightProperty());
I know that elements in Flow Pane layout in JavaFX are positioned next each other in one orientation.
I want in the middle of this process to force JavaFX to put elements in a new line , to some extend like "\n" character in print method .
How i can do this ?
A blank full width node behaves like "\n" in FlowPane.
Region p = new Region();
p.setPrefSize(Double.MAX_VALUE, 0.0);
flowPane.getChildren().add(p);
I think this is effective in case you want to control line breaking as a node.
That isn't how FlowPane works. You may be better off using a GridPane so you can specify the number of rows/columns. Or you can use a composite layout and use a FlowPane for each row, then put all your FlowPanes in a VBox.
I'm trying to make an window, where I have StackPane as root and I want to add MenuBar to this window. However MenuBar is in the center of the screen and I want to keep it in the top part of the window as in normal Windows applications.
root = new StackPane();
root.getChildren().add(new MenuBar());
this will show window like this
http://i61.tinypic.com/2pzblmo.jpg
Thanks you for your advice!
I would say StackPane is not suitable for making a GUI including a menubar.
StackPane will just put the controls you add to it one on top of the other.
In java docs you can find:
"StackPane
The StackPane layout pane places all of the nodes within a single stack with each new node added on top of the previous node. This layout model provides an easy way to overlay text on a shape or image or to overlap common shapes to create a complex shape. Figure 1-6 shows a help icon that is created by stacking a question mark on top of a rectangle with a gradient background.
"
If I have a VBox with 3 buttons and make the VBox mouse transparent, how can I ensure that its children won't be made transparent? I need the buttons to be clickable.
I'm trying to make a clock, and my solution so far is to have a StackPane. Add 12 VBoxes in the StackPane, make it as large as the StackPane, and rotate it around the center axis 30 degrees * n. Unfortunately, the VBoxes block the layers beneath it all the way up to the top of the StackPane.
The answer was to set each VBox's pickOnBounds property to false. Since a VBox is really a blank container with no geometric shape, disabling the pick on bounds renders the VBox invisible while leaving its children intact.