JavaFX: TextArea automatic height expanding withou

2019-03-03 17:42发布

问题:

Can I force the TextArea control to automatic expanding the height?

In the following case, I would like to see the scrollbar at ScrollPane control, not at TextArea control.

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.VBox?>

<ScrollPane fitToHeight="true" fitToWidth="true" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
            minWidth="-Infinity" xmlns="http://javafx.com/javafx/8.0.91" xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="sample.Controller">
    <VBox style="-fx-background-color: bisque">
        <TextField/>
        <TextArea VBox.vgrow="ALWAYS">
            <VBox.margin>
                <Insets top="20.0"/>
            </VBox.margin>
        </TextArea>
    </VBox>
</ScrollPane>

回答1:

For now the only solution that is close to your problem is given by @Uluk Biy, that i found here, what i did is just fit his logic, and hide the ScrollBars. The only problem is the size of the TextArea which is binded to that of the Text and so it starts with a minimum height at the beginning of the edition, here is the complete code :

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.Pane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class Launcher extends Application{

private Pane root = new Pane();
private Scene scene;

private ScrollPane scroller;
private Pane content = new Pane();

private TextField textF = new TextField();
private TextArea textA = new TextArea();

private Text textHolder = new Text(); 
private double oldHeight = 0;


@Override
public void start(Stage stage) throws Exception {

    root.getChildren().addAll(yourSP());
    scene = new Scene(root,300,316);
    stage.setScene(scene);
    stage.show();

}

private ScrollPane yourSP(){

    content.setMinSize(300, 300); 
    textF.setPrefSize(260, 40); 
    textF.setLayoutX(20);
    textF.setLayoutY(20); 
    textA.setPrefSize(260, 200);
    textA.setLayoutX(20);
    textA.setLayoutY(80); 

    textA.getStylesheets().add(getClass().getResource("texta.css").toExternalForm());
    content.getChildren().addAll(textA,textF);

    /*************************@Uluk Biy Code**************************/
    textA.setWrapText(true);
    textHolder.textProperty().bind(textA.textProperty());
    textHolder.layoutBoundsProperty().addListener(new ChangeListener<Bounds>() {
        @Override
        public void changed(ObservableValue<? extends Bounds> observable, Bounds oldValue, Bounds newValue) {
            if (oldHeight != newValue.getHeight()) {
                oldHeight = newValue.getHeight();
                textA.setPrefHeight(textHolder.getLayoutBounds().getHeight() + 20); 
                System.out.println(textHolder.getLayoutBounds().getHeight());
            }
        }
    });
    /****************************************************************/

    scroller = new ScrollPane(content);
    scroller.setHbarPolicy(ScrollBarPolicy.NEVER); 
    scroller.setPrefSize(300, 316); 


    return scroller;
}


public static void main(String[] args) {

    launch(args); 

  }

 }

Of course the code can be adapted to fxml format, I just have not had enough time to do it, and here is the style of the TextArea:

.text-area > .scroll-pane{

-fx-hbar-policy:never;
-fx-vbar-policy:never; 

}

good luck for the continuation !