<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>GWT Brasil &#187; image bundle</title>
	<atom:link href="http://www.gwt.com.br/tag/imagebundle/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gwt.com.br</link>
	<description>Grupo de usuários do GWT no Brasil</description>
	<lastBuildDate>Sat, 10 Oct 2009 03:37:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.3</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Utilizando um ImageBundle</title>
		<link>http://www.gwt.com.br/2008/09/08/utilizando-um-imagebundle/</link>
		<comments>http://www.gwt.com.br/2008/09/08/utilizando-um-imagebundle/#comments</comments>
		<pubDate>Tue, 09 Sep 2008 00:28:35 +0000</pubDate>
		<dc:creator>Marcelo Emanoel</dc:creator>
				<category><![CDATA[Básico]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[deferred binding]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[image bundle]]></category>

		<guid isPermaLink="false">http://www.gwt.com.br/2008/09/08/utilizando-um-imagebundle/</guid>
		<description><![CDATA[Se algum dia você já se deparou com a seguinte situação: criar uma aplicação em web que possua diversas imagens estáticas (por exemplo í­cones) e você utilizou css para selecionar e carregar as imagens&#8230; você já deve ter percebido que para cada imagem da aplicação uma nova conexão é aberta só para buscar essa imagem&#8230; [...]]]></description>
			<content:encoded><![CDATA[<p>Se algum dia você já se deparou com a seguinte situação: criar uma aplicação em web que possua diversas imagens estáticas (por exemplo í­cones) e você utilizou css para selecionar e carregar as imagens&#8230; você já deve ter percebido que para cada imagem da aplicação uma nova conexão é aberta só para buscar essa imagem&#8230; e as demais só serão carregadas uma após a outra&#8230; pois é&#8230; para essa situação nada melhor que um ImageBundle! Para aqueles que ainda não conhecem essa funcionalidade vou dar uma pequena e rápida introdução. Confiram após o break <img src='http://www.gwt.com.br/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><span id="more-61"></span></p>
<p>Um ImageBundle é um objeto que automaticamente pega todos os í­cones mensionados anteriormente e os une em uma única imagem fazendo com que n requests ao servidor sejam condensadas em UMA ÚNICA!!! Além disso as imagens são &#8220;recortadas&#8221; depois tornando transparente ao usuário que se trata de uma mesma imagem. O procedimento de &#8220;recortar&#8221; novamente a figura depois de carregada é conhecido como &#8220;clipping&#8221; e é implementado através de CSS. </p>
<p>Parece complicado não é? Pois é&#8230; pode até parecer&#8230; mas utilizando GWT isso fica fácil fácil&#8230; e com algumas linhas de código tudo isso é rapidamente desenvolvido sem dores de cabeça e de maneira transparente ao programador!!!!! Isso é possí­vel graças ao mecanismo batizado de Deferred Binding do GWT que fornece pontos de extensção ao framework. Em um próximo tópico explicarei como o Deferred Binding funciona e o que você pode fazer com essa funcionalidade. </p>
<p>Voltando ao ImageBundle&#8230;.</p>
<p>Tudo que vocÃª precisarÃ¡ para a utlizaÃ§Ã£o de um ImageBundle Ã© implementar uma interface que extende ImageBundle e criar mÃ©todos que retornam um object <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/1.5/com/google/gwt/user/client/ui/AbstractImagePrototype.html">AbstractImagePrototype</a> esse mÃ©todo deve conter anotaÃ§Ãµes especificando quais recursos (leia-se imagens) devem ser carregados pelo compilador. O objeto AbstractImagePrototype possui um mÃ©todo muito Ãºtil que Ã© o createImage() que retorna nada mais nada menos que a imagem que precisamos! Dito isso chega de conversa fiada e vamos ao cÃ³digo <img src='http://www.gwt.com.br/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Para exemplificar a tÃ©cnica vamos construir um componente bastante usado em aplicaÃ§Ãµes desktop, uma ToolBar. Como se sabe em uma ToolBar Ã© muito comum o uso de Ã­cones representando ferramentas ou funcionalidades do software. Ã‰ nesse momento que o ImageBundle entra em cena. Para a criaÃ§Ã£o do exemplo vou ilustrar uma ToolBar com e sem ImageBundle. Para verificar o nÃºmero de conexÃµes geradas para buscar a imagem utilizaremos o firebug, extensÃ£o do firefox que facilita e muito a vida dos desenvolvedores web. </p>
<p>As imagens utilizadas no exemplo bem como o cÃ³digo fonte estÃ£o disponÃ­veis no final do post em arquivos zip.</p>
<p>Inicialmente a classe que representa o componente ToolBar:</p>
<p>[java]<br />
package br.com.gwt.client.toolbar;</p>
<p>import com.google.gwt.user.client.ui.Composite;<br />
import com.google.gwt.user.client.ui.FlexTable;<br />
import com.google.gwt.user.client.ui.ButtonBase;<br />
import com.google.gwt.user.client.ui.SimplePanel;</p>
<p>/**<br />
 * Uma ToolBar nada mais Ã© senÃ£o um painel com botÃµes que representam aÃ§Ãµes ou<br />
 * funcionalidades de um sistema. Geralmente os botÃµes da toolbar utilizam Ã­cones<br />
 * em vez de textos, entretanto esse detalhe nÃ£o serÃ¡ tratado nessa classe.<br />
 *<br />
 * @author Marcelo Emanoel<br />
 */<br />
public class ToolBar extends Composite {<br />
	private FlexTable toolbarTable;<br />
	private int buttonCount;</p>
<p>	public ToolBar(){<br />
		init();<br />
		setupStyles();<br />
	}</p>
<p>	/**<br />
	 * InicializaÃ§Ãµes<br />
	 */<br />
	private void init() {<br />
		toolbarTable = new FlexTable();<br />
		buttonCount = 0;</p>
<p>		SimplePanel panel = new SimplePanel();<br />
		panel.add(toolbarTable);</p>
<p>		initWidget(panel);<br />
	}</p>
<p>	/**<br />
	 * Adiciona um botÃ£o Ã  ToolBar.<br />
	 * @param button<br />
	 */<br />
	public void addButton(ButtonBase button){<br />
		toolbarTable.setWidget(0, buttonCount++, button);<br />
	}</p>
<p>	/**<br />
	 * Seta os estilos dos componentes internos e da ToolBar.<br />
	 */<br />
	private void setupStyles() {<br />
		setStylePrimaryName(&#8221;br_com_gwt_ToolBar&#8221;);<br />
		toolbarTable.setStylePrimaryName(&#8221;br_com_gwt_ToolBar&#8221;);<br />
	}<br />
	/**<br />
	 * Retorna o nÃºmero de botÃµes existentes na ToolBar.<br />
	 * @return<br />
	 */<br />
	public int getButtonCount() {<br />
		return buttonCount;<br />
	}<br />
}<br />
[/java]</p>
<p>AtÃ© aqui acredito que nÃ£o temos muitas surpresas. A ToolBar Ã© composta por uma FlexTable e botÃµes adicionados a ela. AlÃ©m disso Ã© possÃ­vel contar quantos botÃµes foram inseridos. </p>
<p>Agora vamos verificar como foi feito o ImageBundle.</p>
<p>[java]/**<br />
 *<br />
 */<br />
package br.com.gwt.client.toolbar.imagebundle;</p>
<p>import com.google.gwt.user.client.ui.AbstractImagePrototype;<br />
import com.google.gwt.user.client.ui.ImageBundle;</p>
<p>/**<br />
 * BlogBundle contÃ©m imagens relacionadas Ã  atividades de um blog. Adicionar,<br />
 * remover, inserir videos bem como configurar alguma coisa no blog.<br />
 *<br />
 * As imagens foram retiradas do <a href="http://www.iconspedia.com/">IconsPedia</a>. Todos os direitos reservados.<br />
 * @author Marcelo Emanoel<br />
 */<br />
public interface BlogBundle extends ImageBundle {</p>
<p>	/**<br />
	 * Imagem de adicÃ£o.<br />
	 * @return<br />
	 */<br />
	@Resource(&#8221;br/com/gwt/resources/add.png&#8221;)<br />
	public AbstractImagePrototype add();</p>
<p>	/**<br />
	 * Imagem de remoÃ§Ã£o.<br />
	 * @return<br />
	 */<br />
	@Resource(&#8221;br/com/gwt/resources/remove.png&#8221;)<br />
	public AbstractImagePrototype remove();</p>
<p>	/**<br />
	 * Imagem de video.<br />
	 * @return<br />
	 */<br />
	@Resource(&#8221;br/com/gwt/resources/video.png&#8221;)<br />
	public AbstractImagePrototype video();</p>
<p>	/**<br />
	 * Imagem de configuraÃ§Ã£o.<br />
	 * @return<br />
	 */<br />
	@Resource(&#8221;br/com/gwt/resources/settings.png&#8221;)<br />
	public AbstractImagePrototype settings();</p>
<p>	/**<br />
	 * Imagem de ok.<br />
	 * @return<br />
	 */<br />
	@Resource(&#8221;br/com/gwt/resources/check.png&#8221;)<br />
	public AbstractImagePrototype check();<br />
}[/java]</p>
<p>Finalmente como utilizar o ImageBundle e a ToolBar juntos.</p>
<p>[java]package br.com.gwt.client;</p>
<p>import br.com.gwt.client.toolbar.ToolBar;<br />
import br.com.gwt.client.toolbar.imagebundle.BlogBundle;</p>
<p>import com.google.gwt.core.client.EntryPoint;<br />
import com.google.gwt.core.client.GWT;<br />
import com.google.gwt.user.client.Window;<br />
import com.google.gwt.user.client.ui.Button;<br />
import com.google.gwt.user.client.ui.ClickListener;<br />
import com.google.gwt.user.client.ui.DockPanel;<br />
import com.google.gwt.user.client.ui.HTML;<br />
import com.google.gwt.user.client.ui.Image;<br />
import com.google.gwt.user.client.ui.PushButton;<br />
import com.google.gwt.user.client.ui.RootPanel;<br />
import com.google.gwt.user.client.ui.Widget;</p>
<p>/**<br />
 * Entry point classes define <code>onModuleLoad()</code>.<br />
 */<br />
public class ImageBundleTest implements EntryPoint {</p>
<p>	/**<br />
	 * This is the entry point method.<br />
	 * Instancia duas ToolBars uma com as imagens adquiridas via ImageBundle e a<br />
	 * outra criada com imagens extraÃ­das por css.<br />
	 *<br />
	 *  O intuito Ã© verificar o nÃºmero de conexÃµes extras causadas pela ausÃªncia<br />
	 *  do ImageBundle.<br />
	 */<br />
	public void onModuleLoad() {<br />
		/**<br />
		 * Instancia-se o ImageBundle via Deferred Binding.<br />
		 */<br />
		BlogBundle blogBundle = GWT.create(BlogBundle.class);</p>
<p>		ToolBar blogTools = new ToolBar();<br />
		ToolBar dbTools = new ToolBar();</p>
<p>		DockPanel dock = new DockPanel();<br />
		RootPanel.get().add(dock);</p>
<p>		dock.setStylePrimaryName(&#8221;dock&#8221;);</p>
<p>		HTML center = new HTML();<br />
		dock.add(center, DockPanel.CENTER);<br />
		dock.setCellHeight(center, &#8220;100%&#8221;);</p>
<p>		/*<br />
		 * Instancia todas as imagens do ToolBar que usa ImageBundle.<br />
		 */<br />
		Image addImg = blogBundle.add().createImage();<br />
		Image removeImg = blogBundle.remove().createImage();<br />
		Image checkImg = blogBundle.check().createImage();<br />
		Image settingsImg = blogBundle.settings().createImage();</p>
<p>		blogTools.addButton(createButton(addImg, blogTools.getButtonCount()));<br />
		blogTools.addButton(createButton(removeImg, blogTools.getButtonCount()));<br />
		blogTools.addButton(createButton(checkImg, blogTools.getButtonCount()));<br />
		blogTools.addButton(createButton(settingsImg, blogTools.getButtonCount()));</p>
<p>		dbTools.addButton(createEmptyButton(dbTools.getButtonCount(),&#8221;feather&#8221;));<br />
		dbTools.addButton(createEmptyButton(dbTools.getButtonCount(), &#8220;db&#8221;));</p>
<p>		dock.add(blogTools, DockPanel.NORTH);<br />
		dock.add(dbTools, DockPanel.SOUTH);<br />
	}</p>
<p>	/**<br />
	 * MÃ©todo de fÃ¡brica. Cria botÃµes a partir de uma posiÃ§Ã£o e o nome do estilo<br />
	 * que deverÃ¡ ser atribuÃ­do ao botÃ£o.<br />
	 * @param pos<br />
	 * @param id<br />
	 * @return<br />
	 */<br />
	public Button createEmptyButton(int pos, String id){<br />
		Button simpleButton = new Button();<br />
		simpleButton.setTitle(pos+&#8221;");<br />
		simpleButton.setStylePrimaryName(id);<br />
		simpleButton.addClickListener(new ClickListener() {<br />
			public void onClick(Widget sender) {<br />
				Window.alert(sender.getTitle());<br />
			}<br />
		});<br />
		return simpleButton;<br />
	}</p>
<p>	/**<br />
	 * MÃ©todo de fÃ¡brica. Cria botÃµes a partir de uma imagem e uma posiÃ§Ã£o.<br />
	 * @param icon<br />
	 * @param pos<br />
	 * @return<br />
	 */<br />
	public PushButton createButton(Image icon, int pos){<br />
		PushButton pushButton = new PushButton(icon);<br />
		pushButton.setTitle(pos+&#8221;");<br />
		pushButton.addClickListener(new ClickListener() {<br />
			public void onClick(Widget sender) {<br />
				Window.alert(sender.getTitle());<br />
			}<br />
		});<br />
		return pushButton;<br />
	}<br />
}<br />
[/java]</p>
<p>Agora vejamos o que o firebug nos diz a respeito das toolbars criadas e suas imagens via css e imageBundle.</p>
<div style="text-align: center;">
<div class="imageframe imgaligncenter" style="width:200px;"><a href="http://www.gwt.com.br/wp-content/uploads/2008/09/imagebundle.jpg" rel="lightbox[pics61]" title="ComparaÃ§Ã£o ImageBundle"><img src="http://www.gwt.com.br/wp-content/uploads/2008/09/imagebundle.thumbnail.jpg" width="200" height="46" alt="ComparaÃ§Ã£o ImageBundle" /></a>
<div class="imagecaption">ComparaÃ§Ã£o ImageBundle</div>
</div>
</div>
<p>Como pode se observar com uma Ãºnica requisiÃ§Ã£o feita atravÃ©s do imageBundle, quatro imagens foram trazidas atÃ© o cliente, e podem ser colocadas em cache tranquilamente (O nome &#8220;maluco&#8221; do arquivo Ã© um nÃºmero hash). Enquanto isso, para cada imagem setada atravÃ©s de css Ã© feita uma nova requisiÃ§Ã£o ao servidor, consumindo tempo e banda do usuÃ¡rio. </p>
<p>As vantagens do uso de ImageBundle sÃ£o claras em relaÃ§Ã£o ao carregamento de imagens via CSS. AlÃ©m disso, uma outra utilidade dos ImageBundle&#8217;s que nÃ£o foi citada no texto Ã© o uso de internacionalizaÃ§Ã£o de imagens. Mas esse Ã© assunto para um prÃ³ximo post. Espero que tenham gostado. A seguir um arquivo zip com o projeto desenvolvido.</p>
<p><a href="http://w13.easy-share.com/1701504890.html" title="imagebundletest.zip">imagebundletest.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gwt.com.br/2008/09/08/utilizando-um-imagebundle/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
