The solution you posted in your question seemed to work OK for me on testing.
In the image below the scene has been resized to trigger wrapping of the TextFlow (shown in red). On the right, the TextFlow does not exactly wrap at the last visible character, because the last character in the line is a space, so the wrapping occurs after the space. Taking into account the TextFlow bounds are flush to all of the text as required.
If you unclamp the max width, you get the default behavior of the text box which is to have the width grow (as you can see below).
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.text.*;
import javafx.stage.Stage;
public class TextFlowWrapper extends Application {
@Override
public void start(Stage stage) {
TextFlow textFlow = new TextFlow(
new Text(
"Box with long description that should be wrapped"
)
) {
@Override
protected void layoutChildren() {
super.layoutChildren();
double maxChildWidth = 0;
for (Node child : getManagedChildren()) {
double childWidth = child.getLayoutBounds().getWidth();
maxChildWidth = Math.max(maxChildWidth, childWidth);
}
double insetWidth = getInsets().getLeft() + getInsets().getRight();
double adjustedWidth = maxChildWidth + insetWidth;
setMaxWidth(adjustedWidth);
}
};
textFlow.setStyle("-fx-background-color: red");
textFlow.setMaxWidth(Control.USE_PREF_SIZE);
textFlow.setMaxHeight(Control.USE_PREF_SIZE);
Button unclamp = new Button("Unclamp max width");
unclamp.setOnAction(e -> textFlow.setMaxWidth(Double.MAX_VALUE));
StackPane wrappedText = new StackPane(textFlow);
VBox vbox = new VBox(
unclamp,
wrappedText
);
VBox.setVgrow(wrappedText, Priority.ALWAYS);
Scene scene = new Scene(
vbox
);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The solution is a little bit of a hack, you might want to ask one of the JavaFX developers for some input on the openjfx developer list. Maybe some additional api like a boolean pack property which would conditionally update the internal textflow layout algorithm to automatically pack the textflow to a minimal size would be a way to do this better. Part of the difficulty is that it is a hard question to write in such a way that the issue is easily understandable. It is also hard to say if this is some kind of corner case or if it is something that more people will encounter (hence perhaps justifying the complexity of an additional API).