2012-05-08 3 views
2

아파치 개찰구를 사용하여 읽기 전용 콘솔 창과 같은 것을 만들려고합니다. 기본적으로 사용자는 서버 측 작업을 시작하기 위해 양식을 제출합니다. 그런 다음 페이지에서 작업 출력을 추적 할 수 있습니다. 이 솔루션개찰구로 텍스트 영역 업데이트하기

public class ConsoleExample extends WebPage { 

protected boolean refreshing; 
private String output = ""; 

public void setOutput(String newOutput) { 
    synchronized (this) { 
     output = newOutput; 
    } 
} 

public void appendOutput(String added) { 
    synchronized (this) { 
     this.output = output+added; 
    } 
} 

public ConsoleExample() { 

    Form<ConsoleExample> form = new Form<ConsoleExample>("mainform"); 
    add(form); 
     final TextArea<String> outputArea = new TextArea<String>("output", 
      new PropertyModel<String>(this, "output")); 
    outputArea.setOutputMarkupId(true); 
    // A timer event to add the outputArea to the target, triggering the refresh 
    outputArea.add(new AbstractAjaxTimerBehavior(Duration.ONE_SECOND){ 
     private static final long serialVersionUID = 1L; 
     @Override 
     protected void onTimer(AjaxRequestTarget target) { 
      synchronized (this) { 
       if(refreshing){ 
        target.focusComponent(null); 
        target.addComponent(getComponent()); 
       } 
      } 
     } 

    }); 

    add(outputArea); 

    form.add(new AjaxSubmitLink("run") { 
     private static final long serialVersionUID = 1L; 

     @Override 
     public void onSubmit(final AjaxRequestTarget target, Form<?> form) { 
      setOutput(""); 
      new Thread(new Runnable() { 
       @Override 
       public void run() { 
        try { 
         refreshing = true; 
         ProcessBuilder pb = new ProcessBuilder(Collections.singletonList("execute")); 
         pb.redirectErrorStream(true); 
         String line; 
         BufferedReader br = new BufferedReader(new InputStreamReader(pb.start().getInputStream())); 
         while ((line = br.readLine()) != null) { 
          appendOutput("\n" + line); 
         } 
        } catch (IOException e) { 
         //... 
        } finally { 
         //... 
         refreshing = false; 
        } 
       } 
      }).start(); 
     } 
    }); 
} 

문제는 때마다 AjaxTimerBehaviorRuns 새로 고침가 텍스트 영역의 속성, 즉, 커서의 위치를 ​​재설정하고 위치를 이동한다는 것입니다 : 아래 그림과 같이

나는 현재 출력을 표시하고 있습니다. 따라서 출력이 늘어남에 따라 텍스트 영역이 매초마다 시작으로 점프하므로 사용자가 출력을 추적 할 수 없습니다.

더 좋은 방법이 있나요?

+0

난 당신이 그것을 새로 고친 후 텍스트보기를 아래로 스크롤 동작에 자바 스크립트 함수를 추가 할 수있을 것 같아요. 나는 마음으로 그렇게하는 법을 모른다. 그래서 나는 대답으로 게시하지 않았다. –

답변

0

부분 해결 난 그냥 새로운 텍스트를 추가하는 자바 스크립트의 비트를 추가하고있는 appendJavaScript() 함수를 사용 jordeu의 제안에 이어 마지막 업데이트.

스크롤 문제는 해결되지만 사용자 선택은 여전히 ​​재설정됩니다. 또한 나에게 "좋은"해결책처럼 보이지 않습니다.

개선 방법에 대한 제안 사항은 언제든지 환영합니다.

0

추적 할 수없는 가망 구현하기 쉬운 방법은 당신이 AjaxTimerBehavior에 던져 AJAX를 업데이트 숨겨진 TextField을 추가하는 것입니다 다음 <textarea>에 숨겨진 TextField의 값을 동기화하는 자바 스크립트 함수 (AjaxRequestTarget.appendJavaScript()를 사용)를 호출합니다.

protected void onTimer(AjaxRequestTarget target) { 
    synchronized (this) { 
     if(refreshing){ 
      if(update != null){ 
       target.appendJavascript("var obj=document.getElementById(\"output\");var txt=document.createTextNode(\""+update+"\");obj.appendChild(txt)"); 
       update = null; 
      } 
     } 
    } 
} 

update 필드는 이후 새로운 텍스트입니다 :

+0

흥미로운 솔루션입니다. 나는 약간의 동기화 문제를 다루는 방법에 관심이 있지만 나는 그것을 줄 것이다. – Jim