I’m attempting to create something like a read-only console window using apache wicket.
Essentially the users submits a form to kick off a server-side operation. Then can then track the job output on the page.
I’m currently displaying the output as shown below:
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();
}
});
}
The problem with this solution is that each time the AjaxTimerBehaviorRuns the refresh resets the text area properties, namely, cursor position and scroll position.
Therefore as the output increases the user can’t track the output as the textarea jumps back to start every second.
Is there a better way to achieve this?
Partial Solution
Following on from jordeu’s suggestion of using the appendJavaScript() function I am just adding a bit of javascript to append the new text:
Where the
updatefield is any new text since the last update.This solves the scroll issue but any user selection is still reset.
Also it doesn’t seem like a “nice” solution to me.
Any further suggestions of how to improve are welcome.