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.
Related
Link to screenshots: https://imgur.com/a/uSpTG8I
First image is when the window is expanded, second one is when the program runs. The others is of the FXML file and the scenebuilder program.
I have looked this up and tried the various layout options in the scenebuilder program itself but none of them works as I wanted. I want the image to stay centered, and if possible, the arrow buttons to also be centered.
Thanks
I'm a fan of BorderPanes. If you wrap your arrows to the Center of the BorderPane they will stay centerd, even if you resize your Scene.
So if You want the arrows and the big Image Centered use a BorderPane and wrap the Image to the Center. Now you can wrap another BorderPane in parent BorderPane's Bottom and wrap your Arrows to center.
I am attempting to have an ImageView that scales with its parent. I have searched through every StackOverflow post I can find on this, and here is what I've tried:
taggedImage.setPreserveRatio(true);
//taggedImage.fitWidthProperty().bind(
// Bindings.min(imagePane.widthProperty(), imagePane.widthProperty()));
//taggedImage.fitHeightProperty().bind(
// Bindings.min(imagePane.heightProperty(), imagePane.heightProperty()));
taggedImage.fitWidthProperty().bind(imagePane.widthProperty());
taggedImage.fitHeightProperty().bind(imagePane.heightProperty());
The commented lines I tried as well and the issue with these approaches is that when the imageview binds to the parent, the parent can only scale up and not down. Therefore, if you increase the size of the window, the picture will get bigger. If you decrease the size of the picture again, it doesn't decrease the picture size. In this example, imagePane is a StackPane. I have also tried a borderFrame. As well, I've tried using a Pane as the parent. This way, the image successfully scales up and down. However, the image isnt centered and is always in the top left corner of the pane if it doesnt match the size of the pane exactly.
Scene Tree:
https://gyazo.com/45e0daebbfd98dfd3446185d21eb91ee
Values:
Top gridpane:
https://gyazo.com/f48ebb39f48d876a02d44792a73eaad4
lower level gridpane:
https://gyazo.com/3399d9f3ab00e8babd36ee3b0e3b27ba
BorderPane:
https://gyazo.com/51c24f8de50ae3865a299fdddf3a1490
ImageView:
https://gyazo.com/7dfc1071d2b516a83baed301596be2b9
Note, here I'm trying it with a borderpane instead of what I was using before. However, the result is the same no matter which object is the parent of the imageview.
Solved. I've been messing around and found a fix. This isn't exactly intuitive but it worked for me: I left the image inside the borderframe and, in the java code, I created a pane in the same part of the gridpane as the image. I then bound the imageview's width and height to the pane. Then, the centering of the image was correct as well as the scaling.
Here is what i did:
imageView.setPreserveRatio(true);
Pane pane = new Pane();
testGridPane.add(pane, 1, 1);
imageView.fitWidthProperty().bind(pane.widthProperty());
imageView.fitHeightProperty().bind(pane.heightProperty());
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
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.
"
I have a layout where I have a vertical split pane that divides two components. The component inside the right side of the splitpane I want to grow (it's an image), but the components on the left side of the split pane I want to remain in the exact same place with the divider in the exact same position when the window is enlarged.
I have attempted to wrap the left side AnchorPane in a Vbox and it seemed to work except when the window is resized all of the components in the left side get moved down. This also occurs when I wrap it in an HBox.
I can't think of the best way to fix this. I'm using scene builder and I'm still fairly new to Javafx. Can anyone help?
Thank you!
Calling setMinWidth and setMaxWidth on the component that must not grow with the same fixed value will prevent the user to change the divider position.
So for example let's say that you want a max size of 100 for your left component, the code could be:
SplitPane pane = new SplitPane();
double leftComponentSize = 100.0;
VBox leftComponent = new VBox();
// Set the min and max width to a fixed size
leftComponent.setMinWidth(leftComponentSize);
leftComponent.setMaxWidth(leftComponentSize);
...
pane.getItems().addAll(leftComponent, rightComponent);
// Initialize the divider positions to allocate the expected size
// to the left component according to the size of the window
pane.setDividerPositions(leftComponentSize / stage.getScene().getWidth());