Zkoss - componente listbox(listitem)

Bom dia a todos!
Eu não consigo recuperar os valores digitados no componente listitem, ele está me retornando o número de itens corretamente, no exemplo abaixo foram digitados 2 itens, porém o formato que está vindo é o seguinte:

[<Listitem z_lt_l1>, <Listitem z_lt_u1>]

O código é o seguinte:
Captura o valor digitado pelo usuário e envia para o listbox.

package br.com.semente.xxx.MenuPopUp;
import org.zkoss.zul.Label;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listitem;

@SuppressWarnings("serial")
public class ExpandingMenuItemRows extends Listbox{
	 public void addEmails(String email){
		 Label strEmail = new Label();
		 strEmail.setValue(email);
		 
		 Listitem listitem = new Listitem();
		 Listcell strEmailList = new Listcell(); 		 
		 
		 strEmailList.appendChild(strEmail);
		 
		 listitem.appendChild(strEmailList);		 
		 this.appendChild(listitem);
	 }

O resultado do método addEmails preenche o listitem, abaixo do listhead.

&lt;listbox id="rowsEmails" use="br.com.semente.xxx.testes.MenuPopUp.ExpandingMenuItemRows"&gt; &lt;listhead &gt; &lt;listheader label="Email" width="auto"/&gt; &lt;/listhead&gt; &lt;/listbox&gt;

E aqui eu estou tentando capturar os valores digitados, só que está me retornando o número de registros num formato estranho (acima em negrito), talvez esteja faltando algum tipo de conversão.

&lt;button id="btnGravar" label="Inserir"&gt; &lt;attribute name="onClick"&gt; &lt;![CDATA[ List listBox = new ArrayList(); listBox.add(rowsEmails.getItems()); Iterator it = listBox.iterator(); while (it.hasNext()){ if (!listBox.isEmpty()){ Email email = new Email(); System.out.print(it.next()); if (email.validaEmail() == false){ System.out.println("Email incorreto: " + email.getEmail()); } } } ]]&gt; &lt;/attribute&gt; &lt;/button&gt;

Alguém sabe o que é isso?

Não sei se entendi direito, mas aqui vai o chute.

Acho que vc tem que atualizar o model da lista (ListModelList), aliás quando vc atualiza o model o ZK já cuida da view pra vc.

P.S Tente não colocar código dentro da sua página veja as sugestões da equipe do ZK para o pattern MVC.

flws

Cara, não entendi o lance de atualizar o model.
Não tem como colocar um exemplo aí?
O que estou querendo fazer é o seguinte:
Pegar os valores inseridos no listbox, capturar todos os itens.

Tente algo assim:

import java.util.List;

import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listbox;

@SuppressWarnings("serial")
public class YourListBox extends Listbox {
	private ListModelList modelList = new ListModelList();

	public void setData(List<Object> data) {

		this.modelList.addAll(data);

		super.setModel(modelList);
	}

	public void addItem(Object item) {
		if (!this.modelList.contains(item)) {
			this.modelList.add(item);
		}
	}

	public void removeItem(Object item) {
		this.modelList.remove(item);
	}

	public Object[] getData() {
		return this.modelList.toArray();
	}
}

Na sua página você utiliza o setData()/ou no construtor para colocar sua lista inicial e o addItem() para adicionar itens.

flws

Cara, acho que expliquei errado.
Eu estou apenas querendo dar um get numa determinada posição do array e pegar o valor, apenas isso.
O MVC já estou fazendo e estou populando o listbox, falta só pegar os valores.
Por exemplo, eu insiro 2 itens no listbox e capturo o length com o comando:

listbox.getItemCount();

E me retorna 2. Sem problemas até aqui.

Agora quando digito listbox.getItems(), me retorna os seguintes valores:
[<Listitem z_ga_l1>, <Listitem z_ga_u1>]
É isso que preciso resolver, preciso tratar esta saída. O número de itens está retornando, mas o formato que esta retornando não está certo.

Obs.: listbox é o id.

Dá uma olhada neste código pra ver se ajuda:

Aqui a classe da lista:

[code]public class GListBox extends Listbox {
private Object selected = null;
private ListModelList modelList = new ListModelList();

public void setData(List<Object> data) {

	this.modelList.addAll(data);
	
	super.addEventListener("onSelect", new EventListener() {
		public void onEvent(Event e) throws Exception {
			int index = GListBox.this.getSelectedIndex();
			if (index != -1) {
				selected = GListBox.this.modelList.get(index);
			}
		}
	});

	super.setModel(modelList);
}

public void addItem(Object item) {
	if (!this.modelList.contains(item)) {
		this.modelList.add(item);
	}
}

public void removeItem(Object item) {
	this.modelList.remove(item);
}

public Object getSelected() {
	return this.selected;
}

public Object[] getData() {
	return this.modelList.toArray();
}

}
[/code]

Pagina da lista:

[code]<?page id=“pgLista” title="" cacheable=“false”
language=“xul/html” zscriptLanguage=“Java” contentType=“text/html;charset=UTF-8”?>

<window id="controller"
	apply="controller.ListaController"
	title="TESTE" position="center" width="700px"
	border="normal" style="background-color:#FFFFFF">

	<listbox id="list" use="view.GListBox"
		height="250px" mold="paging" pageSize="14">
	</listbox>

	<button id="print" label="Imprimir" width="85px" height="24px"
		forward="onClick=onPrint" />

</window>
[/code]

Controler da lista:

[code]public class ListaController extends GenericAutowireComposer {
protected GListBox list = null;

private Window window = null;

@Override
public void doAfterCompose(Component cmp) throws Exception {

	List<Object> itens = new ArrayList<Object>(0);

	itens.add("Item 1");
	itens.add("Item 2");
	itens.add("Item 3");

	this.window = (Window) cmp;

	this.list = (GListBox) this.window.getFellow("list");

	this.list.setData(itens);

	ListitemRenderer renderer = new ListitemRenderer() {

		@Override
		public void render(Listitem listItem, Object data) throws Exception {
			String d = (String) data;

			new Listcell(d).setParent(listItem);
		}
	};

	this.list.setItemRenderer(renderer);

	super.doAfterCompose(cmp);
}

public void onPrint(Event event) throws Exception {

	for (Object item : this.list.getData()) {
		System.out.println("-->> " + item);
	}

	Messagebox.show("Impressão concluida!", "Mensagem", Messagebox.OK, Messagebox.INFORMATION);
}

}
[/code]

No método onPrint no controller estou imprimindo o conteúdo da lista.

P.S. Na classe da lista o nome foi alterado para GListBox e o método setData foi melhorado para obter o item selecionado.

flws

Caro fantomas!
Valeu demais sua ajuda, mas cara eu sou novo mesmo com isso.
Mas fala uma coisa, para mim implementar estes métodos addItem, removeItem, getSelected e getData usando MVC, como você fez com o método onPrint, eu nem faço idéia de como começar.
Dá uma luz aí, já abusando de sua boa vontade.

Dá uma lida neste link: http://www.zkoss.org/smalltalks/mvc2/

Os caras do ZK da algumas sugestões de como implementar o pattern MVC, essa é uma delas na versão 3.5.0; na versão mais recente eles melhoraram um pouco mais mas não tive tempo de estudar ainda.

Na verdade a coisa é simples; basta criar uma classe que herda a estrutura do componente visual que vc esta interessado no caso o Listbox e adicionar os métodos que vc acha interessante.
A sacada do model eu ralei um pouco pra pegar, acho que foi no forum que eles tem; vale a pena se incluir no forum os usuário fazem um monte de pergunta interessante e os caras do ZK responde quase tudo rapidinho, mesmo que seja para dizer que não dá e vai fazer depois.

A classe correspondente ao controller herda a estrutura da classe GenericAutowireComposer e o objeto resultante é ASSOCIADO (não é herança) a sua página pelo atributo APPLY. Quando vc utiliza o atributo USE vc está incluindo um objeto que possui HERANÇA de algum componente do ZK. Então fica esperto com o conceito APPLY -> associação, USE -> herança.

No meio surge a pergunta: Como é que o botão consegue acionar o método onPrint no controller?
Tem a conveção, os métodos que descrevem eventos possui o on no inicio do método ex: onProcessar. O outro ponto e o atributo forward que diz qual método será executado forward=“onClick=onConfirmar”.
De certa maneira é simples do ZK fazer isto porque vc associou sua classe através do atributo APPLY, como o nome do método foi mencionado basta ele vasculhar o objeto e pronto.

O que atrapalha um pouco, embora seja a proposta declarada pela equipe do ZK, é que eles tem vários jeito de resolver esse pattern (MVC) então acaba ficando um pouco confuso na hora de estudar e decidir qual caminho seguir.

Espero ter ajudado.

flws

Valeu cara, mais uma vez!
Tenho dificuldade porque vim do PHP, tudo está sendo novo pra mim.

ve se isso lhe ajuda

<zscript>
        public void showItem(){
            int index = 2; // 
            alert("item  selecionado >>> " + rowsEmails.selectedItem.children.get(index).label); // retorna a segunda coluna do intem selecionado do   listbox   
        }
</zscript>
no onSelect do listbox vc chama esse método 

espero ter ajudado

flw!

A solução definitiva pro problema!

&lt;?page title=&quot;new page title&quot; contentType=&quot;text/html;charset=UTF-8&quot;?&gt;
&lt;zk&gt;
&lt;window title="My First Window" border="normal"&gt;
&lt;window&gt;
&lt;zscript&gt;
	String[] lista = new String[1];
	lista[0] = "Item";
	
&lt;/zscript&gt;
&lt;listbox id="lbx" mold="paging" multiple="true"&gt;
&lt;listitem forEach="${lista}"&gt;
	&lt;listcell label="${each} - ColA"/&gt;
	&lt;listcell label="${each} - ColB"/&gt;
	&lt;listcell label="${each} - ColC"/&gt;
&lt;/listitem&gt;
&lt;/listbox&gt;
&lt;button label="show selected" onClick='alert(""+lbx.getSelectedItem().getChildren().get(2).getLabel())'/&gt;
	&lt;!-- Apenas mudar o get() para alterar entre as colunas --&gt;
&lt;/window&gt;
&lt;/window&gt;	
&lt;/zk&gt;

Assim eu consigo selecionar entre uma coluna ou outra, basta alterar o index que está no get.
Ou seja, com um for eu resolvo isso.
Valeu a ajuda.