Eclipse plugin / RCP : Showing menu via handler - java

I'm looking to create a toolbar with a drop-down menu largely identical to Eclipse's "Open Console" button in the console view.
I can do this by programmatically adding actions (which is what the Console View does), however I'm looking to do this via commands & handlers in plugin.xml.
The instructions at https://wiki.eclipse.org/Menu_Contributions/Dropdown_Command are extremely good, however I'm looking to show the drop-down menu when the button itself is clicked (I.E.: clicking the button behaves the same as clicking the drop-down menu triangle to the right of the button). Again: identical to how the "Open Console" button works.
However I've no clue how to do this in "plugin.xml land". I've tried the following in the handler:
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
Event e = (Event) event.getTrigger();
ToolBar t = ((ToolItem) e.widget).getParent();
Menu m = t.getMenu();
m.setVisible(true);
[...]
... however t.getMenu() returns a null ...

Related

set Focus on a view inside Listener

I'm building a Plugin with the JCEF Framework for a Eclispe rcp. the Framework is written in C++ and has wrapper for Java. With the framework I get a browser in a Component
I have a curios Problem, which needs some steps to get there:
Click (set focus) to a random view in the rcp
Click in the browser
open another window (e.g. windows explorer)
click on the close button from the rcp
then a dialog box opens and ask if you want to close the program. The problem is that you cant click on yes or no, only if you click on another view again. The problem only occurs with my plugin.
I have added the Component to a Frame in the createPartControl methode:
public void createPartControl(final Composite parent) {
//create the browser
Composite composite = new Composite(parent, SWT.EMBEDDED);
Frame frame = SWT_AWT.new_Frame(composite);
frame.add(browser_component);
//do some other stuff
}
Do someone know what the problem could be?
If not, I thought about a workaround, that I will set the focus on my view from my code, if I click on the browser. I can create and add a FocusListener for the Browser.
My attempt:
//in the methode of the FocusListener
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView("myview");
But it throws an Invalid thread access Exception

How enable or disable correctly an Action

i have a little problem when i try to disable an Action of my Netbeans platform project. When the app starts, some Actions must be disabled, and i do that with this method:
CallableSystemAction.get(BuildProjectAction.class).setEnabled(FLAG);
It works, because the BuildProjectAction is disabled, but the corresponding items of the MenuBar and the Toolbar remains enabled until i click on one of it.
Only later that i have clicked on it, the comportament start to work correctly.
First question: Why?
If i want disable an Action, it's obvious that i want disable also the relative Icon in the Menu and in the Toolbar, so it must be automatic when i call Action.setEnabled(false).
It doesn't have sense that the Icons are not refreshed if i don't click on they.
Same problem if i try to use .getToolbarPresenter().setEnabled(false); and .getMenuPresenter().setEnabled(false);
For start the application with the icons disabled, I have tried to set the lazy attribute to FALSE and declare the image programmatically with the method setIcon(new ImageIcon(image)); that sets the same image for Menu and Toolbar.
And it works; there is only another problem: Menu and Toolbar have icons of different size (16x16 and 24x24).
It doesn't have sense that the if i set the icon with the #ActionRegistration(iconBase = "image.png") the correct icon is automatically selected, but if i use the method .setIcon(), it doesn't.
I have read some articles about Action, CookieAction, Lookup, but the only thing that i want is disable the graphic elements in the same moment when i disable the Action.
Second question: How i can do that?
This is an example of my Action.
#ActionID(
category = "Run",
id = "BuildProjectAction")
#ActionRegistration(
lazy = true,
iconBase = "images/icons/compile.png",
displayName = "#CTL_BuildProjectAction")
#ActionReferences({
#ActionReference(
path = "Menu/Run",
position = 3),
#ActionReference(path = "Toolbars/Run",
position = 3),
#ActionReference(
path = "Shortcuts",
name = "D-B")
})
#Messages("CTL_BuildProjectAction=Build Project")
public final class BuildProjectAction extends CallableSystemAction {
#Override
public void actionPerformed(ActionEvent e) {...}
#Override
public void performAction() {}
#Override
public String getName() {
return Bundle.CTL_BuildProjectAction();
}
#Override
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
Thanks
The easiest way to create an action that is disabled at startup is to use the platform’s New Action Wizard to create your action, and to create one that depends on a "context" -- this is, on finding a specific object in the global lookup. If no object is available in the lookup, as at startup, then the action will be disabled.
The menu and toolbar graphic elements are bundled together with your action via the annotations. This means that enabled/disabled state of your context-aware action will automatically affect the icons in the menu and toolbar as well.
This article by Geertjan Wielenga has a walkthrough on creating a context-aware action:
http://netbeans.dzone.com/how-to-make-context-sensitive-actions
When you want to enable your action, you will add the object on which the action depends into the global lookup, which will cause the action (and its graphic elements) to be enabled.
This entry in the platform’s Developer FAQ has some examples of how to add an object to the global context:
http://wiki.netbeans.org/DevFaqAddGlobalContext
If you need to create an action that depends on a more complex set of conditions there is some discussion, as well as a code sample illustrating how to do this, in this platform developer list thread:
http://forums.netbeans.org/ptopic55295.html
The grayed-out versions of the icons that are shown when your action is disabled are created automatically by the platform. You only have to provide the "normal" non-grayed-out images.
As for the icons of different sizes, it’s a matter of filename convention. If your annotation declares the icon with #ActionRegistration(iconBase = "image.png”), then you will provide a 16x16 image called “image.png” and a 24x24 version called “image24.png”. The platform will find and use the appropriate size in the menu and toolbar.

Java get changed title of a dialog

I am trying to catch SWT events, like SWT.activate, SWT.deactivate and SWT.dispose in Eclipse. So, I can see which dialog was opened or activated, which was closed and which was deactivated. If the event was caught, I extract the Shell object and extracts its title with shell.getText(). To listen to events, I used an untyped listener (edited):
PlatformUI.getWorkbench().getDisplay().addFilter(SWT.Activate, shellListener);
Listener shellListener = new Listener(){
#Override public void handleEvent(Event e) {
if (event.widget.getClass() == org.eclipse.swt.widgets.Shell.class){
Shell shell = (Shell) e.widget;
String shellTitle = shell.getText();
if (event.type == Activate) {
String message = "The following dialog was activated: " + shellTitle;
// do other stuff with 'message'
}
}
}
};
If in Eclipse I open 'New' and the listener above correctly displays 'New' as activated dialog. But if I select 'Java Interface' within the 'New' dialog, then I am landing in a dialog, called 'New Java Interface'. But my handleEvent method is not fired and therefore I cannot extract the new dialog title. My question is: What kind of event is called or what happens, when I am in an Eclipse dialog and clicking on something in it which leads me to another dialog (with a new title)?
I think the problem here comes from the fact that the New 'dialog' in Eclipse is actually a Wizard. When you select 'Java Interface' (in the 'New' dialog) you are actually then landing not in another dialog but on a page within the same wizard. Every page in this wizard can have it's own title but behind the scene it is the same underlying shell object, that is why you don't receive further events.
By the way: when working with the SWT.Activate, SWT.Deactivate and other similar shell events, it might be helpflul / easier to the a ShellAdapter

Eclipse 3.5: Implementing my own context menu for a MultipageEditorPart --> no viewer involved

In my current RCP-project i use a MultipageEditorPart. It has various pages, with simple SWT composites on it. The composites contain some Text and Combo elements. When the user right clicks onto the editor page, I want a context menu to open. This menu holds a command for creating a new editor page, with a composite on it.
The command is already working, but I'm quite clueless about how to implement the context menu for the editor. Can someone help with this?
This should be based on Action contributions: see Contributing Actions to the Eclipse Workbench
As an RCP-based example, You could check out "Designing a Workflow Editor Eclipse XML", where a contextual menu is added to an EditorPart, included in a MultipageEditorPart.
protected void createContextMenuFor(StructuredViewer viewer) {
MenuManager contextMenu = new MenuManager("#PopUp");
contextMenu.add(new Separator("additions"));
contextMenu.setRemoveAllWhenShown(true);
contextMenu.addMenuListener(this);
Menu menu= contextMenu.createContextMenu(viewer.getControl());
viewer.getControl().setMenu(menu);
getSite().registerContextMenu(contextMenu, new UnwrappingSelectionProvider(viewer));
}
See also Step 18 for extending that context menu (section "Delete - Contextual Menu, requiring using GEF).

Menu item accel key works only after menu item has been shown

I'm developing a SWT/JFace application using the libraries from Eclipse 3.4.1.
I encounter the following problem on Windows (Vista 32bit) and Ubuntu 8.10 32bit:
I create a menu bar in the createMenuManager method of the JFace ApplicationWindow. I add MenuManagers for file, edit and help.
I then add an ExitAction to the file MenuManager like so:
filemenu.add(new ExitAction(this));
The ExitAction is defined this way:
public class ExitAction extends Action {
final ApplicationWindow window;
public ExitAction(ApplicationWindow w) {
this.window = w;
setText("E&xit");
setToolTipText("Exit the application");
setAccelerator(SWT.MOD1 + 'Q');
}
}
Now when my application starts I want be able to press "CTRL+Q" to quit the application. This does however not work. Only AFTER I click on "File" in the menu bar and THEN clicking "CTRL+Q" the application will quit.
I've tried this with different accelerators- same behavior.
It does work however if I create a "MenuItem" instead of an "Action" to contribute to the menu bar.
Is this a SWT bug or do I miss something?
Torsten.
Update: There is a duplicate bug of mine which also contains a workaround.
The bug url is: https://bugs.eclipse.org/bugs/show_bug.cgi?id=243758
Basically the workaround is to call create() on the ApplicationWindow and then getMenuBarManager().updateAll(true); which will force all menu items to get initialized.
Of course you have to call the above methods after you created the menu items.
AFAIK setAccelerator(.) does nothing else than adding the appropriate text to your MenuItem. You are responsible to register for an KeyUp event and react on it.
You can use Display.addFilter(SWT.KeyUp, myListener) to register your Listener independently of your widgets.
Turns out that this is a bug in Eclipse 3.4.
I have submitted a bug report: https://bugs.eclipse.org/bugs/show_bug.cgi?id=253078

Categories