【问题标题】:Stream Process Output to Java FX Text Area with Auto Scroll使用自动滚动流式处理输出到 Javafx Textarea
【发布时间】:2017-08-08 12:10:06
【问题描述】:

我正在构建一个应用程序来创建一个进程,并将其标准输出流式传输到 文本区域。就像终端模拟器一样,如果进程显示太多行,我希望输出自动滚动到控制台的末尾。

问题是文本区域不会滚动到文本的末尾,而是停留在顶部。另一个奇怪的行为是当我尝试使用鼠标滚轮/键盘/滚动条滚动文本区域时,文本区域滚动到最顶部。

我已经尝试了hereherehere 的答案。好像我在其他地方有问题。

这里是方法 void streamToTextArea(java.lang.Process process) 的内容 - 在执行流程并将其流式传输到 consoleTextArea 时完成繁重工作的方法。

Task bgTask = new Task<Void>() {
    @Override
    protected void call() throws Exception {
        InputStream inputStream = process.getInputStream();
        StringBuilder consoleContent = new StringBuilder();

       try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
           String line;
           while((line = reader.readLine()) != null) {
               consoleContent
                   .append(line)
                   .append("\n");
               updateMessage(consoleContent.toString());
               consoleTextArea.appendText(""); // trigger ChangeListener
           }
       } catch (IOException e) { doSomething(e); }
       return null;
    }
};

StringProperty textProperty = consoleTextArea.textProperty();
textProperty.addListener((observable, oldValue, newValue) -> {
    // currently:
    consoleTextArea.selectPositionCaret(consoleTextArea.getLength());
    consoleTextArea.deselect();

    // also tried:
    // consoleTextArea.setScrollTop(Double.MAX);
});
textProperty.bind(bgTask.messageProperty());

// start bgTask as daemon thread
// add event handling when bgTask ended

【问题讨论】:

标签: javafx java javafx process javafx-8 daemon


【解决方案1】:

首先Task.call() 方法在JavaFX 应用程序线程中执行,因此在此方法中更改当前视图的任何状态都是不合适的。您在错误的线程中将"" 添加到consoleTextArea。你应该这样做:

Platform.runLater(() -> {
    consoleTextArea.appendText("");
});

第二个问题是调用consoleTextArea.appendText(""); 不会触发你的ChangeListener(实际上它什么也不会做),因为你将consoleTextArea 文本属性绑定到Task 消息属性textProperty.bind(bgTask.messageProperty());。在这种情况下,文本区域将只收听Task 消息属性中的文本更改。将您的侦听器添加到消息属性:

bgTask.messageProperty().addListener((observable, oldValue, newValue) -> {
    // currently:
    consoleTextArea.selectPositionCaret(consoleTextArea.getLength());
    consoleTextArea.deselect();

    // also tried:
    // consoleTextArea.setScrollTop(Double.MAX);
});

【讨论】:

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