Zkoss - componente listbox(listitem)

10 respostas
amoreiraedu

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?

10 Respostas

fantomas

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

amoreiraedu

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.

fantomas

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

amoreiraedu

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.

fantomas

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

Aqui a classe da lista:
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();
	}
}
Pagina da lista:
<?page id="pgLista" title="" cacheable="false" 
	language="xul/html" zscriptLanguage="Java" contentType="text/html;charset=UTF-8"?>

<zk xmlns="http://www.zkoss.org/2005/zul"
	xmlns:h="http://www.w3.org/1999/xhtml"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  
	<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>
</zk>

Controler da lista:

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);
	}
}

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

amoreiraedu

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.

fantomas

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

amoreiraedu

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

gilmaslima

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!

amoreiraedu

A solução definitiva pro problema!

&lt;?page title="new page title" contentType="text/html;charset=UTF-8"?&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.

Criado 6 de fevereiro de 2009
Ultima resposta 18 de fev. de 2009
Respostas 10
Participantes 3