使用编程菜单时如何管理命令参数
How to manage command parameters when using programmatic menu
我正在使用 MenuContribution 提供菜单条目,实现类似于 E3 中的 "switch workspace" 的功能。
在动态菜单贡献中,我正在构建一个包含最近打开的项目的 3 项列表,然后是 "Other.." 条目。
从图形上看,我完成了,显示了 3 个列表、分隔符和 "other.." 菜单元素。
但是对于最近的项目,我必须动态地将项目 name/Path 传递给使用选择事件的处理程序。
下面是一个类似于我在菜单贡献中的代码,它创建了最近的 3 个项目之一:
@AboutToShow
public void aboutToShow(List<MMenuElement> items, MApplication application) {
MHandledMenuItem dynamicItem = modelService.createModelElement(MHandledMenuItem.class);
dynamicItem.setLabel(projectName);
dynamicItem.setContributorURI("platform:/plugin/com.acme");
MCommand command = modelService.createModelElement(MCommand.class);
command.setElementId(LOAD_PROJECT_COMMAND_ID);
MCommandParameter commandParam = modelService.createModelElement(MCommandParameter.class);
commandParam.setElementId(PROJECT_NAME_PARAMETER_ID);
commandParam.setName(PROJECT_NAME_PARAMETER_ID);
command.getParameters().add(commandParam);
// one of the 3 last used projects
String projectName = "foo";
dynamicItem.setCommand(command);
items.add(dynamicItem);
}
其中 LOAD_PROJECT_COMMAND_ID 和 PROJECT_NAME_PARAMETER_ID 是 e4xmi 命令和命令参数 ID。
我想知道如何将 projectName 放入命令中以便能够将其返回到关联的处理程序中,其中包含类似的内容:
@Execute
public void execute(ParameterizedCommand command) {
[...]
}
注意:我阅读了 Lars tutorial about menus 但没有在其中找到解决方案
--- 编辑:完整贡献代码 ---
import java.util.Collections;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.eclipse.e4.core.commands.ECommandService;
import org.eclipse.e4.ui.di.AboutToShow;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.commands.MCommand;
import org.eclipse.e4.ui.model.application.commands.MParameter;
import org.eclipse.e4.ui.model.application.ui.menu.MDirectMenuItem;
import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
import org.eclipse.e4.ui.model.application.ui.menu.MMenuSeparator;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import com.acme.model.platypus.extractionresult.CampaignResultProvider;
@SuppressWarnings("restriction")
public class SwitchProjectMenuContribution {
private static final String NEW_PROJECT = "Other...";
private static final String LOAD_PROJECT_COMMAND_ID = "gui.rcp4.command.loadProjectCommand";
private static final String PROJECT_NAME_PARAMETER_ID = "gui.rcp4.command.loadProjectCommand.projectName";
@Inject
CampaignResultProvider campaignResultProvider;
@Inject
private EModelService modelService;
@Inject
ECommandService commandService;
private MDirectMenuItem otherProjectItem;
private MMenuSeparator separatorItem;
private MCommand loadProjectCommand;
@SuppressWarnings("unchecked")
@PostConstruct
public void initialize(MApplication application) {
loadProjectCommand = (MCommand) modelService
.findElements(application, LOAD_PROJECT_COMMAND_ID, MCommand.class, Collections.EMPTY_LIST).get(0);
otherProjectItem = modelService.createModelElement(MDirectMenuItem.class);
otherProjectItem.setLabel(NEW_PROJECT);
otherProjectItem.setContributorURI("platform:/plugin/com.acme.gui.rcp4");
otherProjectItem.setContributionURI(
"bundleclass://com.acme.gui.rcp4/com.acme.gui.rcp4.handlers.OtherProjecthandler");
separatorItem = modelService.createModelElement(MMenuSeparator.class);
}
@AboutToShow
public void aboutToShow(List<MMenuElement> items, MApplication application) {
String[] lastProject = campaignResultProvider.getLastUsed();
MMenuElement newEntry;
for (String projectName : lastProject) {
newEntry = createExistingProjectEntry(projectName);
items.add(newEntry);
}
if (lastProject.length > 0) {
items.add(separatorItem);
}
items.add(otherProjectItem);
}
private MHandledMenuItem createExistingProjectEntry(String projectPath) {
MHandledMenuItem dynamicItem = modelService.createModelElement(MHandledMenuItem.class);
dynamicItem.setLabel(projectPath);
dynamicItem.setContributorURI("platform:/plugin/com.acme.gui.rcp4");
MParameter commandParam = modelService.createModelElement(MParameter.class);
commandParam.setName("projectName");
commandParam.setElementId(PROJECT_NAME_PARAMETER_ID);
commandParam.setValue(projectPath);
dynamicItem.getParameters().add(commandParam);
dynamicItem.setCommand(loadProjectCommand);
return dynamicItem;
}
}
您将参数值添加到 MHandledMenuItem
而不是命令。
使用 MParameter
并调用 setName
和 setValue
方法来设置名称(必须与命令中的参数名称匹配)和值(您的项目名称) ).
将 MParameter
添加到 MHandledMenuItem.getParameters()
列表。
注意:您应该只定义一次命令和命令参数,而不是每次调用 aboutToShow
时(所以它可能应该在 e4xmi 文件中)。
我正在使用 MenuContribution 提供菜单条目,实现类似于 E3 中的 "switch workspace" 的功能。 在动态菜单贡献中,我正在构建一个包含最近打开的项目的 3 项列表,然后是 "Other.." 条目。 从图形上看,我完成了,显示了 3 个列表、分隔符和 "other.." 菜单元素。
但是对于最近的项目,我必须动态地将项目 name/Path 传递给使用选择事件的处理程序。 下面是一个类似于我在菜单贡献中的代码,它创建了最近的 3 个项目之一:
@AboutToShow
public void aboutToShow(List<MMenuElement> items, MApplication application) {
MHandledMenuItem dynamicItem = modelService.createModelElement(MHandledMenuItem.class);
dynamicItem.setLabel(projectName);
dynamicItem.setContributorURI("platform:/plugin/com.acme");
MCommand command = modelService.createModelElement(MCommand.class);
command.setElementId(LOAD_PROJECT_COMMAND_ID);
MCommandParameter commandParam = modelService.createModelElement(MCommandParameter.class);
commandParam.setElementId(PROJECT_NAME_PARAMETER_ID);
commandParam.setName(PROJECT_NAME_PARAMETER_ID);
command.getParameters().add(commandParam);
// one of the 3 last used projects
String projectName = "foo";
dynamicItem.setCommand(command);
items.add(dynamicItem);
}
其中 LOAD_PROJECT_COMMAND_ID 和 PROJECT_NAME_PARAMETER_ID 是 e4xmi 命令和命令参数 ID。 我想知道如何将 projectName 放入命令中以便能够将其返回到关联的处理程序中,其中包含类似的内容:
@Execute
public void execute(ParameterizedCommand command) {
[...]
}
注意:我阅读了 Lars tutorial about menus 但没有在其中找到解决方案
--- 编辑:完整贡献代码 ---
import java.util.Collections;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.eclipse.e4.core.commands.ECommandService;
import org.eclipse.e4.ui.di.AboutToShow;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.commands.MCommand;
import org.eclipse.e4.ui.model.application.commands.MParameter;
import org.eclipse.e4.ui.model.application.ui.menu.MDirectMenuItem;
import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
import org.eclipse.e4.ui.model.application.ui.menu.MMenuSeparator;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import com.acme.model.platypus.extractionresult.CampaignResultProvider;
@SuppressWarnings("restriction")
public class SwitchProjectMenuContribution {
private static final String NEW_PROJECT = "Other...";
private static final String LOAD_PROJECT_COMMAND_ID = "gui.rcp4.command.loadProjectCommand";
private static final String PROJECT_NAME_PARAMETER_ID = "gui.rcp4.command.loadProjectCommand.projectName";
@Inject
CampaignResultProvider campaignResultProvider;
@Inject
private EModelService modelService;
@Inject
ECommandService commandService;
private MDirectMenuItem otherProjectItem;
private MMenuSeparator separatorItem;
private MCommand loadProjectCommand;
@SuppressWarnings("unchecked")
@PostConstruct
public void initialize(MApplication application) {
loadProjectCommand = (MCommand) modelService
.findElements(application, LOAD_PROJECT_COMMAND_ID, MCommand.class, Collections.EMPTY_LIST).get(0);
otherProjectItem = modelService.createModelElement(MDirectMenuItem.class);
otherProjectItem.setLabel(NEW_PROJECT);
otherProjectItem.setContributorURI("platform:/plugin/com.acme.gui.rcp4");
otherProjectItem.setContributionURI(
"bundleclass://com.acme.gui.rcp4/com.acme.gui.rcp4.handlers.OtherProjecthandler");
separatorItem = modelService.createModelElement(MMenuSeparator.class);
}
@AboutToShow
public void aboutToShow(List<MMenuElement> items, MApplication application) {
String[] lastProject = campaignResultProvider.getLastUsed();
MMenuElement newEntry;
for (String projectName : lastProject) {
newEntry = createExistingProjectEntry(projectName);
items.add(newEntry);
}
if (lastProject.length > 0) {
items.add(separatorItem);
}
items.add(otherProjectItem);
}
private MHandledMenuItem createExistingProjectEntry(String projectPath) {
MHandledMenuItem dynamicItem = modelService.createModelElement(MHandledMenuItem.class);
dynamicItem.setLabel(projectPath);
dynamicItem.setContributorURI("platform:/plugin/com.acme.gui.rcp4");
MParameter commandParam = modelService.createModelElement(MParameter.class);
commandParam.setName("projectName");
commandParam.setElementId(PROJECT_NAME_PARAMETER_ID);
commandParam.setValue(projectPath);
dynamicItem.getParameters().add(commandParam);
dynamicItem.setCommand(loadProjectCommand);
return dynamicItem;
}
}
您将参数值添加到 MHandledMenuItem
而不是命令。
使用 MParameter
并调用 setName
和 setValue
方法来设置名称(必须与命令中的参数名称匹配)和值(您的项目名称) ).
将 MParameter
添加到 MHandledMenuItem.getParameters()
列表。
注意:您应该只定义一次命令和命令参数,而不是每次调用 aboutToShow
时(所以它可能应该在 e4xmi 文件中)。