Reputation: 1525
I've been struggling with this issue for a couple hours and managed to reproduce the problem with the sample below. The actual program changes what is set in main.add(node, 0, 1)
as the content based on what button is pressed in menu
. I tried several different things such as AnchorPanes, changing setMaxHeight, and setVgrow for many different nodes in the each pane but have not been very successful. How would I make the ListView in the example fill the rest of the window height where it is located?
public class Main extends Application {
public void start(Stage stage) throws Exception {
// I've tried with this as a VBox, no effect.
GridPane main = new GridPane();
main.setGridLinesVisible(true);
main.setHgap(5);
main.setVgap(10);
// Meant to change what content is displayed in the actual program.
HBox menu = new HBox();
menu.setMaxWidth(Double.MAX_VALUE);
menu.setAlignment(Pos.CENTER);
main.add(menu, 0, 0);
GridPane.setHgrow(menu, Priority.ALWAYS);
menu.getChildren().addAll(new Button("Button 1"), new Button("Button 2"), new Button("Button 3"), new Label("Hello world!"));
// Changes often.
GridPane content = new GridPane();
main.add(content, 0, 1);
// Options for the displayed content, changes the StackPane displayed below in my actual program.
HBox submenu = new HBox();
submenu.setMaxWidth(Double.MAX_VALUE);
submenu.setAlignment(Pos.CENTER);
content.add(submenu, 0, 0);
GridPane.setHgrow(submenu, Priority.ALWAYS);
submenu.getChildren().addAll(new Button("Button A"), new Button("Button B"), new Button("Button C"), new Label("Hello world!"));
// This is a custom class extended by StackPane in my actual program. Is often over overlayed with another transparent StackPane (not relevant to the problem).
StackPane subcontent = new StackPane();
subcontent.setMaxHeight(Double.MAX_VALUE);
subcontent.setMaxWidth(Double.MAX_VALUE);
content.add(subcontent, 0, 1);
// This was meant to be a TabPane in my actual program but this has the same outcome that won't fill the rest of the window height.
ListView<String> list = new ListView<>();
list.setMaxHeight(Double.MAX_VALUE);
list.setMaxWidth(Double.MAX_VALUE);
ObservableList<String> items = FXCollections.observableArrayList();
list.setItems(items);
subcontent.getChildren().add(list);
for(int i=0; i<100; i++) {
items.add("# "+i);
}
Scene scene = new Scene(main, 900, 550);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Upvotes: 1
Views: 2037
Reputation: 209235
You need both
GridPane.setVgrow(content, Priority.ALWAYS);
and
GridPane.setVgrow(subcontent, Priority.ALWAYS);
The grid panes are going to size things to their preferred heights with the default vgrow
: the preferred height of content
is determined by the preferred height(s) of its child nodes, and the preferred height of a ListView
is a fixed (arbitrary) size (I believe 400 pixels). So if you don't instruct subcontent
to grow, it will by the preferred size of the list view, and forcing content
to grow will just add extra (blank) space to content
: if you don't force content
to grow, it will take its preferred size, which is the preferred size of subcontent
plus the preferred size of submenu
.
Setting the max height doesn't do anything in this example, as you just need to allow the various nodes to grow beyond their preferred size:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Main extends Application {
public void start(Stage stage) throws Exception {
// I've tried with this as a VBox, no effect.
GridPane main = new GridPane();
main.setGridLinesVisible(true);
main.setHgap(5);
main.setVgap(10);
// Meant to change what content is displayed in the actual program.
HBox menu = new HBox();
// menu.setMaxWidth(Double.MAX_VALUE);
menu.setAlignment(Pos.CENTER);
main.add(menu, 0, 0);
GridPane.setHgrow(menu, Priority.ALWAYS);
menu.getChildren().addAll(new Button("Button 1"), new Button("Button 2"), new Button("Button 3"), new Label("Hello world!"));
// Changes often.
GridPane content = new GridPane();
main.add(content, 0, 1);
// Options for the displayed content, changes the StackPane displayed below in my actual program.
HBox submenu = new HBox();
// submenu.setMaxWidth(Double.MAX_VALUE);
submenu.setAlignment(Pos.CENTER);
content.add(submenu, 0, 0);
GridPane.setHgrow(submenu, Priority.ALWAYS);
submenu.getChildren().addAll(new Button("Button A"), new Button("Button B"), new Button("Button C"), new Label("Hello world!"));
// This is a custom class extended by StackPane in my actual program. Is often over overlayed with another transparent StackPane (not relevant to the problem).
StackPane subcontent = new StackPane();
// subcontent.setMaxHeight(Double.MAX_VALUE);
// subcontent.setMaxWidth(Double.MAX_VALUE);
content.add(subcontent, 0, 1);
// This was meant to be a TabPane in my actual program but this has the same outcome that won't fill the rest of the window height.
ListView<String> list = new ListView<>();
// list.setMaxHeight(Double.MAX_VALUE);
// list.setMaxWidth(Double.MAX_VALUE);
ObservableList<String> items = FXCollections.observableArrayList();
list.setItems(items);
subcontent.getChildren().add(list);
for(int i=0; i<100; i++) {
items.add("# "+i);
}
GridPane.setVgrow(content, Priority.ALWAYS);
GridPane.setVgrow(subcontent, Priority.ALWAYS);
Scene scene = new Scene(main, 900, 550);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Upvotes: 2