I have tried to follow the approach described in the article "GWT:
improving performance" -
http://techzone.enterra-inc.com/?p=25
I have classes that render different HTML "templates" and various
controls that are placed into the skeleton, much like the
FastContainer pattern described in the article.
My HTML appears intact and the controls appear as expected, but I am
unable to receive any events fired by listeners attached to these
controls.
Has anyone who has implemented the FastContainer pattern seen anything
similar to this?
I have attached a test-case that, albeit a simple version, highlights
the exact problem.
/dave
--------------------------------- 8< ---------------------------------
package com.rt.client;
import java.util.HashMap;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FocusListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class RTTest implements EntryPoint {
/**
* This is the entry point method.
*/
public void onModuleLoad() {
final Button button = new Button("Click me");
final Label label = new Label();
final TextBox textbox = new TextBox();
FlowPanel flowPanel = new FlowPanel();
if (false) {
// Change this to "true" if you want to see how straight-forward
widgets behave
flowPanel.add(button);
flowPanel.add(textbox);
}
else {
// Create a chunk of HTML and use it as the "template" for a
FlowPanel using DOM.setInnerHTML
// Create two placeholders where the controls will eventually be
inserted
String buttonID = "button";
String textboxID = "textbox";
String panelHTML = "<div id=\"" + buttonID + "\"></div><div id=\""
+ textboxID + "\"></div>";
DOM.setInnerHTML(flowPanel.getElement(),panelHTML);
// The elements are not in the DOM yet, so DOM.getElementById()
does not find them
// Instead, find all elements with an attribute id= in the newly-
created HTML
HashMap namedElements = new HashMap();
findNamedElements(flowPanel.getElement(),namedElements);
// Grab the DOM element we just found and append the control to it
Element buttonElement = (Element) namedElements.get(buttonID);
DOM.appendChild(buttonElement,button.getElement());
Element textboxElement = (Element) namedElements.get(textboxID);
DOM.appendChild(textboxElement,textbox.getElement());
}
RootPanel.get("slot1").add(flowPanel);
RootPanel.get("slot2").add(label);
// Regardless of where the listeners are added (before or after
they are added to the RootPanel)
// they do not appear to register as they do not fire when the
control is clicked on
button.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
if (label.getText().equals(""))
label.setText("Hello World!");
else
label.setText("");
}
});
textbox.addFocusListener(new FocusListener() {
public void onFocus(Widget sender) {
textbox.setText("focus");
}
public void onLostFocus(Widget sender) {
textbox.setText("lost focus");
}
});
}
// given a starting point, recursively search for elements that have
an id= attribute
protected void findNamedElements(Element element, HashMap hashMap) {
String id = DOM.getElementAttribute(element, "id");
if (id != null) {
hashMap.put(id, element);
}
Element firstChild = DOM.getFirstChild(element);
while (firstChild != null) {
findNamedElements(firstChild,hashMap);
firstChild = DOM.getNextSibling(firstChild);
}
}
}