Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX: textArea.setScrollTop(Double.MAX_VALUE) not always works

Tags:

java

javafx

This is the piece of my code.

textArea.setText(someNewText)
textArea.positionCaret(textArea.getText().length());
textArea.setEditable(true);
textArea.setScrollTop(Double.MAX_VALUE);

I use textArea.setScrollTop(Double.MAX_VALUE) to scroll textarea to the bottom (solution I found in internet). It works, but not always. I've noted that it can not work only when vertical scroll bar is not visible before calling this code and visible after the code was executed. When vertical scroll bar is visible before calling this code then scrolling to the bottom works always. How to fix it? Maybe I should make vertical scroll bar always visible? If yes, then how - I didn't find the solution.

EDIT: This is the sample code:

public class JavaFxApp1 extends Application{

    private TextArea textArea;

    @Override
    public void start(Stage stage) throws Exception {
        Button button=new Button("Press here");
        textArea=new TextArea();
        VBox vbox = new VBox(button,textArea);
        button.setOnAction((event)->{
            textArea.appendText("###This is a very long string:some text some text some text some text some"
                    + " text some text some text some text some text some text"
                    + " text some text some text some text some text some text"
                    + " text some text some text some text some text some text .\n");
            textArea.selectEnd();
            textArea.deselect();
            textArea.setScrollTop(Double.MAX_VALUE);
        });
        textArea.setEditable(true);
        textArea.setWrapText(true);
        textArea.setStyle("-fx-font-size:14px;-fx-focus-color: transparent;-fx-font-family: monospace;");
        Scene scene=new Scene(vbox);
        stage.setTitle("SomeTitle");
        stage.setScene(scene);
        stage.setMinHeight(400);
        stage.setMinWidth(800);
        stage.show();
    }
}

This is the result when I pressed button 4 times: enter image description here As you see it didn't scroll to the bottom. After I press button again (the fifth time) I have the following result: enter image description here Now, as you see it was scrolled to the bottom. I tried to add:

ScrollPane scrollPane = (ScrollPane) textArea.lookup(".scroll-pane");  
scrollPane.setVbarPolicy(ScrollBarPolicy.ALWAYS);

to make scrollbar visible always - it is visible but after 4 times anyway doesn't scroll to the bottom.

How to fix it?

like image 330
Pavel_K Avatar asked Aug 05 '16 13:08

Pavel_K


1 Answers

if you want to scroll to the Top your code will be this way

ta.selectHome();
ta.deselect();

if you want to scroll to the Bottom your code will be this way

ta.selectEnd();
ta.deselect();

now let the TextArea worry about its visible areas

edit

maybe i didnt get your requirement, cause honestly this is the first time i have seen that method so to give an answer based on your hypothesis

Maybe I should make vertical scroll bar always visible? If yes, then how

well thats easy TextArea uses ScrollPane, when there is a visible scroll this line TextArea.getChildrenUnmodifiable().size(); will check out to be 1, so you fish it out when you create your TextArea

TextArea.getChildrenUnmodifiable().addListener(new ListChangeListener<Node>() {
        @Override
        public void onChanged(javafx.collections.ListChangeListener.
            Change<? extends Node> c) {
            while(c.next()){
                if(c.wasAdded()){
                    for(Node n : TextArea.getChildrenUnmodifiable()){
                        if(n.getClass().isAssignableFrom(ScrollPane.class)){
                            //just trying to be cool here ^^
                            ScrollPane sp = (ScrollPane) n;
                            sp.setVbarPolicy(ScrollBarPolicy.ALWAYS);
                        }
                    }
                }
            }
        }
    });

actually you can keep a reference to the ScrollPane and anytime you want to scroll to the bottom ScrollPane.setVvalue(1.0); to the top ScrollPane.setVvalue(0.0); etc etc.

you can get the value with ScrollPane.getVvalue().

like image 192
Elltz Avatar answered Nov 01 '22 08:11

Elltz