What is the preferred size of the control?

My first attempt to play with JavaFX, and I'm trying to understand a little about prototyping. How to access the preferred size of the control?

In the example below, I am trying to set the maximum width to 200 pixels wider than the preferred width. That is, I want the button to increase (to the maximum) as the frame width increases.

However, when I run the code, the preferred width is -1, so adding 200 to the preferred width gives a maximum width of 199.

import javafx.application.Application; import javafx.event.*; import javafx.stage.Stage; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.*; import javafx.geometry.Insets; public class BorderPaneSSCCE extends Application { @Override public void start(Stage primaryStage) { Button button = new Button( "Button at PreferredSize" ); button.setMaxWidth( button.getPrefWidth() + 200 ); System.out.println(button.prefWidth(-1) + " : " + button.getPrefWidth()); button.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { System.out.println("Width: " + button.getWidth()); } }); HBox root = new HBox(); HBox.setHgrow(button, Priority.ALWAYS); root.getChildren().add(button); Scene scene = new Scene(root); primaryStage.setTitle("Java FX"); primaryStage.setScene(scene); primaryStage.show(); System.out.println(button.prefWidth(-1) + " : " + button.getPrefWidth()); } public static void main(String[] args) { launch(args); } } 

When I run the code and click on the button, I see: Width: 139.0

After resizing the frame so that the button is as large as possible, and I click the button that I see: Width: 199.0

I was hoping to see Width: 339.0 (i.e. 139 + 200)

So, how do we access the preferred size / width of the control?

+5
source share
3 answers

getPrefWidth() by default returns the flag USE_COMPUTED_SIZE (which is -1).

You can use prefWidth(-1) to get the internally calculated preferred width. However, the preferred width will not be calculated until the node is laid out by the layout panel (HBox in your example). This happens the first time a scene is displayed.

You have several options if you want the maximum width to depend on your preferred width. One of them is to set the preferred width to a fixed value using setPrefWidth() before setting the maximum width.

Another is to implement your own layout algorithm - either on the node or on the layout panel. Here is an example of using a custom button.

 // button whose maxWidth is always prefWidth + 200 Button button = new Button() { @Override protected double computeMaxWidth(double height) { return this.prefWidth(height) + 200.0; } }; 
+4
source

-1 is the value of Region.USE_COMPUTED_SIZE , which tells the component to figure out its own best size. This works because each Node has a method called prefWidth(double height) and it is double prefHeight(double width) (the same for the minimum / maximum size) that layout managers use to calculate the layout of their children. To get the pref size you need to use

 button.prefWidth([-1 or Region.USE_COMPUTED_SIZE]) 

( docs )

+2
source

getPrefWidth() only works after Node been shown / displayed.

You can show Button first or try using Node.prefWidth(-1) .

+1
source

All Articles