Creating Ext GWT Extensions and Components

Preview:

DESCRIPTION

Do you have a need for custom components or behavior? This session will bring you the knowledge you require to create and extend custom components. Learn which calls to intercept for your custom logic.

Citation preview

Wednesday, November 2, 11

Sven BrunkenCUSTOM COMPONENTS

sven@sencha.com @svenbrunken

Wednesday, November 2, 11

OverviewWidget vs Component

Important methods of the Widget classWhen to use the Cell class?

Important methods of the Cell classQuestions

Wednesday, November 2, 11

Which Class To Start From?

Wednesday, November 2, 11

WidgetBuild on top of a DOM ElementListens to browser eventsNeeds to be attached and detached for event handlingDoes not solve the different sizing boxesCan fire custom events through its HandlerManager

Wednesday, November 2, 11

ComponentExtends the Widget class and so inherits all its featuresSolves the different sizing boxesCan be disabled directlyCan be positioned

Wednesday, November 2, 11

Important Methods

Wednesday, November 2, 11

sinkEvents()Defines which events can be listened toEvents not sunk cannot be listened to

public void sinkEvents(int eventBitsToAdd) { if (isOrWasAttached()) { DOM.sinkEvents(getElement(), eventBitsToAdd|DOM.getEventsSunk(getElement())); } else { eventsToSink |= eventBitsToAdd; }}

Wednesday, November 2, 11

onAttach()Removes the event listenerMandatory to enable browser event handlingAttaches the event listener of all its children widgets

protected void onAttach() { attached = true; DOM.setEventListener(getElement(), this); int bitsToAdd = eventsToSink; eventsToSink = -1; if (bitsToAdd > 0) { sinkEvents(bitsToAdd); } doAttachChildren(); onLoad(); AttachEvent.fire(this, true);}

Wednesday, November 2, 11

onDetach()Removes the event listener added from onAttach()Browser events are no longer handled for this WidgetPrevents memory leaksDetaches the event listener for all its children widgets

protected void onDetach() { try { onUnload(); AttachEvent.fire(this, false); } finally { try { doDetachChildren(); } finally { DOM.setEventListener(getElement(), null); attached = false; } }}

Wednesday, November 2, 11

fireEvent()Fires a custom event through the HandlerManagerOther classes could listen to these events

public void fireEvent(GwtEvent<?> event) { if (handlerManager != null) { handlerManager.fireEvent(event); }}

Wednesday, November 2, 11

onBrowserEvent()Only called when a Widget is attachedGets called with the browser event that occurredRefires the browser event through the HandlerManager

public void onBrowserEvent(Event event) { DomEvent.fireNativeEvent(event, this, this.getElement());}

Wednesday, November 2, 11

setElement()Sets the element for this WidgetMandatory to be calledAn Element can only be set once and not changedNeeds to be called before calling getElement()

protected void setElement(Element elem) { assert (element == null) : SETELEMENT_TWICE_ERROR; this.element = elem;}

Wednesday, November 2, 11

How To Start?

Wednesday, November 2, 11

Gathering InformationWhat is the purpose of my custom widget?Which browser events are required?Can I extend an already existing class?

Do I understand all my requirements?

Wednesday, November 2, 11

Implementation

Wednesday, November 2, 11

The ClassExtending Component to overcome different sizing models

public class SquareWidget extends Component {

}

Wednesday, November 2, 11

ConstructorSetting the ElementDefining the events we want to listen to

public SquareWidget(Data data) { this.data = data; SquareWidgetTemplate t = GWT.create(SquareWidgetTemplate.class); setElement(XDOM.create(t.render(data)));

sinkEvents(Event.ONMOUSEOVER | Event.ONMOUSEOUT | Event.ONCLICK);

setPixelSize(100, 100); }

Wednesday, November 2, 11

onBrowserEvent()Contains our event handling logicShould call the super method

@Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event);

if (event.getTypeInt() == Event.ONMOUSEOUT) { onMouseOut(event); } else if (event.getTypeInt() == Event.ONMOUSEOVER) { onMouseOver(event); } else if (event.getTypeInt() == Event.ONCLICK) { onClick(event); } }

Wednesday, November 2, 11

onMouseOver()getRelatedEventTarget returns the Element coming fromSetting the mouse over value

private void onMouseOver(Event event) { EventTarget t = event.getRelatedEventTarget(); if (t == null || Element.is(t) && !getElement().isOrHasChild(Element.as(t))) { String s = SafeHtmlUtils.fromString(data.getMouseOverName()).asString(); getContentElement().setInnerHTML(s); } }

Wednesday, November 2, 11

onMouseOut()getRelatedEventTarget returns the Element moving toClearing the background colorSetting the standard value again

private void onMouseOut(Event event) { EventTarget t = event.getRelatedEventTarget(); if (t == null || (Element.is(t) && !getElement().isOrHasChild(Element.as(t)))) { getElement().getStyle().clearBackgroundColor();

String s = SafeHtmlUtils.fromString(data.getName()).asString(); getContentElement().setInnerHTML(s); } }

Wednesday, November 2, 11

onClick()Sets the different background color

private void onClick(Event event) { getElement().getStyle().setBackgroundColor("red"); }

Wednesday, November 2, 11

Demonstration

Wednesday, November 2, 11

But, Do We Really Require a Widget?

Wednesday, November 2, 11

Introducing CellCells can handle browser eventsCells can be used in data componentsWidgets cannot be used thereCells render a lot faster

Wednesday, November 2, 11

Context of the CellContains the relevant row and column indexImportant when used in data widgetsContains the key representing the value

Wednesday, November 2, 11

Important Methods

Wednesday, November 2, 11

onBrowserEvent()Gets called when an event for this cell occurredGets passed in the parent ElementCell on its own does not know anything where it is displayedOne Cell can be displayed in many places

void onBrowserEvent(Context context, Element parent, C value, NativeEvent event, ValueUpdater<C> valueUpdater);

Wednesday, November 2, 11

render()Called when a Cell should be renderedThe output should be written to the SafeHtmlBuilder

void render(Context context, C value, SafeHtmlBuilder sb);

Wednesday, November 2, 11

getConsumedEvents()Returns the events this cell requiresCannot change in the lifecycle of a Cell

Set<String> getConsumedEvents();

Wednesday, November 2, 11

Implementation

Wednesday, November 2, 11

The ClassExtending AbstractCellImplementing the Cell interface directly works too

public class SquareCell extends AbstractCell<Data> {

}

Wednesday, November 2, 11

ConstructorDefining the events this cell listens to

public SquareCell() { super("click", "mouseover", "mouseout"); }

Wednesday, November 2, 11

onBrowserEvent()Contains our event handling logic

public void onBrowserEvent(Context context, Element parent, Data value, NativeEvent event, ValueUpdater<Data> valueUpdater) { Element t = parent.getFirstChildElement(); Element target = event.getEventTarget().cast(); if (!t.isOrHasChild(target)) { return; }

if ("mouseout".equals(event.getType())) { onMouseOut(context, parent, value, event); } else if ("mouseover".equals(event.getType())) { onMouseOver(context, parent, value, event); } else if ("click".equals(event.getType())) { onClick(context, parent, value, event); } }

Wednesday, November 2, 11

onMouseOver()getRelatedEventTarget returns the Element coming fromSetting the mouse over value

private void onMouseOver(Context context, Element parent, Data value, NativeEvent event) { Element fc = parent.getFirstChildElement(); EventTarget t = event.getRelatedEventTarget(); if (t == null || (Element.is(t) && !fc.isOrHasChild(Element.as(t)))) { String s = SafeHtmlUtils.fromString(value.getMouseOverName()).asString(); getContentElement(parent).setInnerHTML(s); } }

Wednesday, November 2, 11

onMouseOut()getRelatedEventTarget returns the Element moving toClearing the background colorSetting the standard value again

private void onMouseOut(Context context, Element parent, Data value, NativeEvent event) { Element fc = parent.getFirstChildElement(); EventTarget t = event.getRelatedEventTarget(); if (t == null || (Element.is(t) && !fc.isOrHasChild(Element.as(t)))) { fc.getStyle().clearBackgroundColor(); String s = SafeHtmlUtils.fromString(value.getName()).asString(); getContentElement(parent).setInnerHTML(s); } }

Wednesday, November 2, 11

onClick()Sets the different background color

private void onClick(Context context, Element parent, Data value, NativeEvent event) { parent.getFirstChildElement().getStyle().setBackgroundColor("red"); }

Wednesday, November 2, 11

Demonstration

Wednesday, November 2, 11

Questions

Wednesday, November 2, 11

Thank You!

Wednesday, November 2, 11