首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在命令中传递对象参数?

如何在命令中传递对象参数?
EN

Stack Overflow用户
提问于 2014-01-14 19:27:43
回答 4查看 5.1K关注 0票数 5

我用一个带有参数的新命令创建了eclipse项目的plugin.xml。

代码语言:javascript
复制
 ArrayList<parameterization> parameters = new ArrayList<parameterization>();
 IParameter iparam;

 //get the command from plugin.xml
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
 ICommandService cmdService =     (ICommandService)window.getService(ICommandService.class);
 Command cmd = cmdService.getCommand("org.ipiel.demo.commands.click");

//get the parameter
iparam = cmd.getParameter("org.ipiel.demo.commands.click.paramenter1");
Parameterization params = new Parameterization(iparam, "commandValue");
parameters.add(params);

//build the parameterized command
 ParameterizedCommand pc = new ParameterizedCommand(cmd, parameters.toArray(new       Parameterization[parameters.size()]));

//execute the command
 IHandlerService handlerService = (IHandlerService)window.getService(IHandlerService.class);
handlerService.executeCommand(pc, null);

我试过这个例子来传递参数,它起了作用。

本例中的问题是,我只能传递String类型的参数。(因为参数化)

我希望传递散列映射的参数,并通常传递任何对象。

我试过这段代码

代码语言:javascript
复制
     IServiceLocator serviceLocator = PlatformUI.getWorkbench();
    ICommandService commandService = (ICommandService)      serviceLocator.getService(ICommandService.class);




    ExecutionEvent executionEvent = new ExecutionEvent(cmd, paramArray, null, null);
    cmd.executeWithChecks(executionEvent);

但是它没有工作参数没有移动(它是空的)

您能帮我把对象作为命令中的参数吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-01-20 11:55:09

因为在我的第一个答案中添加另一个解决方案会变得很混乱,所以我将为第二个解决方案提供另一个解决方案。我给出的选择是“A)使用选定的”执行事件“对象(检查它包含了很多信息)。B)您可以使用AbstractSourceProvider,这样就可以将对象传递给应用程序上下文。”

如果您的对象是像Tree这样的结构化对象的选择,则可以在您的Handler中使用:

代码语言:javascript
复制
MyObject p = (MyObject) ((IStructuredSelection) HandlerUtil.getCurrentSelection(event)).getFirstElement();

( B)源提供程序的使用要复杂一些。主要思想是,将对象添加到应用程序上下文中。Eclipse3.x的重要片段来自我在阅读这个博客之后设置的一个项目(注意:它是德语的,它提供的示例不起作用):在plugin.xml中添加:

代码语言:javascript
复制
  <extension point="org.eclipse.ui.services">
  <sourceProvider
        provider="com.voo.example.sourceprovider.PersonSourceProvider">
     <variable
           name="com.voo.example.sourceprovider.currentPerson"
           priorityLevel="activePartId">
     </variable>
  </sourceProvider>

建立自己的SourceProvider。调用"getCurrentState“可以获得该SourceProvider的变量(在本例中为Person对象):

代码语言:javascript
复制
public class PersonSourceProvider extends AbstractSourceProvider{

/** This is the variable that is used as reference to the SourceProvider
 */
public static final String PERSON_ID = "com.voo.example.sourceprovider.currentPerson";
private Person currentPerson;

public PersonSourceProvider() {

}

@Override
public void dispose() {
    currentPerson = null;
}

**/**
 * Used to get the Status of the source from the framework
 */
@Override
public Map<String, Person> getCurrentState() {
    Map<String, Person> personMap = new HashMap<String, Person>();
    personMap.put(PERSON_ID, currentPerson);
    return personMap;
}**

@Override
public String[] getProvidedSourceNames() {
    return new String[]{PERSON_ID};
}

public void personChanged(Person p){
    if (this.currentPerson != null && this.currentPerson.equals(p)){
        return;
    }

    this.currentPerson = p;
    fireSourceChanged(ISources.ACTIVE_PART_ID, PERSON_ID, this.currentPerson);
}

}

在您的视图中,您注册到SourceProvider,并将对象设置为要传输到您的Handler的对象。

代码语言:javascript
复制
public void createPartControl(Composite parent) {

    viewer = new TreeViewer(parent);
    viewer.setLabelProvider(new ViewLabelProvider());
    viewer.setContentProvider(new ViewContentProvider());
    viewer.setInput(rootPerson);
    getSite().setSelectionProvider(viewer);
    viewer.addSelectionChangedListener(new ISelectionChangedListener() {
        @Override
        public void selectionChanged(SelectionChangedEvent event) {
            Person p = null;
            if (event.getSelection() instanceof TreeSelection) {
                TreeSelection selection = (TreeSelection) event.getSelection();
                if (selection.getFirstElement() instanceof Person) {
                    p = (Person) selection.getFirstElement();
                }
            }
            if (p==null) {
                return;
            }
            IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
            ISourceProviderService service = (ISourceProviderService) window.getService(ISourceProviderService.class);
            PersonSourceProvider sourceProvider = (PersonSourceProvider) service.getSourceProvider(PersonSourceProvider.PERSON_ID);
            sourceProvider.personChanged(p);
        }
    });
}

在您的Handler中,您只需调用PersonSourceProvider#getCurrentState来获取对象。

此方法的优点是,您可以在任何地方使用Objectd。例如,您甚至可以根据当前选定的对象设置一个PropertyTester来启用/禁用UI元素。

票数 5
EN

Stack Overflow用户

发布于 2014-01-16 06:43:36

参数化命令只接受字符串。下面是一个较小对象的示例:

免责声明:这是用于Eclipse3.x的。我并不经常使用Eclipse4.x,所以您可能需要在那里进行调整,以防需要它。

使用View (com.voo.example.commandparameter.advanced.view)创建一个Pluginproject (com.voo.example.commandparameter.advanced),一个带有菜单项和Handler(com.voo.example.commandparameter.advanced.sysoCommand),的命令(com.voo.example.commandparameter.advanced.sysoCommand)以及一个通用对象(MyTestObject)。

命令需要plugin.xml中的一个参数和一个参数类型,然后传递给它:

代码语言:javascript
复制
<extension
     point="org.eclipse.ui.commands">
  <command
        id="com.voo.example.commandparameter.advanced.sysoCommand"
        name="SysoCommand">
     <commandParameter
           id="myObject"
           name="object"
           optional="true"
           typeId="com.voo.example.commandparameter.advanced.testType">
     </commandParameter>
  </command>
  <commandParameterType
        id="com.voo.example.commandparameter.advanced.testType"
        type="com.voo.example.commandparameter.advanced.MyTestObject">
  </commandParameterType>

在像name和street这样的对象中设置atrtibutes,并定义这样的convertToString方法:

代码语言:javascript
复制
public String convertToString() {
    return getName() +",,,"+ getStreet();
}

(您也可以重写toString方法。我只是使用该方法将毛茸茸的分隔符设置为返回的字符串),在类MyParamterConverter中,您可以将其传回:

代码语言:javascript
复制
public class MyParameterConverter extends AbstractParameterValueConverter {

public MyParameterConverter() {

}

@Override
public String convertToString(Object parameterValue)
        throws ParameterValueConversionException {
    return parameterValue.toString();
}

/**
 * This will always create a new object. Just keep that in mind 
 * if you're trying to work with the objects.
 */
@Override
public Object convertToObject(String parameterValue)
        throws ParameterValueConversionException {

    //Split the String to get the attributes back
    String delimiter =",,,";
    String[] split = parameterValue.split(delimiter);
    String name = split[0];
    String street = split [1];

    return new MyTestObject(name, street);
}
}

现在,您可以在视图中单击按钮来调用该命令,例如:

代码语言:javascript
复制
    btnGo.addSelectionListener(new SelectionAdapter() {
        @Override
        public void widgetSelected(SelectionEvent event) {

            MyTestObject testObject = new MyTestObject(textName.getText(),textStreet.getText());

            ICommandService cS = (ICommandService)getSite().getService(ICommandService.class);
            IHandlerService hS = (IHandlerService)getSite().getService(IHandlerService.class);

            Command sysoComm = cS.getCommand("com.voo.example.commandparameter.advanced.sysoCommand");


            HashMap<String, String> params = new HashMap<String, String>();
            params.put("myObject", testObject.convertToString());

            ParameterizedCommand pC = ParameterizedCommand.generateCommand(sysoComm, params);

            try {
                hS.executeCommand(pC, null);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

而Handler可以将传递的参数转换回:

代码语言:javascript
复制
public class MyObjectHandler extends AbstractHandler {

@Override
public Object execute(ExecutionEvent event) throws ExecutionException { 
    String param1 = event.getParameter("myObject");
    MyParameterConverter converter = new MyParameterConverter();
    Object convertToObject = null;

    try {
        convertToObject = converter.convertToObject(param1);
    } catch (ParameterValueConversionException e) {
        e.printStackTrace();
    }

    if (convertToObject instanceof MyTestObject) {
        MyTestObject to = (MyTestObject) convertToObject;
        System.out.println(to.toString());
    }

    return null;
}
}

这应该适用于大多数较小的对象,这些对象在传递时不会更改。如果您需要传递更大的对象,您将有两个选择: A)使用所选对象的“执行事件”(检查,它包含了大量的信息)。B)您可以使用AbstractSourceProvider,这样就可以将对象传递给应用程序上下文。

票数 3
EN

Stack Overflow用户

发布于 2018-09-28 14:27:32

很长一段时间以来,我一直专注于通过命令参数传递对象。但最后,最简单的解决方法是忽略参数填充,将所需的对象放入一个新的子IExclipseContext中,并使用该上下文执行命令。这样你的处理程序就会注入你的对象。

来电者:

代码语言:javascript
复制
ECommandService commandService = // get commandService...
EHandlerService handlerService = // get handlerService...
IEclipseContext context = // get active or application context...

IEclipseContext childCtx = context.createChild();
childCtx.set(MyObject.class, instancOfMyObject);

ParameterizedCommand command = commandService.createCommand("my.command.id", null);
handlerService.executeHandler(command, childCtx);

在您的处理程序中:

代码语言:javascript
复制
@Execute
public void execute(@Optional MyObject myObject) {
  if(myObject != null) {
    // work with your object
  }
}

瞧,没有转换器或回调(即SelectionService)需要.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21122233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档