2017-03-17 15 views
1

私はプロセスを作成し、stdoutをテキスト領域にストリームするビルドとアプリケーションです。端末エミュレータと同じように、プロセスに行が多すぎると出力が自動的にコンソールの最後までスクロールするようにします。自動スクロールを使用したJava FXテキスト領域へのストリーム出力

問題は、テキスト領域がテキストの最後までスクロールせず、上部に留まることです。別の変わった動作は、マウスホイール/キーボード/スクロールバーを使用してテキスト領域をスクロールしようとすると、テキスト領域が非常に上にスクロールします。

回答はすでにherehere、およびhereです。私は他のどこかで何かが間違っているようです。

ここには、方法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 
+0

投稿する[MCVE] – c0der

答えて

1

全てTask.call()方法の第一は、このメソッドでは、現在のビューのいずれかの状態を変更することは不適切である、JavaFXのアプリケーションスレッドで実行ありません。あなたは間違ったスレッドでconsoleTextArea""を追加しています。

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

第二の問題は、あなたがTaskメッセージプロパティtextProperty.bind(bgTask.messageProperty());にconsoleTextAreaテキストプロパティをバインドするためconsoleTextArea.appendText("");を起動すると、(実際には、それは何もしません)あなたのChangeListenerを誘発しないということです:あなたはこのようにそれを行う必要があります。その場合、テキスト領域はTaskメッセージプロパティのテキスト変更のみを聴きます。リスナーをメッセージプロパティに追加します。

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

    // also tried: 
    // consoleTextArea.setScrollTop(Double.MAX); 
}); 
関連する問題