Search code examples
javajavafxjavafx-8fxml

How to wrap a Text in JavaFX


I am trying to create a simple JavaFX app where Texts are programmatically added to a VBox positioned in a Scrollpane (so that, when there are too many texts, the window can be scrolled to see other parts of the overall).

My problem is that my Texts do not wrap : they just go out of the window on a single line.

Using preceding StackOverflow answers, I successively tried :

  • deactivating the horizontal scrolling of my scrollpane,
  • setting the ScrollPane with fitToWidth="true"
  • binding my Texts widthProperty to that of one of the enclosing layouts
  • binding my Texts widthProperty to that of the scene itself (which I would like to avoid, as I need to set the first in the Initialize() method of my controller, when the Scene is not yet available, it didn't work anyway).

None of these made any difference (besides the disappearance of the horizontal scrollbar, which is pointless, since you can scroll by panning anyway).

Here is my fxml :

<BorderPane fx:controller="org.duckdns.spacedock.lifepathfx.PathController" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
<center>
<ScrollPane hbarPolicy="NEVER" pannable="true" fitToWidth="true" fx:id="scrollPane" >
    <content>
    <VBox fx:id="mainBox" >

    </VBox>
    </content>
</ScrollPane>
</center>
<top>
<ToolBar>
    <items>
    <Button mnemonicParsing="false" text="Back" onAction="#rollback" />
    </items>
</ToolBar>
</top>

And here is the code where I add my Texts :

private void displayNewParagraph()
{
Text text = new Text(someFunctionReturningAString());
text.wrappingWidthProperty().bind(mainBox.widthProperty().subtract(15));
mainBox.getChildren().add(text);
} 

Note : I am using a fullscreen stage as I want my app to display about the same way on every screen size. That is why I am not using a fixed width for the Texts.

Edit : I tried another thing : binding the ScrollPane and the VBox width properties with :

mainBox.maxWidthProperty().bind(scrollPane.widthProperty().subtract(10).subtract(10));
mainBox.minWidthProperty().bind(scrollPane.widthProperty().subtract(10).subtract(10));

All it did was deactivating the horizontal scrolling, but the Texts still don't wrap : so now they go out the window and can't be seen in their entirety.

Edit2 : I also tried :

text.setWrappingWidth(mainBox.widthProperty().intValue() - 10);

didn't work either : the text just won't wrap at all.

Edit3 : I tried this simple experiment :

text.setWrappingWidth(150);
System.out.println("wrapping width:" + text.getWrappingWidth());

wrapping width:150 is outputed but the text doesn't wrap... now I am confused.


Solution

  • Alright, answering my own question, I found out the normal procedure is to wrap the Texts in a TextFlow object. Do this and the Texts wrap nicely.

    What I don't understand is why absolutely nowhere in the doc is it written that Texts won't wrap if they are in a *Box in a ScrollPane even if you set their wrapping width properly.

    That said it is working now, Texts are being added to the TextFlow instead of the Box directly and everyone is happy.