Preventing a side of a SplitPane from resizing in javafx - java

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());

Related

JFX scale image up and down to parent

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());

Java FX - How to create a Label with no contents to reserve spot in Layout Manager?

Is there a way to create a Label with some type of invisible contents, to preserve it's "space" in a layout such as a HBox or VBox so as to prevent Layout Manager engaging in some type of resizing, so that if I have to set the contents of a certain Label to empty, the Layout Manager will not resize the container?
Thanks!
All layouts will lay out an invisible node as if it is visible. You can use an invisible Label as a “strut” by making it invisible and placing it, along with your visible node, in a StackPane:
Label valueLabel = new Label("This may become empty");
Label strut = new Label(valueLabel.getText());
strut.setVisible(false);
StackPane labelPane = new StackPane(strut, valueLabel);
hBox.getChildren().add(labelPane);
Another option is to simply make your value Label invisible instead of making its text empty, but I realize there are circumstances where that may not be possible, such as if the Label’s text property is bound.
As with all Regions you can set the minWidth property:
label.setMinWidth(100);
Which will result in the label not being resized below size 100 regardless of it's text.

Change growth ratios for panes inside SplitPane

Have an horizontal split pane. If the pane grows, then the two interior panes will grow equally (if the split pane grows 100 pixels then each interior pane grows 50 pixels).
Is it possible to adjust this so that the second interior pane grows more than the first one? Like the first one gets 25% of the growth and the second gets 75%.
The SplitPane has no direct API for this, but indirectly we may achieve this..
The API doc gives us a hint:
The dividers in a SplitPane have the following behavior: [...]
Dividers moving to the left/top will stop when the node's min size is reached.
Dividers moving to the right/bottom will stop when the node's max size is reached.
[...]
So, by setting a minimum size, we can force the SplitPane to distribute the available space as we need it.
This is a little example with two TableViews aligned left and right in a SplitPane. Now I bound the minimum size of the left TableView to 20% of the Stages current width and the right ones to 70%.
TableView<?> table1 = createTable();
TableView<?> table2 = createTable();
table1.minWidthProperty().bind(primaryStage.widthProperty().multiply(0.2));
table2.minWidthProperty().bind(primaryStage.widthProperty().multiply(0.7));
SplitPane split = new SplitPane(table1,table2);
You can easily modify the minimum size, to constant values or bind them to different parent container sizes.

Node setMouseTransparent Exceptions

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.

How to shift the position of tabbed panes

I know that when I create an instance of tabbed panes I set the position as such:
jtp = new JTabbedPane(SwingConstants.LEFT)
My question is that is it possible to set the position to the left as above, but to shift the starting position a little bit downwards? I do not want the first tab appearing at the very top of the left hand side. I want to leave some empty space. Is that possible? Thanks.
You can pack your component into javax.swing.Box add shift it:
jtp.add("Component shifted vertically", shiftVertical(your_component, 5)); // 5 px or more
public static Box shiftVertical(JComponent component, int size){
Box vBox = Box.createVerticalBox();
vBox.add(Box.createVerticalStrut(size));
vBox.add(component);
return vBox;
}
I managed to find a work around for this problem. I did this by creating a "dummy" icon which was basically a square with the same colour as the background colour of the tabbed panes. I then set this icon as the icon for a "dummy" tabbed pane and disabled the tab:
jtp.addTab("", dummyIcon, null);
jtp.setEnabledAt(0, false);
By resizing the icon I could make the first tabbed pane take up as much space as i wanted since the panes don't have to be the same size. This way The first tab was not clickable and it had a colour similar to the background colour of the panel, so it appeared as if the space was empty.

Categories

Resources