Difference between revisions of "Developing Plug-Ins - IUserPanelMenuFactory"

From iDempiere en
Line 134: Line 134:
 
}
 
}
 
}
 
}
−
</per>
+
</pre>
  
−
Notice how i use the ID of the target of the event to determine which menu was pressed. The last thing you need to do now is to create new messages but lets start the application first.
+
Notice how i use the ID of the target of the event to determine which menu was pressed. The last thing you need to do now is to create new messages but lets start the application first. See how the new menus are added:
  
 
[[File:Menu3.png|320px]]
 
[[File:Menu3.png|320px]]
 
[[File:Menu4.png|320px]]
 
[[File:Menu4.png|320px]]

Revision as of 10:42, 16 June 2014

This tutorial is brought to you by Jan Thielemann from evenos GmbH (www.evenos-consulting.de). If you have questions, criticism or improvement suggestions, feel free to visit me (Jan.thielemann) or write me an email

Goal of this tutorial

The goal of this tutorial is to show you how you can use the IUserPanelMenuFactory service in you plug-in project. The reason why you might want to use this service is to provide additional menu entries in the WebUI (besides Feedback, Preference, Change Role and Log Out).


Prerequisites

Before you start this tutorial, you should take a look at the follwing tutorials:

Also if not already integreated into the trunk, you need to install the provided patch from https://idempiere.atlassian.net/browse/IDEMPIERE-2000

The workflow

The first thing you want to do is to create a Plug-In. If you already have a Plug-In and just want to add the MenuFactory there, thats also ok. To create a new Plug-In you select the Eclipse-Menu File>New>Other... Here you go to the "Plug-in Development" section and chose Plug-in Project. Chose a name and a location, make sure the OSGi framework is Equinox and click on next. Chose your name and the execution environment and click on finish.

The second step is to create a class which implements the IUserPanelMenuFactory interface. To do this, create a package of your choice and create a new class in there:

Menu1.png

package org.evenos.menutest;

import org.adempiere.webui.panel.IUserPanelMenuFactory;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;

public class MenuFactory implements IUserPanelMenuFactory {

	@Override
	public void onEvent(Event event) throws Exception {
		// TODO Auto-generated method stub
		
	}

	@Override
	public String[] getMenus() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void setComponent(Component component) {
		// TODO Auto-generated method stub
		
	}

}

The third step is to create a new component definition so that the core can know that your Plug-In provides a factory. To do this, select File>New>Other... from the Eclipse menu and chose Component Definition from the Plug-in Development section. Give it a unique name in your Plug-In and click on finish.

Menu2.png

In the component definition, provide a unique name (unique in the whole application). The best is to use the reverse domain identifier or the plugin name followd by menufactory (e. g. org.evenos.menutest.menufactory). Then chose you class which implements the IUserPanelMenuFactory and add a new property called "service.ranking" which is a integer and has a value > 0. Then go to the Services tab and select the org.adempiere.webui.panel.IUserPanelMenuFactory service in the provided services section. The component definition should now look like this:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.evenos.menutest.menufactory">
   <implementation class="org.evenos.menutest.MenuFactory"/>
   <service>
      <provide interface="org.adempiere.webui.panel.IUserPanelMenuFactory"/>
   </service>
   <property name="service.ranking" type="Integer" value="100"/>  
</scr:component>

After the component definition is ready, we can finally start implementing the menu factory. The first thing you might want to do is to create variables for the menu ids. I do this by using private final static Strings. In the getMenus() method, i return a new array with these strings.

	private final static String MENU_ONE = "org.evenos.menu.one";
	private final static String MENU_TWO = "org.evenos.menu.two";

	@Override
	public String[] getMenus() {
		return new String[] { MENU_ONE, MENU_TWO };
	}

In the setComponent() method, i store the component for later use, you will see why in the next step.

	private Component component;

	@Override
	public void setComponent(Component component) {
		this.component = component;
	}

I also want to implement a popup menu like the Feedback button has one so i use the constructor of my factory to create the menu and store it in a variable

	private Menupopup myMenu;

	public MenuFactory() {
		myMenu = new Menupopup();
		Menuitem mi = new Menuitem(Msg.getMsg(Env.getCtx(), "org.evenos.menuitem.one"));
		mi.setId("org.evenos.menuitem.one");
		myMenu.appendChild(mi);
		mi.addEventListener(Events.ON_CLICK, this);
		mi = new Menuitem(Msg.getMsg(Env.getCtx(), "org.evenos.menuitem.two"));
		mi.setId("org.evenos.menuitem.two");
		mi.addEventListener(Events.ON_CLICK, this);
		myMenu.appendChild(mi);
	}

The last step is to implement the onEvent() method to handle all the events. On the first menu button, i want to show the popup menu, on the second, i want to show a dialog box. On the popupmenu button, i simply want to log something to the console. Heres the implementation:

	@Override
	public void onEvent(Event event) throws Exception {
		if (event.getTarget().getId().equals(MENU_ONE)) {
			if (myMenu.getPage() == null) {
				component.appendChild(myMenu);
			}
			myMenu.open(event.getTarget(), "after_start");
		} else if (event.getTarget().getId().equals(MENU_TWO)) {
			FDialog.ask(0, component, "Do something?", new Callback<Boolean>() {
				@Override
				public void onCallback(Boolean result) {}
			});
		} else if (event.getTarget() instanceof Menuitem) {
			Menuitem mi = (Menuitem) event.getTarget();
			if ("org.evenos.menuitem.one".equals(mi.getId())) {
				System.out.println("Menuitem one pressed");
			} else if ("org.evenos.menuitem.two".equals(mi.getId())) {
				System.out.println("Menuitem two pressed");
			}
		}
	}

Notice how i use the ID of the target of the event to determine which menu was pressed. The last thing you need to do now is to create new messages but lets start the application first. See how the new menus are added:

Menu3.png Menu4.png

Cookies help us deliver our services. By using our services, you agree to our use of cookies.