0

Unable to retrieve context menu fellows in Java

asked 2010-06-07 08:06:17 +0800

tvella gravatar image tvella
87 3

updated 2010-06-07 08:07:13 +0800

Hi,

I have been using a context menu to insert Treeitems into a tree. I am having difficulty with the following:

1. I can't seem to locate a menuitem component that is defined in a context menu popup using component.getFellow(String)
2. I am unable to receive onClick events for this menuitem

I am using ZK EE 5.0.2. I can confirm the problem exists in Firefox 3.6 and IE 8

Heres the zul code file: test3.zul

<?xml version="1.0" encoding="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"
    xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd">

	<tree apply="bugshow.MyComposer3">
		<treecols sizable="true">
			<treecol width="30%" />
			<treecol width="7%" />
			<treecol width="12%"/>
			<treecol width="12%"/>
			<treecol width="17%"/>
			<treecol width="12%"/>
			<treecol width="12%"/>
		</treecols>
		<treechildren>
			<treeitem context="editPopup">
				<treerow draggable="true" droppable="true">
					<treecell>
						<textbox value="" inplace="true"/>
					</treecell>
					<treecell><intbox value="1"/></treecell>
					<treecell>
						<decimalbox value="0"/>
					</treecell>
					<treecell>	<label value="0"/></treecell>
					<treecell><datebox /></treecell>
					<treecell><label value="0"/></treecell>
					<treecell>
						<label value="5,527"/>
					</treecell>
				</treerow>
			</treeitem>
		</treechildren>
	</tree>

	<menupopup id="editPopup">
		<menu label="Insert..." >
			<menupopup>
				<menuitem id="generalInsertMenuItem" label="General" />
			</menupopup>
		</menu>
	</menupopup>
</zk>


Here's the Composer java code: MyComposer3.java


package bugshow;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Menuitem;

/**
 * MyComposer3.java: Handles onClick event from context menupopup.
  */

public class MyComposer3 extends GenericForwardComposer {

	/*
	 *  The following are handlers are for the menu pop up menus
	 */

	public void doAfterCompose(Component component) throws java.lang.Exception {
		super.doAfterCompose(component);

		Menuitem menuItem  = (Menuitem) component.getFellow("generalInsertMenuItem");
		menuItem.setLabel("found fellow!");
	}

	public void onClick$generalInsertMenuItem(Event event) throws Exception {
		Menuitem menuItem  = (Menuitem) event.getTarget();
		menuItem.setLabel("Received onClick Event!");
	}
}

When the doAfterCompose() method is automatically invoked it throws a ComponentNotFound exception. If you comment the code out in that method you will also be able to confirm that you never receive the onClick event when you exercise the menu popup

Can you tell me what I am doing wrong so I can resolve the two problems?

Thanking you in advance,
Trevor

delete flag offensive retag edit

4 Replies

Sort by ยป oldest newest

answered 2010-06-07 20:05:01 +0800

SimonPai gravatar image SimonPai
1696 1

Hi Trevor,

The reason the Tree can't find the Menuitem is because they are in different IdSpace. You can wrap the Tree and Menubar (you put menupopup in the zul, but I assume it's menubar?) with a Window and put the composer on it:

	<window apply="bugshow.MyComposer3">
		<tree>
			// ...
		</tree>
		<menubar>
			// ...
		</menubar>
	</window>

And since you are using GenericForwardComposer, you don't need to use getFellow() to retrieve it:

public class MyComposer3 extends GenericForwardComposer {

	Menuitem generalInsertMenuItem; // auto wired

	public void doAfterCompose(Component component) throws Exception {
		super.doAfterCompose(component);

		generalInsertMenuItem.setLabel("found fellow!");
	}

	public void onClick$generalInsertMenuItem(Event event) throws Exception {
		generalInsertMenuItem.setLabel("Received onClick Event!");
	}
}

Regards,
Simon

link publish delete flag offensive edit

answered 2010-06-08 06:06:54 +0800

tvella gravatar image tvella
87 3

updated 2010-06-08 06:27:13 +0800

Thank you Simon. Wrapping the zul code under a window tag did get around the issues 1 and 2. I think though it has raised another issue. Specifically, when the onClick$generalInsertMenuItem() method is triggered, the target ends up being the window instead of the menuitem that was clicked.

That seems strange and not inline with what I was expecting. When a widget is clicked on in the GUI, the event.getTarget() call should return the object that was clicked on. Yet this does not seem to be the case. Its appears to be inconsistent. Have I misunderstood the way the event API is meant to work? Your thoughts would be greatly appreciated.

Here's my updated MyComposer3.java code which highlights the issue:

package bugshow;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Menuitem;

public class MyComposer3 extends GenericForwardComposer {

	public void onClick$generalInsertMenuItem(Event event) throws Exception {
		Menuitem menuItem  = (Menuitem) event.getTarget();
		menuItem.setLabel("Received onClick Event!");
	}
}

When I click on the generalInsertMenuItem (which is located in the context menu popup) I get the following exception:

SEVERE: >>java.lang.ClassCastException: org.zkoss.zul.Window cannot be cast to org.zkoss.zul.Menuitem
>>	at bugshow.MyComposer3.onClick$generalInsertMenuItem(MyComposer3.java:30)
>>	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>	at java.lang.reflect.Method.invoke(Method.java:597)
>>	at org.zkoss.zk.ui.event.GenericEventListener.onEvent(GenericEventListener.java:87)
>>	at org.zkoss.zk.ui.impl.EventProcessor.process0(EventProcessor.java:196)
>>	at org.zkoss.zk.ui.impl.EventProcessor.process(EventProcessor.java:140)
>>	at org.zkoss.zk.ui.impl.EventProcessingThreadImpl.process0(EventProcessingThreadImpl.java:517)
>>	at org.zkoss.zk.ui.impl.EventProcessingThreadImpl.sendEvent(EventProcessingThreadImpl.java:121)
>>...

link publish delete flag offensive edit

answered 2010-06-10 20:35:48 +0800

SimonPai gravatar image SimonPai
1696 1

Hi Trevor,

It looks strange in the first glance, but this is the correct behavior. When the onClick event is triggered on generalInsertMenuItem, it is automatically forwarded to the Window (this is GenericForwardComposer's job). Thus, the event argument we get in onClick$generalInsertMenuItem is a ForwardEvent on the Window whose original event is the onClick MouseEvent on the Menuitem. To reach the original event/target you can do this:

Component comp = ((ForwardEvent) event).getOrigin().getTarget();
// this component will be the Menuitem
Menuitem menuitem = (Menuitem) comp;

Regards,
Simon

link publish delete flag offensive edit

answered 2010-06-29 06:28:26 +0800

tvella gravatar image tvella
87 3

Understood. Thank you kindly Simon

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2010-06-07 08:06:17 +0800

Seen: 1,236 times

Last updated: Jun 29 '10

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More