ContextMenu component

I’m using 3.1.0 and it’s working great for the most part. Some comments/questions:

  1. I second the other requests to open this up a bit so it’s possible to subclass ContextMenu and ContextMenuItem. For example, I get events in my ClickListener for menu items that have submenus. There’s no action to take so they should be filtered … but ContextMenuItem.hasSubMenus() is inaccessible. Would also be nice to have the submenu hover delay settable.

  2. If I pause on an item with a submenu the submenu appears fine but it doesn’t close if I continue on to other items on the same menu. This happens in several different browsers. Standard context menu behavior is to only display the submenu while the cursor is on the parent or a submenu item.

Any thoughts on timing for the next release?

Thanks -

When I add a ContextMenu.ClickListener to a context menu, the event is fired when I hover over a menu item, that has sub items, long enough for the sub items to appear. Is this intended behaviour?

New ContextMenu 4.0 experimental release is available for Vaadin 7 Alpha 2. New version contains many of the requested changes as well as all new features and enhancements that Vaadin 7 makes possible.

Few highlights:

  • Interfaces for ContextMenu and ContextMenuItem and abstract implementations to support extending and customization
  • Fully reworked communication mechanism with Vaadin 7
  • Fully component based as menu items are components
  • Support keyboard navigation
  • No more fixed widths.
  • New click listener mechanism that supports item specific click listeners.
  • Tons of fixes, adjustments and details.

Current version is highly experimental and there will most likely be changes for next version as Vaadin 7 evolves. This is just a try out. Older 3.1 version is still of course available for Vaadin 6.x branch.

Have fun testing, feedback is appreciated.

Hi Peter Lehto!

Please add this function to ContextMenu.java - it is provide more functionality.

public void removeAll() {
itemIds.clear();
items.clear();
}

Great component. I really like it.
But I have question/feature request:
I have about 100 elements in menu. They doesn’t fit into window. Is it possible to add there vertical scrollbar? ( 3.1.0)

Thank you

Hi there!
Is it possible to add this ContextMenu to RichTextArea so that it could show up after clicking with the right button on text area?

Hi, I am using the component for V6 and I seem to be having an issue with what appears to ge a “ghost” div tag that gets created as soon as I add this component to my vertical layout.

I have a class which extends VerticalLayout and I am adding this component to the layout followed by a HorizontalSplitPanel. I have a gap at the top of the VieticalLayout which appears to be a div which I cannot size. (If I add it after the HorizontalSplitPanel then I get a gap below as you would expect).

Any ideas, is there a trick I am missing here?

thanks
Paul

That div is unfortunately caused by the fact that in Vaadin 6 each component must be attached to a parent component in order to be visible. That’s why also the context menu must be added to layout creating the empty ghost div. However, in the theme this div is set to size 0,0 and hidden with CSS. This should be enough and not show any gaps in the layout. Is there some modifications to the context menu theme?

In Vaadin 7 ContextMenu works as an extension which does not require adding it to any parent component directly.

Hey,

i’m using V7 and ContextMenu4.1.2. I cant figure out how to make it work with a Tree, hope someone can help me :slight_smile:

Thanks

Hello, in 4.1.2 you cannot use it with Tree. I’ve just released 4.1.3 which supports also the tree component now. Add ContextMenu with setContextMenuOf(tree) and register TreeListener for the context menu to be notified on which item the menu was clicked on.

Hi Peter.
Thank you for your great work!
Is it any possibility to add scroll bars to your Context menu? Now when items count is greater than can be displayed in a browser window the menu top border just shifts outsides application frame. So first menu items becomes unreachable.
Also do you plan add a keyboard support for menu items selecting and choosing?

Scrolling the items is a good point, I’ll consider it for the next version. Keyboard is already supported in Vaadin 7 version. With arrow keys you can open the menu items (once you have one selected) and with enter key you select an item. Currently I have no plans with Vaadin 6 version as people are migrating more to Vaadin 7.

Hi, it works now, nice job.
Keep up the good work!

Cannot get to compile the add on. I am using the latest version 4.1.3 however widget compilation succeeds with version 3.1.0
Here is the error:

Compiling widgetset com.example.dragdrop.widgetset.DragdropWidgetset
Updating GWT module description file...
Feb 20, 2013 3:11:06 PM com.vaadin.terminal.gwt.widgetsetutils.ClassPathExplorer getAvailableWidgetSets
INFO: Widgetsets found from classpath:
	com.vaadin.terminal.gwt.DefaultWidgetSet in jar:file:C:/workspace/DragDrop/WebContent/WEB-INF/lib/vaadin-6.8.1.jar!/
	com.example.dragdrop.widgetset.DragdropWidgetset in file://C/workspace/DragDrop/src
	org.vaadin.peter.contextmenu.ContextmenuWidgetset in jar:file:C:/workspace/DragDrop/WebContent/WEB-INF/lib/ContextMenu-4.1.3.jar!/

Feb 20, 2013 3:11:06 PM com.vaadin.terminal.gwt.widgetsetutils.ClassPathExplorer getAvailableWidgetSets
INFO: Search took 4ms
Done.
Starting GWT compiler
Loading inherited module 'org.vaadin.peter.contextmenu.ContextmenuWidgetset'
   Loading inherited module 'com.vaadin.DefaultWidgetSet'
      [ERROR]
 Unable to find 'com/vaadin/DefaultWidgetSet.gwt.xml' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source?
   [ERROR]
 Line 7: Unexpected exception while processing element 'inherits'
com.google.gwt.core.ext.UnableToCompleteException: (see previous log entries)
	at com.google.gwt.dev.cfg.ModuleDefLoader.nestedLoad(ModuleDefLoader.java:262)
	at com.google.gwt.dev.cfg.ModuleDefSchema$BodySchema.__inherits_begin(ModuleDefSchema.java:495)
	at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at com.google.gwt.dev.util.xml.HandlerMethod.invokeBegin(HandlerMethod.java:230)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.startElement(ReflectiveParser.java:274)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.emptyElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.parse(ReflectiveParser.java:331)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.access$100(ReflectiveParser.java:48)
	at com.google.gwt.dev.util.xml.ReflectiveParser.parse(ReflectiveParser.java:402)
	at com.google.gwt.dev.cfg.ModuleDefLoader.nestedLoad(ModuleDefLoader.java:280)
	at com.google.gwt.dev.cfg.ModuleDefSchema$BodySchema.__inherits_begin(ModuleDefSchema.java:495)
	at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at com.google.gwt.dev.util.xml.HandlerMethod.invokeBegin(HandlerMethod.java:230)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.startElement(ReflectiveParser.java:274)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.emptyElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.parse(ReflectiveParser.java:331)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.access$100(ReflectiveParser.java:48)
	at com.google.gwt.dev.util.xml.ReflectiveParser.parse(ReflectiveParser.java:402)
	at com.google.gwt.dev.cfg.ModuleDefLoader.nestedLoad(ModuleDefLoader.java:280)
	at com.google.gwt.dev.cfg.ModuleDefLoader$1.load(ModuleDefLoader.java:192)
	at com.google.gwt.dev.cfg.ModuleDefLoader.doLoadModule(ModuleDefLoader.java:308)
	at com.google.gwt.dev.cfg.ModuleDefLoader.loadFromClassPath(ModuleDefLoader.java:151)
	at com.google.gwt.dev.GWTCompiler.run(GWTCompiler.java:162)
	at com.google.gwt.dev.GWTCompiler$1.run(GWTCompiler.java:131)
	at com.google.gwt.dev.CompileTaskRunner.doRun(CompileTaskRunner.java:87)
	at com.google.gwt.dev.CompileTaskRunner.runWithAppropriateLogger(CompileTaskRunner.java:81)
	at com.google.gwt.dev.GWTCompiler.main(GWTCompiler.java:138)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at com.vaadin.tools.WidgetsetCompiler$1.run(WidgetsetCompiler.java:82)
	at java.lang.Thread.run(Unknown Source)
   [ERROR]
 Failure while parsing XML
com.google.gwt.core.ext.UnableToCompleteException: (see previous log entries)
	at com.google.gwt.dev.util.xml.DefaultSchema.onHandlerException(DefaultSchema.java:58)
	at com.google.gwt.dev.util.xml.Schema.onHandlerException(Schema.java:66)
	at com.google.gwt.dev.util.xml.Schema.onHandlerException(Schema.java:66)
	at com.google.gwt.dev.util.xml.HandlerMethod.invokeBegin(HandlerMethod.java:240)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.startElement(ReflectiveParser.java:274)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.emptyElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.parse(ReflectiveParser.java:331)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.access$100(ReflectiveParser.java:48)
	at com.google.gwt.dev.util.xml.ReflectiveParser.parse(ReflectiveParser.java:402)
	at com.google.gwt.dev.cfg.ModuleDefLoader.nestedLoad(ModuleDefLoader.java:280)
	at com.google.gwt.dev.cfg.ModuleDefSchema$BodySchema.__inherits_begin(ModuleDefSchema.java:495)
	at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at com.google.gwt.dev.util.xml.HandlerMethod.invokeBegin(HandlerMethod.java:230)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.startElement(ReflectiveParser.java:274)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.emptyElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.parse(ReflectiveParser.java:331)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.access$100(ReflectiveParser.java:48)
	at com.google.gwt.dev.util.xml.ReflectiveParser.parse(ReflectiveParser.java:402)
	at com.google.gwt.dev.cfg.ModuleDefLoader.nestedLoad(ModuleDefLoader.java:280)
	at com.google.gwt.dev.cfg.ModuleDefLoader$1.load(ModuleDefLoader.java:192)
	at com.google.gwt.dev.cfg.ModuleDefLoader.doLoadModule(ModuleDefLoader.java:308)
	at com.google.gwt.dev.cfg.ModuleDefLoader.loadFromClassPath(ModuleDefLoader.java:151)
	at com.google.gwt.dev.GWTCompiler.run(GWTCompiler.java:162)
	at com.google.gwt.dev.GWTCompiler$1.run(GWTCompiler.java:131)
	at com.google.gwt.dev.CompileTaskRunner.doRun(CompileTaskRunner.java:87)
	at com.google.gwt.dev.CompileTaskRunner.runWithAppropriateLogger(CompileTaskRunner.java:81)
	at com.google.gwt.dev.GWTCompiler.main(GWTCompiler.java:138)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at com.vaadin.tools.WidgetsetCompiler$1.run(WidgetsetCompiler.java:82)
	at java.lang.Thread.run(Unknown Source)
   [ERROR]
 Unexpected error while processing XML
com.google.gwt.core.ext.UnableToCompleteException: (see previous log entries)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.parse(ReflectiveParser.java:355)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.access$100(ReflectiveParser.java:48)
	at com.google.gwt.dev.util.xml.ReflectiveParser.parse(ReflectiveParser.java:402)
	at com.google.gwt.dev.cfg.ModuleDefLoader.nestedLoad(ModuleDefLoader.java:280)
	at com.google.gwt.dev.cfg.ModuleDefSchema$BodySchema.__inherits_begin(ModuleDefSchema.java:495)
	at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at com.google.gwt.dev.util.xml.HandlerMethod.invokeBegin(HandlerMethod.java:230)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.startElement(ReflectiveParser.java:274)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.emptyElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.parse(ReflectiveParser.java:331)
	at com.google.gwt.dev.util.xml.ReflectiveParser$Impl.access$100(ReflectiveParser.java:48)
	at com.google.gwt.dev.util.xml.ReflectiveParser.parse(ReflectiveParser.java:402)
	at com.google.gwt.dev.cfg.ModuleDefLoader.nestedLoad(ModuleDefLoader.java:280)
	at com.google.gwt.dev.cfg.ModuleDefLoader$1.load(ModuleDefLoader.java:192)
	at com.google.gwt.dev.cfg.ModuleDefLoader.doLoadModule(ModuleDefLoader.java:308)
	at com.google.gwt.dev.cfg.ModuleDefLoader.loadFromClassPath(ModuleDefLoader.java:151)
	at com.google.gwt.dev.GWTCompiler.run(GWTCompiler.java:162)
	at com.google.gwt.dev.GWTCompiler$1.run(GWTCompiler.java:131)
	at com.google.gwt.dev.CompileTaskRunner.doRun(CompileTaskRunner.java:87)
	at com.google.gwt.dev.CompileTaskRunner.runWithAppropriateLogger(CompileTaskRunner.java:81)
	at com.google.gwt.dev.GWTCompiler.main(GWTCompiler.java:138)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at com.vaadin.tools.WidgetsetCompiler$1.run(WidgetsetCompiler.java:82)
	at java.lang.Thread.run(Unknown Source)
Widgetset compilation failed

Version 4.1.x is for Vaadin 7 and version 3.1.x is for Vaadin 6.
You should choose the correct version based on the Vaadin version you are using.

I have some strange behavior and don’t get rid of this: Version 4.1.2 was working fine. Then i just upgraded to 4.1.3 and made a maven clean install. Suddenly while starting my webapp on tomcat I get

when downgrading back to 4.1.2 everything is working fine again. Any idea what is going wrong?

Hi,

I would like to popup a right-click menu over a label component. Is contextmenu component what I should try?

I try to display the menu on a given coordinate but, i could not figure out how to add this menu to the container class ( tried with a verticallayout, panel or UI ?)

Thanks

Yasin

So far, I love the add-on. One thing I really need to be able to do is when using within the context of a table (or a tree but I’m not doing that currently), display different menu items depending on the underlying row.

For instance, if the table is a list of users, you would not want a “Disable” context menu item on a user whose account is already disabled. Further, you WOULD want a “Enable” menu item. There are several “boolean” choices like that I might be able to hack around, but there are others that are only applicable to state of the underlying row.

Is there anyway to accomplish this requirement?

Hello,

I’m trying to use this extension for my table, but t

he menu never shows up in the browser.
My code looks like this:


        contextMenu = new ContextMenu();
        contextMenu.addItem("test1");
        contextMenu.addItem("test2");
        contextMenu.addItem("test3");
        contextMenu.setOpenAutomatically(true);
        contextMenu.setAsTableContextMenu(table);

I have debuged what was going on in ContextMenu class here:


table.addItemClickListener(new ItemClickEvent.ItemClickListener() {

			[size=1]
@Override
			public void itemClick(ItemClickEvent event) {
				if (event.getButton() == MouseButton.RIGHT) {
					fireEvent(new ContextMenuOpenedOnTableRowEvent(
							ContextMenu.this, table, event.getItem(), event
									.getPropertyId()));
					open(event.getClientX(), event.getClientY());
				}
			
[/size]}
		});

This part of code does happen and open() method is called, but the menu is never displayed.

Can anyone please help?

Solved for me…
Miha, I just realized that I had to compile widgetset with context menu.

It is working now.

Thanks