V jak Vaadin – własne komponenty cz.2

Wiemy już jak utworzyć komponent Vaadin w Vaadin oraz jak wpiąć komponent GWT do aplikacji Vaadni. Czas przyjrzeć się trochę bardziej skomplikowanemu procesowi czyli wpięciu komponentu GWT i komunikacji z nim.

Jeszcze raz komponent GWT i wpinanie go do aplikacji

Będzie w dużym skrócie. Sam kod komponentu GWT:

Listing 1. Komponent GWT

package pl.koziolekweb.vaadin.gwt.client.ui;

import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;

public class MyComponentGWT extends Composite {
	
	protected String random;

	protected Label label = new Label();

	private VerticalPanel panel = new VerticalPanel();

	public MyComponentGWT() {
		panel.add(new Label("GWT: "));
		panel.add(label);
		initWidget(panel);
	}

	protected void setRandom(String text) {
		label.setText(text);
   };
}

Następnie v-komponent, czyli rozszerzenie w komponentu GWT w Vaadin:

Listing 2. v-komponent

package pl.koziolekweb.vaadin.gwt.client.ui;

import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.UIDL;

public class VMyComponentGWT extends MyComponentGWT implements Paintable {

	private ApplicationConnection client;
	private String uidlId;

	public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
		if (client.updateComponent(this, uidl, true)) {
			return;
		}
		this.client = client;
		uidlId = uidl.getId();
		setRandom(uidl.getStringVariable("random"));
	}

	@Override
	protected void setRandom(String text) {
		super.setRandom(text);
		if (uidlId == null || client == null) {
			return;
		}
		client.updateVariable(uidlId, "random", text, true);
	}

}

Tu pierwsze różnice w porównaniu ze zwykłym wpinaniem bez komunikacji. Po pierwsze metoda updateFromUIDL uzyskała „ciało”. W ciele tym pobieramy informacje o id komponentu oraz o aplikacji. Następnie aktualizujemy komponent, ale… nie wywołujemy super.setRandom() tylko samo setRandom(), które najpierw aktualizuje właściwy komponent GWT, a następnie aktualizuje stan zmiennej random. Po co to? Jak pamiętamy Vaadin jest tak naprawdę implementacją terminala webowego, dla aplikacji, której cały stan „dzieje się” po stronie serwera. Należy zatem samodzielnie serializować i deserializować dane z serwera po stronie klienta… czyli w v-komponencie.
Skoro już o serwerze mowa to jest jeszcze komponent serwerowy:

Listing 3. Komponent po stronie serwera

package pl.koziolekweb.vaadin;

import java.util.Map;

import pl.koziolekweb.vaadin.gwt.client.ui.VMyComponentGWT;

import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.ui.AbstractField;
import com.vaadin.ui.ClientWidget;

@SuppressWarnings("serial")
@ClientWidget(VMyComponentGWT.class)
public class MyComponentGWTProxy extends AbstractField {

	private String random = "";

	public MyComponentGWTProxy() {
		super();
		setValue(new String("0"));
	}

	@Override
	public void changeVariables(Object source, Map variables) {
		if (variables.containsKey("random") && !isReadOnly()) {
			final String newValue = (String) variables.get("random");
			setValue(newValue, true);
		}
	}

	@Override
	public void paintContent(PaintTarget target) throws PaintException {
		super.paintContent(target);
		target.addVariable(this, "random", getRandom());
	}

	public String getRandom() {
		return random;
	}

	public void setRandom(String random) {
		this.random = random;
		setValue(random);
	}

	@Override
	public Class getType() {
		return String.class;
	}
}

W tym przypadku jest to serializacja i deserializacja danych po stronie serwera. Opiera się ona o dwie metody paintContent() i changeVariables. Pierwsza z nich pozwala na wysyłanie do klienta nowych zmiennych, druga na ich odbiór i utrwalenie po stronie serwera.

Proste 🙂

Napisz odpowiedź

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax