Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding TextArea height to its content

JavaFX: Is it possible to bind TextArea height (row count) to the height of its content?
I would like to dynamically change height of TextArea while writing the text.

like image 947
madox2 Avatar asked Mar 23 '13 23:03

madox2


People also ask

How do I change the height of a textarea according to content?

You can achieve this by using a span and a textarea. You have to update the span with the text in textarea each time the text is changed. Then set the css width and height of the textarea to the span's clientWidth and clientHeight property.

How to set textarea size in JavaScript?

You can change the size of a textarea by chaning the cols and rows . If you want to expand and then shrink back to normal size you could define them as: var textarea = document. getElementById("queryText"); var largeRows = "20"; var largeCols = "100"; var normalRows = textarea.


3 Answers

Have a look at JavaFX utility class. Although this is not a solution using binding, computeTextHeight(Font font, String text, double wrappingWidth) method can help you.

like image 151
Ramazan Avatar answered Sep 30 '22 22:09

Ramazan


This is an exact, simple & working solution:

SimpleIntegerProperty count = new SimpleIntegerProperty(20);
int rowHeight = 10;

txtArea.prefHeightProperty().bindBidirectional(count);
txtArea.minHeightProperty().bindBidirectional(count);
txtArea.scrollTopProperty().addListener(new ChangeListener<Number>(){
    @Override
    public void changed(ObservableValue<? extends Number> ov, Number oldVal, Number newVal) {
        if(newVal.intValue() > rowHeight){
            count.setValue(count.get() + newVal.intValue());
        }
    }
});

Alternatively you can use lambdas to simply the syntax even further:

SimpleIntegerProperty count=new SimpleIntegerProperty(20);
int rowHeight = 10;

textArea.prefHeightProperty().bindBidirectional(count);
textArea.minHeightProperty().bindBidirectional(count);
textArea.scrollTopProperty().addListener((ov, oldVal, newVal) -> {
    if(newVal.intValue() > rowHeight){
        count.setValue(count.get() + newVal.intValue());
    }
});
like image 33
Ruturaj Patil Avatar answered Sep 29 '22 22:09

Ruturaj Patil


A solution that workq fine in javafx8 (hiding toolbar is inspired from JavaFX TextArea Hiding Scroll Bars):

class MyTextArea extends TextArea {

    @Override
    protected void layoutChildren() {
        super.layoutChildren();
        ScrollBar scrollBarv = (ScrollBar) this.lookup(".scroll-bar:vertical");
        if (scrollBarv != null) {
            System.out.println("hiding vbar");
            ((ScrollPane) scrollBarv.getParent()).setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        }
        ScrollBar scrollBarh = (ScrollBar) this.lookup(".scroll-bar:horizontal");
        if (scrollBarh != null) {
            System.out.println("hiding hbar");
            ((ScrollPane) scrollBarh.getParent()).setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
        }
    }

    @Override
    protected double computePrefWidth(double width) {
        Bounds bounds = getTextBounds();
        Insets insets = getInsets();
        double w = Math.ceil(bounds.getWidth() + insets.getLeft() + insets.getRight());
        return w;
    }

    @Override
    protected double computePrefHeight(double height) {
        Bounds bounds = getTextBounds();
        Insets insets = getInsets();
        double h = Math.ceil(bounds.getHeight() + insets.getLeft() + insets.getRight());
        return h;
    }

    //from https://stackoverflow.com/questions/15593287/binding-textarea-height-to-its-content/19717901#19717901
    public Bounds getTextBounds() {
        //String text = (textArea.getText().equals("")) ? textArea.getPromptText() : textArea.getText();
        String text = "";
        text = this.getParagraphs().stream().map((p) -> p + "W\n").reduce(text, String::concat);
        text += "W";
        helper.setText(text);
        helper.setFont(this.getFont());
        // Note that the wrapping width needs to be set to zero before
        // getting the text's real preferred width.
        helper.setWrappingWidth(0);
        return helper.getLayoutBounds();
    }
}
like image 30
Daniel Avatar answered Sep 30 '22 22:09

Daniel