Share the post "How To Set Dynamic Height Of TextArea Based On Width In Java FX 2"
I wish Oracle simply included this feature so developers would not have to code it from scratch. However, I came across a custom made class called ScrollFreeTextArea from the javafx-demos website.
This class simply did the trick for me. So whenever you type a long text and it wraps itself or press the ENTER key for a new line, the height of the TextArea increases without displaying the scrollbar.
Here is the complete source code.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
public class ScrollFreeTextArea extends StackPane { private Label label; private TextArea textArea; private Character enterChar = new Character((char) 10); private Region content; private SimpleDoubleProperty contentHeight = new SimpleDoubleProperty(); private final double NEW_LINE_HEIGHT = 18D; private final double TOP_PADDING = 3D; private final double BOTTOM_PADDING = 6D; public ScrollFreeTextArea() { super(); configure(); } private void configure() { setAlignment(Pos.TOP_LEFT); this.textArea = new TextArea() { @Override protected void layoutChildren() { super.layoutChildren(); if (content == null) { content = (Region) lookup(".content"); contentHeight.bind(content.heightProperty()); content.heightProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> paramObservableValue, Number paramT1, Number paramT2) { //System.out.println("Content View Height :"+paramT2.doubleValue()); } }); } }; }; this.textArea.setWrapText(true); this.label = new Label(); this.label.setWrapText(true); this.label.prefWidthProperty().bind(this.textArea.widthProperty()); label.textProperty().bind(new StringBinding() { { bind(textArea.textProperty()); } @Override protected String computeValue() { if (textArea.getText() != null && textArea.getText().length() > 0) { if (!((Character)textArea.getText().charAt(textArea.getText().length() - 1)).equals(enterChar)) { return textArea.getText() + enterChar; } } return textArea.getText(); } }); StackPane lblContainer = StackPaneBuilder.create() .alignment(Pos.TOP_LEFT) .padding(new Insets(4,7,7,7)) .children(label) .build(); // Binding the container width/height to the TextArea width. lblContainer.maxWidthProperty().bind(textArea.widthProperty()); textArea.textProperty().addListener(new ChangeListener<String>() { @Override public void changed(ObservableValue<? extends String> paramObservableValue, String paramT1, String value) { layoutForNewLine(textArea.getText()); } }); label.heightProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> paramObservableValue, Number paramT1, Number paramT2) { layoutForNewLine(textArea.getText()); } }); getChildren().addAll(lblContainer, textArea); } private void layoutForNewLine(String text){ if (text != null && text.length() > 0 && ((Character)text.charAt(text.length() - 1)).equals(enterChar)) { textArea.setPrefHeight(label.getHeight() + NEW_LINE_HEIGHT + TOP_PADDING + BOTTOM_PADDING); textArea.setMinHeight(textArea.getPrefHeight()); } else { textArea.setPrefHeight(label.getHeight() + TOP_PADDING + BOTTOM_PADDING); textArea.setMinHeight(textArea.getPrefHeight()); } } public TextArea getTextArea() { return textArea; } } |
Works like a charm. Thanks a lot!
Thank for the code!
One question: if I set max height for scrollfreetextarea, then enter very long text, how do I set scrolling automatically to the end of the text?