RSS

Search Engine

Wednesday, June 16, 2010

Providing your own expression

You can write your own Java class which can be used define a variable which can then be used to define if a certain UI element shall be active or not. For example you can read the authorization of the user from your own class and then return the value which is assign to the user. This return value can then be used in a visible / enabled statement. This is similar to the usage of the core expressions we have seen earlier.

Create a RCP application "de.vogella.rcp.commands.sourceprovider" with the template "Hello RCP".

We will create a source provider. This source provider can provide variables which can be used in defining the visibility of commands. Add the extension point "org.eclipse.ui.services" to your plugin and create a new service provider.

This defines a service which provides the variable "de.vogella.rcp.commands.sourceprovider.active" to the workbench. This class must implement ISourceProvider. This value can then be used similar to a core expression. Maintain the following code.

   
package de.vogella.rcp.commands.sourceprovider;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.ui.AbstractSourceProvider;
import org.eclipse.ui.ISources;

public class CommandState extends AbstractSourceProvider {
public final static String MY_STATE = "de.vogella.rcp.commands.sourceprovider.active";
public final static String ENABLED = "ENABLED";
public final static String DISENABLED = "DISENABLED";
private boolean enabled = true;


@Override
public void dispose() {
}

// We could return several values but for this example one value is sufficient
@Override
public String[] getProvidedSourceNames() {
return new String[] { MY_STATE };
}

// You cannot return NULL
@SuppressWarnings("unchecked")
@Override
public Map getCurrentState() {
Map map = new HashMap(1);
String value = enabled ? ENABLED : DISENABLED;
map.put(MY_STATE, value);
return map;
}



// This method can be used from other commands to change the state
// Most likely you would use a setter to define directly the state and not use this toogle method
// But hey, this works well for my example
public void toogleEnabled() {
enabled = !enabled ;
String value = enabled ? ENABLED : DISENABLED;
fireSourceChanged(ISources.WORKBENCH, MY_STATE, value);
}

}

Create two commands "de.vogella.rcp.commands.sourceprovider.command1" and "de.vogella.rcp.commands.sourceprovider.command2". Create any handler you want for the first command. Command2 will be used to change the state in our ISourceProvider. Maintain the following code for the handler.

   
package de.vogella.rcp.commands.sourceprovider.handler;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.services.ISourceProviderService;

import de.vogella.rcp.commands.sourceprovider.CommandState;

public class Command2 extends AbstractHandler {

@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
// Get the source provider service
ISourceProviderService sourceProviderService = (ISourceProviderService) HandlerUtil
.getActiveWorkbenchWindow(event).getService(
ISourceProviderService.class);
// Now get my service
CommandState commandStateService = (CommandState) sourceProviderService
.getSourceProvider(CommandState.MY_STATE);
commandStateService.toogleEnabled();
return null;
}

}

Add both commands to the menu.

Now use the state provided by your ISourceProvider in your declaration of your menu.

This looks in plugin.xml like the following.

   
point="org.eclipse.ui.menus">
locationURI="menu:org.eclipse.ui.main.menu">
commandId="de.vogella.rcp.commands.sourceprovider.command1"
label="Command1"
style="push">
checkEnabled="false">
variable="de.vogella.rcp.commands.sourceprovider.active">
value="ENABLED">




commandId="de.vogella.rcp.commands.sourceprovider.command2"
label="Command2"
style="push">



If you now start your application can select the second command the first command will not be available anymore. If you press it again the first command will be displayed again.

0 comments:

Post a Comment