2012-05-08 17 views
2

私はApache Wicketを使用して読み取り専用のコンソールウィンドウのようなものを作成しようとしています。 基本的に、ユーザーはサーバー側の操作を開始するためのフォームを送信します。その後、ページ上のジョブ出力を追跡できます。wicketでテキストエリアを更新する

以下に示すように、私は現在、出力を表示しています:

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はリフレッシュがテキストエリアの特性、すなわち、カーソル位置とスクロール位置をリセットしますということです。 したがって、出力が増加するにつれて、テキストエリアが1秒おきに戻るようにジャンプするので、ユーザーは出力を追跡できません。

これを達成するより良い方法はありますか?

+0

JavaScriptの機能をリフレッシュした後、テキストビューをすべてスクロールダウンするという振る舞いにJavaScript関数を追加できます。私は心からそれを行う方法を知らないので、私は答えとして投稿していないのです。興味深い解決策。 –

答えて

0

部分的な解決策 私はちょうど新しいテキストを追加するためのjavascriptのビットを追加していappendJavaScript()関数を使用してのjordeuの提案に続いて最後の更新。

これはスクロールの問題を解決しますが、ユーザーの選択はまだリセットされています。 また、それは私にとって「良い」解決策のようには見えません。

どのように改善するかについてのご意見は歓迎します。

0

かのう実装が容易なアプローチは、あなたがAjaxTimerBehaviorとスローAJAXを更新隠さTextFieldを追加することで、その後、あなたの<textarea>と隠されたTextFieldの値を同期化するJavaScript関数(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