JavaFX:使用appendText自动滚动TextArea但没有监听器

时间:2016-07-29 18:43:21

标签: multithreading javafx textarea appendtext

我已经在这个主题上阅读了有关Stackoverflow的其他文章。但它们都没有完全符合我的问题。

我想在TextArea中记录算法。在算法的每次迭代中,应通过appendText()扩展此TextArea中的文本。

我的第一个问题是:我应该在哪里创建新线程以及两个线程如何相互通信(GUI和算法)?

在我的实际设计中,我有三个重要的类:视图,它包含TextArea,控制器,它调用算法和算法,需要多次迭代和TextArea(调用appendText() - 方法在代码中的代表性地点。)

在此设计中,控制器调用算法,算法使用for循环迭代n次,在终止后,GUI显示更改。但是当算法调用appendText() - 方法时,我希望GUI同时显示更改。

我的第二个问题是TextArea的自动滚动。在每次appendText调用之后,TextArea应该完全向下滚动。但我认为这个问题的解决方案是我第一个问题的解决方案。

我会非常感谢你的帮助。

1 个答案:

答案 0 :(得分:0)

在没有(很多)更多信息的情况下完全回答你的问题几乎是不可能的,但我会使用的一般方法是让算法有一个回调来处理消息,可以通过算法的每一步。从控制器,在FX应用程序线程上传递回调的实现,该回调用消息更新文本区域。

类似的东西:

public class Algorithm {

    private Consumer<String> statusCallback ;

    public Algorithm(Consumer<String> statusCallback) {
        this.statusCallback = statusCallback ;
    }

    public Algorithm() {
        // by default, callback does nothing:
        this(s -> {});
    }

    public void performAlgorithm() {

        while (! finished() ) {
            doNextStep();
            String statusMessage = getStatus();
            statusCallback.accept(statusMessage);
        }
    }
}

然后

public class Controller {

    private View view = ... ;

    public void startAlgorithm() {
        Algorithm algorithm = new Algorithm(s -> Platform.runLater(view.appendStatus(s)));
        Thread t = new Thread(algorithm::performAlgorithm);
        t.setDaemon(true);
        t.start();
    }
}

对于View,您可以执行以下操作(请注意,您可以使用textArea.setScrollTop(Double.MAX_VALUE);向下滚动):

public class View {
    private TextArea textArea ;

    public View() {
        textArea = new TextArea();
        // ...
    }

    public void appendStatus(String status) {
        if (!textArea.getText().isEmpty()) {
            textArea.appendText("\n");
        }
        textArea.appendText(status);
        textArea.setScrollTop(Double.MAX_VALUE);
    }
}

只要您的算法没有太快地创建太多的状态更新(这样它们会使FX应用程序线程泛滥并阻止它正常工作),这应该可以正常工作。