Skip to content

Instantly share code, notes, and snippets.

@ulmangt
Created September 6, 2012 18:56
Show Gist options
  • Save ulmangt/3659465 to your computer and use it in GitHub Desktop.
Save ulmangt/3659465 to your computer and use it in GitHub Desktop.
A SWT/RCP/JFace MenuManager subclass which stays open when one of its MenuItems is clicked
import java.lang.reflect.Field;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.swt.events.MenuDetectEvent;
import org.eclipse.swt.events.MenuDetectListener;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MenuListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
public class StayOpenMenuManager extends MenuManager
{
private Point point;
@Override
public Menu createContextMenu( Control parent )
{
final Menu menu = super.createContextMenu( parent );
// add a listener to remember the position of the menu when it is created
parent.addMenuDetectListener( new MenuDetectListener( )
{
public void menuDetected( MenuDetectEvent e )
{
point = new Point( e.x, e.y );
}
} );
// add a listener to set the menu "hasLocation" field to false
// when it closes so that it pops up under the mouse the next
// time it is opened
menu.addMenuListener( new MenuListener( )
{
@Override
public void menuHidden( MenuEvent event )
{
try
{
Field field = Menu.class.getDeclaredField( "hasLocation" );
field.setAccessible( true );
field.set( menu, false );
}
catch ( Exception e )
{
e.printStackTrace();
}
}
// whenever the menu is shown, add listeners to all the menu items
// which re-show the menu when an item is selected
// the only way to close the menu is to click outside of it
@Override
public void menuShown( MenuEvent event )
{
for ( MenuItem item : menu.getItems( ) )
{
item.addSelectionListener( new SelectionListener( )
{
@Override
public void widgetSelected( SelectionEvent e )
{
Display.getDefault( ).asyncExec( new Runnable( )
{
@Override
public void run( )
{
menu.setLocation( point );
menu.setVisible( true );
}
} );
}
@Override
public void widgetDefaultSelected( SelectionEvent e )
{
}
});
}
}
});
return menu;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment