1

In my application I am appending the text to TextArea every 2 minutes. When ever I append new line to TextArea the auto scroll automatically going to down. But I want to stay the scroll where i am keep the scroll button. How to do it in JavaFX.

logTextArea.appendText("Here i am appending text to text area"+"\n");
logTextArea.setScrollTop(Double.MIN_VALUE);

I tried this but scroll automatically going to down , but I need to keep my scroll chosen position I don't want to go automatically down.

How can I do this?

DVarga
  • 21,311
  • 6
  • 55
  • 60
epn
  • 83
  • 1
  • 3
  • 12

3 Answers3

2

The most straightforward way is to remember the position of the caret and restore it after it gets moved by appendText or setText.

Here's how you can do it:

int caretPosition = area.caretPositionProperty().get();
area.appendText("Here i am appending text to text area"+"\n");
area.positionCaret(caretPosition);
Dth
  • 1,916
  • 3
  • 23
  • 34
  • This worked when being used in a loop to appendText. – Terry Carter Mar 10 '17 at 16:25
  • Wouldnt use this even better: ``` int caretPosition = getCaretPosition(); int anchorPosition = getAnchor(); super.appendText(text); selectRange(anchorPosition, caretPosition); ``` – Nor.Z May 13 '23 at 16:31
2

You can write your own function to append text. In this method you can use setText, rather than appendText as appendText automatically scrolls to the end of the content (setText scrolls to the beginning but this can be supressed by setting back the scrollTopProperty to its previous value).

Example

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            BorderPane root = new BorderPane();
            Scene scene = new Scene(root,400,400);

            TextArea ta = new TextArea();
            root.setCenter(ta);
            Button button = new Button("Append");
            button.setOnAction(e -> {
                appendTextToTextArea(ta, "BlaBlaBla\n");
            });
            root.setBottom(button);

            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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


    /**
     * Appends text to the end of the specified TextArea without moving the scrollbar.
     * @param ta TextArea to be used for operation.
     * @param text Text to append.
     */
    public static void appendTextToTextArea(TextArea ta, String text) {
        double scrollTop = ta.getScrollTop();
        ta.setText(ta.getText() + text);
        ta.setScrollTop(scrollTop);
    }
}

Note:

Alternatively you can also extend TextArea and overload appendText to be able to specify whether you want to move the scrollbar:

public class AppendableTextArea extends TextArea {

    public void appendText(String text, Boolean moveScrollBar) {
        if (moveScrollBar)
            this.appendText(text);
        else {
            double scrollTop = getScrollTop();
            setText(getText() + text);
            setScrollTop(scrollTop);
        }
    }
}

and the usage:

AppendableTextArea ta = new AppendableTextArea();
ta.appendText("BlaBlaBla\n", false);
DVarga
  • 21,311
  • 6
  • 55
  • 60
0

Maybe you could just add a changeListener to the TextArea which does nothing, or it just scrolls to the top of the TextArea everytime the text inside it is changed.

logTextArea.textProperty().addListener(new ChangeListener<Object>() {
  @Override
  public void changed(ObservableValue<?> observable, Object oldValue, Object newValue) {
      logTextArea.setScrollTop(Double.MIN_VALUE); //this will scroll to the top
  }
});

Now when you logTextArea.appendText("Here i am appending text to text area"+"\n"); to the TextArea, it should stay at the top.

The idea is taken from: JavaFX TextArea and autoscroll

Community
  • 1
  • 1
sundri23
  • 33
  • 2
  • 8
  • where i need to add this one ? means in which class controller class or Application extended class @ user2882590 – epn Aug 23 '16 at 10:51
  • You have a controller class, where you declared your TextArea. If I remember correctly, in the `public void initialize()` function you can add this listener to the `logTextArea` if it comes from an fxml file. If not, then you could just add this listener after you create it. so after: `TextArea logTextArea = new TextArea();` – sundri23 Aug 23 '16 at 10:58
  • Ok, But my question is after adding some text to text area i am scroll my button to middle ,after that when i add text the scroll button will not go up side it need to stay back in middle only i want like that. how can i do ? – epn Aug 23 '16 at 12:29