我正在尝试使用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刷新时都会重置文本区域属性,即光标位置和滚动位置。 因此,随着输出增加,用户无法跟踪输出,因为textarea会跳回到每秒开始。
有没有更好的方法来实现这一目标?
答案 0 :(得分:0)
一个易于实现的易于实现的方法是添加一个隐藏的TextField
,您使用AjaxTimerBehavior
更新抛出AJAX,然后调用同步值的JavaScript函数(使用AjaxRequestTarget.appendJavaScript()
)隐藏TextField
与您的<textarea>
。
答案 1 :(得分:0)
部分解决方案 继jordeu建议使用appendJavaScript()函数后,我只是添加了一些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
字段是自上次更新以来的任何新文本。
这解决了滚动问题,但仍然重置了任何用户选择。 它也不像是一个很好的&#34;我的解决方案。
欢迎任何有关如何改进的进一步建议。