Marcelo Glasberg
Marcelo Glasberg

Reputation: 30879

JavaFx: Sizing, when a Pane contains text

In JavaFX, I have a Label (or TextFlow) inside of an AnchorPane (or StackPane), inside of a container Pane.

The container Pane has infinite height, but its width is fixed to be anything I want.

I need:

1) The AnchorPane's width to fill all of the available space, but not greater than the label's width when it fits all in one line.

2) The Label to be multiline (wrap=true) and fill all of the available space.

3) The AnchorPane's height to be equal to the height of the Label.

enter image description here

The code setup:

Pane rootPane = new Pane();
rootPane.setBackground(new Background(new BackgroundFill(Color.FIREBRICK, CornerRadii.EMPTY, Insets.EMPTY)));
AnchorPane anchorPane = new AnchorPane();
anchorPane.setBackground(new Background(new BackgroundFill(Color.FORESTGREEN, CornerRadii.EMPTY, Insets.EMPTY)));
Label text = new Label("text text text text text text text text text text text");
anchorPane.getChildren().add(text);
rootPane.getChildren().add(anchorPane);

Or, instead of a label I can have:

TextFlow text = new TextFlow(new Text("text text text text text text text text text text text"));

I've wasted hours on this problem. This is so easy in HTML... How can I achieve this?

Upvotes: 1

Views: 1570

Answers (1)

egonr
egonr

Reputation: 982

Code

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;


public class Main extends Application { 

    @Override
    public void start(Stage primaryStage) throws Exception{
        Pane rootPane = new Pane();

        Label text = new Label();        
        text.setWrapText(true);
        text.setText("text text text text text text text text text text text");

        AnchorPane anchorPane = new AnchorPane();
        anchorPane.getChildren().add(text);
        anchorPane.setBackground(new Background(new BackgroundFill(Color.FORESTGREEN, CornerRadii.EMPTY, Insets.EMPTY)));

        rootPane.getChildren().add(anchorPane);
        rootPane.setBackground(new Background(new BackgroundFill(Color.FIREBRICK, CornerRadii.EMPTY, Insets.EMPTY)));

        primaryStage.setScene(new Scene(rootPane, 300, 275));
        primaryStage.show();

        rootPane.widthProperty().addListener(new ChangeListener<Number>() {

            private double textWidth;

            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {

                if(text.getWidth() > 0 && textWidth == 0) {
                    textWidth = text.getWidth();
                }

                if(textWidth > 0 && textWidth > rootPane.getWidth())
                {
                    text.setPrefWidth(rootPane.getWidth());
                }else
                {
                    text.setPrefWidth(Label.USE_COMPUTED_SIZE);
                }
            }
        });
    }


    public static void main(String[] args) {
        launch(args);
    }
}

Result

Upvotes: 2

Related Questions