Fit FlowPane into ScrollPane - javafx

I using this code to fir FlowPane into ScrollPane
FlowPane flowPane = new FlowPane(Orientation.HORIZONTAL);
ScrollPane scroll = new ScrollPane();
scroll.setContent(flowPane);
scroll.viewportBoundsProperty().addListener(new ChangeListener<Bounds>()
{
#Override
public void changed(ObservableValue<? extends Bounds> ov, Bounds oldBounds, Bounds bounds)
{
flowPane.setPrefWidth(bounds.getWidth());
flowPane.setPrefHeight(bounds.getHeight());
}
});
Unfortunately this maybe is not the best solution. Is there another more simple way to fit FlowPane into ScrollPane in Java 8?

There are methods of ScrollPane meant to do this:
scrollPane.setFitToWidth(true);
scrollPane.setFitToHeight(true);

Try setting maxWidth and maxHeoght properties of your flowPane to Double.MAX_VALUE either via CSS or via API so as to provide its maximal expansion whithin container:
flowPane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);

Related

JavaFX listener to a visible part of VBox

I have a JavaFX VBox inside a BorderPane (central). The content of the VBox is calculated using some business logic and it depends on the height of the visible part of the vbox.
So basically I need a listener watching changes of the visible height of the vbox = height of the central part of the border pane.
The following code demonstrates what I have tried:
public class HelloFX extends Application {
#Override
public void start(Stage primaryStage) {
VBox vbox = new VBox();
vbox.boundsInParentProperty()
.addListener((obs, oldValue, newValue) ->
System.out.println(newValue.getHeight()));
Button button = new Button("ADD LINE");
button.setPrefHeight(25);
button.setOnAction(event ->
vbox.getChildren().add(new Label("line")));
BorderPane borderPane = new BorderPane();
borderPane.setCenter(vbox);
borderPane.setTop(button);
Scene scene = new Scene(borderPane, 100, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch();
}
BorderPane with simple button on the top position and VBox on the central. The button click adds one line to vBox. Total scene height is 100, 25 is the button height and the rest (75) is the vBox.
I'm looking for some listener to report changes of the height of the central part of border pane. So in my example it should always print "75" no matter how many lines I have added to the vBox. The only event changing the value should be resizing the whole window. In reality once the vBox is filled my listener reports increasing height values. Apparently the height property includes the invisible part of the vbox.
EDIT
Finally I've found some solution - placing the vBox in the ScrollPane with disabled scrollbars. Then I can simply listen on the height property of the scrollpane and everything works as expected.
public class HelloFX extends Application {
#Override
public void start(Stage primaryStage) {
VBox vbox = new VBox();
ScrollPane scrollPane = new ScrollPane();
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scrollPane.setContent(vbox);
scrollPane.heightProperty()
.addListener((obs, oldValue, newValue) ->
System.out.println(newValue));
Button button = new Button("ADD LINE");
button.setPrefHeight(25);
button.setOnAction(event ->
vbox.getChildren().add(new Label("line")));
BorderPane borderPane = new BorderPane();
borderPane.setCenter(scrollPane);
borderPane.setTop(button);
Scene scene = new Scene(borderPane, 100, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch();
}
}

How to make pane and elements in it resizable when stage size is changing

Can you please tell me how can I realize that the whole content of a pane will be resized while the stage is resized with mousedragg. Here is my code:
public class fab extends Application {
private Stage stage;
private Pane pane;
private Scene scene;
#Override
public void start(Stage stage) throws Exception {
this.stage = stage;
Button button = new Button("Button");
pane = new Pane();
pane.getChildren().add(button);
stage.setTitle("Test");
scene = new Scene(pane, 640, 640);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
I think there is the idea of binding. But I don't know how to use that, in order to make all nodes of a pane resizable, when the stage size is changing.
I'm searching a solution without Fxml or sceneBuilder.
Thank you in advance.
If you insists to use the Pane container then after the line scene = new Scene(pane, 640, 640); add this:
scene.widthProperty().addListener((c,o,n)->button.setPrefWidth((Double)n));
scene.heightProperty().addListener((c,o,n)->button.setPrefHeight((Double)n));
and after the line stage.setScene(scene); add this:
button.setPrefSize(scene.getWidth(), scene.getHeight());
This works fine with Pane and do your required thing.
But I prefer using an AnchorPane container and set the Top, Right,Bottom and Left anchors to 0 .
Here is the solution if you wish to bind the width of the button to you scene width
button.minWidthProperty().bind(scene.widthProperty());
You can also modify this +/- whatever you want for ex
button.minWidthProperty().bind(scene.widthProperty().subtract(20));
and you can do the same for the height
button.minHeightProperty().bind(scene.heightProperty().subtract(200));

How to block a ScrollPane panel JavaFX

I have a small problem. I'm building an interface with JavaFX like this:
I wonder, how can I do to block those "lines" of the ScrollPane I indicated in the image? Practically it is not to be resizable but among its properties the ScrollPane does not allow me to put the check on that property:
How can I do to solve?
thanks to all in advance!
I think your problem is that you have not added a minimum value to your ScrollPanes here's an example :
SplitPane split = new SplitPane();
split.setPrefSize(400, 400);
//First ScrollPane
ScrollPane spA = new ScrollPane();
spA.setMinWidth(100); //Block the scrollPane width to 100
spA.setFitToHeight(true);
spA.setFitToWidth(true);
Pane paneA = new Pane();
paneA.setStyle("-fx-background-color:red;");
spA.setContent(paneA);
//Second ScrollPane
ScrollPane spB = new ScrollPane();
spB.setMinWidth(100); //Block the scrollPane width to 100
spB.setFitToHeight(true);
spB.setFitToWidth(true);
Pane paneB = new Pane();
paneB.setStyle("-fx-background-color:blue;");
spB.setContent(paneB);
split.getItems().addAll(spA,spB);
To be able to use your scrollPane as it grows, you can use the binding and bind the content's (width/height properties) of your ScrollPane to their parents (ScrollPane) example :
//set the (FitToHeight/FitToWidth) properties to false before !
spA.widthProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
paneB.setMinWidth((double)newValue);
}
});
Good luck !

JavaFx Resize VBox as contents are added with ScrollPane

I am relatively new to JavaFx and I need help in getting a Vbox to grow as nodes are added to it.
I've place a VBox in a ScrollPane. The VBox gets filled with TitledPanes as they come in. But once the TitledPanes fill the space allotted the Vbox, the TitledPanes begin to overlap. Ideally I would want to Vbox to resize itself and use the ScrollPane to navigate.
I have the Vbox Max Height set to USE_COMPUTED_SIZE. I've added a listener to the ScrollPane to listen to changes in size of the VBox but no luck. Any Suggestions?
scrollPane.vvalueProperty().addListener(new ChangeListener<Number>() {
public void changed(ObservableValue<? extends Number> ov,
Number old_val, Number new_val) {
vBox.setLayoutY(-new_val.doubleValue());
}
});
Is there any reason you are using a VBox rather than an Accordion?
With an Accordion you could use a ListChangeListener to check for changes in TitledPane number and then adjust the size of the Accordion if an item was added or removed:
accordion.getPanes().addListener(new ListChangeListener<Item>() {
public void onChanged(Change<tem> c) {
while (c.next()) {
if(c.wasAdded() || c.wasRemoved){
//resize Accordion in dependency of the vvalue of your scrollpane
}
}
});
For a VBox, the principle should still be valid:
vbox.getChildren().addListener(new ListChangeListener<Item>() {
public void onChanged(Change<tem> c) {
while (c.next()) {
if(c.wasAdded() || c.wasRemoved){
//rezise VBox in dependency of the vvalue of your scrollpane
}
}
});
based on

How to make javafx.scene.Scene resize while maintaining an aspect ratio?

I'm writing an application with JavaFX 2.2.7-b01.
Here is an example of the code I currently have. How can I allow the application window to be resized but maintain the aspect ratio it is initially configured with? In other words, if the user resizes the window, the window width should always stay double the window height.
...
public void showScene(Stage stage, String fxmlPath) {
try {
FXMLLoader loader = new FXMLLoader();
loader.setBuilderFactory(new JavaFXBuilderFactory());
loader.setLocation(fxmlPath);
Parent page;
try (InputStream in = Main.class.getResourceAsStream(fxmlPath)) {
page = (Parent) loader.load(in);
}
Scene scene = new Scene(page, 400, 200);
stage.setScene(scene);
stage.sizeToScene();
stage.show();
} catch (Exception ex) {
...
}
}
...
It seems JavaFX allows a user to specify the width and height of a scene in the constructor but does not allow programmatic access to update the width or height. There are no setWidth or setHeight methods. I know I can add property listeners to get the read only width/height of the scene while it is being resized, but I haven't been able to figure out how to change the scene dimensions dynamically so I can force the aspect ratio to be maintained.
I imagine this would be possible if I were to subclass the Scene object (if I have to I will) but is there any other simple way to do this?
> How to make javafx.scene.Scene resize while maintaining an aspect ratio?
By manipulating the stage size instead of scene:
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Play by resizing the window");
VBox root = new VBox();
root.getChildren().add(btn);
root.setStyle("-fx-background-color: gray");
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.minWidthProperty().bind(scene.heightProperty().multiply(2));
primaryStage.minHeightProperty().bind(scene.widthProperty().divide(2));
primaryStage.show();
}
Use removeListener and addListener when changing value ​​to prevent listeners from chaining.
private ChangeListener<? super Number> widthChangeListener;
private ChangeListener<? super Number> heightChangeListener;
#Override
public void start(Stage stage) throws Exception {
widthChangeListener = (observable, oldValue, newValue) -> {
stage.heightProperty().removeListener(heightChangeListener);
stage.setHeight(newValue.doubleValue() / 2.0);
stage.heightProperty().addListener(heightChangeListener);
};
heightChangeListener = (observable, oldValue, newValue) -> {
stage.widthProperty().removeListener(widthChangeListener);
stage.setWidth(newValue.doubleValue() * 2.0);
stage.widthProperty().addListener(widthChangeListener);
};
stage.widthProperty().addListener(widthChangeListener);
stage.heightProperty().addListener(heightChangeListener);
}
In netbeans using Java Fx Scene Builder provide you can use AnchorPane Constraints to set
Resizing of stage.

Resources