Java 始终显示文本区域中的最后一行

Java 始终显示文本区域中的最后一行,java,javafx-8,Java,Javafx 8,我有一个JavaFXTextArea,在这里我更新了来自另一个线程的文本 /** * Start a new thread to update the text in the textarea. The progressmanager is called in a loop to deleiver the updated text */ private void startTextAreaUpdate() { final Task<Void&g

我有一个JavaFXTextArea,在这里我更新了来自另一个线程的文本

/**
     * Start a new thread to update the text in the textarea. The progressmanager is called in a loop to deleiver the updated text
     */
    private void startTextAreaUpdate() {

        final Task<Void> updateTextAreaTask = new Task<Void>() {

            @Override
            protected Void call() throws Exception {

                // Start updating the progresstext
                while (!prog.getIsDone()) {
                    updateMessage(prog.getProgressText());
                    Thread.sleep(100);
                }

                return null;

            }

        };

        //Here the TextArea text is bound to the task
        taProgressText.textProperty()
                .bind(updateTextAreaTask.messageProperty());
        // Start the action in a new thread
        Thread th = new Thread(updateTextAreaTask);
        th.setDaemon(true);
        th.start();

    }
/**
*启动一个新线程以更新textarea中的文本。在循环中调用progressmanager以删除更新的文本
*/
私有void startTextAreaUpdate(){
最终任务updateTextAreaTask=新任务(){
@凌驾
受保护的Void调用()引发异常{
//开始更新progresstext
而(!prog.getIsDone()){
updateMessage(prog.getProgressText());
睡眠(100);
}
返回null;
}
};
//此处文本区域文本绑定到任务
taProgressText.textProperty()
.bind(updateTextAreaTask.messageProperty());
//在新线程中启动操作
Thread th=新线程(updateExtraeaTask);
th.setDaemon(true);
th.start();
}
因为文本不适合文本区域,我总是想显示文本的最后一行。 在主线程中,我添加了一个ChangeListener

taProgressText.textProperty().addListener(new ChangeListener<String>() {

    @Override
    public void changed(ObservableValue<? extends String> observable,
            String oldValue, String newValue) {
        int lastPos = taProgressText.getText().length();
        taProgressText.positionCaret(lastPos);
    }
});
taProgressText.textProperty().addListener(新的ChangeListener()){
@凌驾

public void已更改(observeValue我认为克拉的位置已更改,但它实际上没有滚动。 尝试此(丑陋的黑客…)而不是绑定和当前侦听器:

updateTextAreaTask.messageProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> obs, String oldMessage, String newMessage) {
        taProgressText.setText(newMessage);
        ScrollBar scrollBar = (ScrollBar) taProgressText.lookup(".scroll-bar:vertical");
        if (scrollBar != null) {
            scrollBar.setValue(scrollBar.getMax());
        }
    }
});
updateTextAreaTask.messageProperty().addListener(新的ChangeListener()){
@凌驾

public void changed(Observalevalue)与您的问题不太相关,但您没有显示updateMessage方法的实现。我认为这需要在FX应用程序线程上运行。@Boomah是任务API的一部分,“对updateMessage的调用将合并并稍后在FX应用程序线程上运行”。不幸的是,这不起作用。当您从另一个线程更新TextArea时,我怀疑有错误。我还尝试了setScrollTop(Double.MAX_值)和setScrollTop(Double.MIN_值)。当我调试listner时,它会被触发,但滚动条不会发生任何变化。它不会在另一个线程上更新:这将在FX应用程序线程上运行。它对我很有效,但使用这样的查找不是很可靠。