2017-03-17 8 views
1

저는 프로세스를 생성하고 그 stdout을 텍스트 영역으로 스트리밍하는 응용 프로그램입니다. 터미널 에뮬레이터와 마찬가지로 프로세스에 너무 많은 행이 표시되면 출력이 콘솔의 끝까지 자동으로 스크롤되기를 원합니다.자동 스크롤을 사용하여 Java FX 텍스트 영역으로 프로세스 출력을 스트림

문제는 텍스트 영역이 텍스트의 끝으로 스크롤하지 않고 맨 위에 머무르는 것입니다. 또 다른 이상한 행동은 마우스 휠/키보드/스크롤 막대를 사용하여 텍스트 영역을 스크롤하려고 할 때 텍스트 영역이 맨 위에 스크롤됩니다.

이미 답변을 시도한 here, herehere입니다. 내가 다른 곳에서 뭔가 잘못한 것 같다.

다음은 내용의 예입니다. void streamToTextArea(java.lang.Process process) - 프로세스를 실행하고 consoleTextArea으로 스트리밍 할 때 과도한 작업을 수행하는 방법입니다. 모든 Task.call() 방법

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

우선하므로이 방법에서는 현재 뷰 중 하나의 상태를 부적절 변경 자바 FX 애플리케이션 쓰레드로 실행되지 이다. 틀린 실에 ""consoleTextArea을 추가하고 있습니다. 당신은 이런 식으로 그것을 수행해야합니다

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

두 번째 문제는 consoleTextArea.appendText("");를 호출하는 트리거되지 것입니다 귀하의 ChangeListener 당신이 Task 메시지 속성 textProperty.bind(bgTask.messageProperty());에 consoleTextArea 텍스트 속성을 결합하기 때문에, (사실, 아무것도하지 않을 것이다). 이 경우 텍스트 영역은 Task 메시지 속성의 텍스트 변경 내용 만 수신합니다. 수신기에 메시지 속성을 추가하십시오.

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

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