2

apache 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 が更新されるたびに、テキスト領域のプロパティ、つまりカーソル位置とスクロール位置がリセットされることです。したがって、出力が増加すると、テキストエリアが毎秒ジャンプして最初に戻るため、ユーザーは出力を追跡できません。

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

4

2 に答える 2

0

部分的な解決策appendJavaScript()関数を使用するというjordeuの提案に続いて、新しいテキストを追加するためにjavascriptを少し追加しています。

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は、最後の更新以降の新しいテキストです。

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

改善する方法についてのさらなる提案は大歓迎です。

于 2012-05-09T10:35:49.620 に答える
0

実装が簡単な方法として考えられるのは、TextFieldスロー AJAX を で更新する隠しオブジェクトを追加してから、隠しオブジェクトの値を と同期AjaxTimerBehaviorする JavaScript 関数を ( を使用して) 呼び出すことです。 AjaxRequestTarget.appendJavaScript()TextField<textarea>

于 2012-05-08T19:25:24.103 に答える