A "virtual terminal" with vaadin

I assume you know PuTTY. I have to write a similar widget; a console that prints the output of a process and writes to the standard input of this process.
I may come up with some different questions, I’ll put them in here.
There are several thoughts in my mind, but it’s hard for me to write them down (especially in english). I’d like to hear your thoughts :slight_smile:

The first one is:
My “terminal” should only display the latest e.g. 100 lines. The output must be appended line per line. The code for this would be like the following:

  private ArrayList<String> scrollback = new ArrayList<String>( 100 );

  public void appendString( String string ) {
    while ( scrollback.size() >= 100 )
      scrollback.remove( 0 );
    scrollback.add( string );
  }

Obviously, I don’t want to send whole “scrollback” to the client each time. And I don’t think that vaadin would just send the changes, does it?
I think I have to create a custom component that implement this logic at the client’s side.

The next problem is:
I think on the client side, I have to poll the strings from the server. Or is there a way to push the strings to the client? I know some users
asked the same
but maybe something has changed since 6.0?

Or is there be a possibility to put through the InputSream directly to the client? I hope you got me :slight_smile:

How would you proceed? If you have any ideas or see some problems, please write.

Writing a full terminal emulator (like PuTTY) could be quite challenging task to do, but if no keyboard input or VT100 emulation is requires, the task is simplified a lot.

If the terminal is just adding rows to the end and does not handle keyboard input, you could simply add new rows as labels to VerticalLayout. Vaadin only sends the changed/added lines as well as layout info to the browser. Layout info would be list of 100 labels (without their contents). Would this be efficient enough in your application?

A more sophisticated approach would be to create a new widget that caches received lines on client-side and server only paints the new lines added after previous paint() call. When the widget is first shown on screen, it could request all 100 most recent lines from server by setting some “allLines=true” variable.

There is no push mechanism yet, but if you want to experiment and you are writing your own widget in any case, you could pass the contents to terminal using Kaazing (http://www.kaazing.com/).

I had testcase for something similiar in my workbench.

If you do it with server side components only, notice that GridLayout might have more flexible api for that purpose.

Example


public class GridTest extends Application {
        private int rowIndex = 0;

	@Override
	public void init() {
		Window w = new Window("test");

		final GridLayout gl = new GridLayout() {
			@Override
			public void addComponent(Component component) {
				if (getRows() > 100) {
					removeRow(0);
				}
				super.addComponent(component);
			}
		};

		for (; rowIndex < 100; rowIndex++) {
			gl.addComponent(new Label("test" + rowIndex));
		}

		Button b = new Button("test", new Button.ClickListener() {

			public void buttonClick(ClickEvent event) {

				gl.addComponent(new Label("test" + (rowIndex++)));
			}

		});
		w.addComponent(gl);
		w.addComponent(b);
		setMainWindow(w);
	}

Thank you both, I’m already getting closer!

Ok there’s an endless InputStream on the server side now, that I have to read to update my “console output”. As there’s no push, i have to poll. But how to poll? I read
something about an ProgressBar hack
, but don’t know how to do that.

Or is that the point where i have to write a custom component, that calls a getConsoleOutput() frequently?

Just add the progressbar on screen - it’ll take care of polling automatically.

You could also use this one: http://vaadin.com/forum/-/message_boards/message/46688