【问题标题】:JavaFX: Autoscroll of TextArea with appendText but without ListenersJavaFX:使用 appendText 但没有侦听器的 TextArea 自动滚动
【发布时间】:2016-07-29 18:43:21
【问题描述】:

我已阅读有关此主题的 Stackoverflow 上的其他文章。但没有一个完全符合我的问题。

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

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

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

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

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

如果能得到一些帮助,我将不胜感激。

【问题讨论】:

    标签: multithreading javafx textarea appendtext


    【解决方案1】:

    如果没有(很多)更多信息,几乎不可能完全回答您的问题,但我会使用的一般方法是让算法有一个回调来处理消息,可以通过每个步骤调用算法。从控制器,传递一个回调的实现,在 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 应用程序线程并阻止其正常工作),这应该可以工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-08
      相关资源
      最近更新 更多