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

时间:2014-01-14 19:27:44

标签: java eclipse-plugin

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

 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类型的参数。 (因为参数化)

我想传递哈希映射的参数,并且通常传递任何对象。

我试过这段代码

     IServiceLocator serviceLocator = PlatformUI.getWorkbench();
    ICommandService commandService = (ICommandService)      serviceLocator.getService(ICommandService.class);




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

但它不起作用参数没有移动(它为空)

请帮忙将对象作为参数移动到命令中?

4 个答案:

答案 0 :(得分:3)

由于在我的第一个答案中添加另一个解决方案会让人感到困惑,我将为另一个解决方案提供另一个解决方案。 我给出的选择是“A)使用”执行事件“的选定对象(检查它,它包含很多信息).B)你可以使用AbstractSourceProvider,所以你可以将你的对象传递给应用程序上下文。”< / p> 如果您的对象是树的结构化对象的选择,则可以在您的处理程序中使用

MyObject p = (MyObject) ((IStructuredSelection) HandlerUtil.getCurrentSelection(event)).getFirstElement();

B)使用Source提供程序有点棘手。主要思想是,将对象添加到应用程序上下文中。 Eclipse 3.x的重要摘录来自我在阅读this blog后设置的项目(注意:它是德语,它提供的示例不起作用): 在你的plugin.xml中添加:

  <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 对象):

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并将Object设置为要传输到Handler的对象。

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);
        }
    });
}

在你的处理程序中,你可以调用PersonSourceProvider#getCurrentState来恢复你的对象。

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

答案 1 :(得分:2)

参数化命令仅接受字符串。 以下是较小对象的示例:

免责声明:这适用于Eclipse 3.x.我没有经常使用Eclipse 4.x,所以如果你需要它,你可能必须适应它。

使用View(com.voo.example.commandparameter.advanced.view),一个Command(com.voo.example.commandparameter.advanced.sysoCommand)创建一个Pluginproject(com.voo.example.commandparameter.advanced)菜单项和Handler(com.voo.example.commandparameter.advanced.sysoCommand)和一个通用对象(MyTestObject)。

Command需要在plugin.xml中输入一个参数和一个Parametertype,然后传递给它:

<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>

在对象中设置atrtibutes,如name和street,并定义一个convertToString方法,如:

public String convertToString() {
    return getName() +",,,"+ getStreet();
}

(您也可以覆盖toString方法。我只是使用该方法将已经分隔的分隔符设置为返回的String)    在类MyParamterConverter中,您可以将其传回:

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);
}
}

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

    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可以将传递的参数转换回来:

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,因此您可以将对象传递给应用程序上下文。

答案 2 :(得分:0)

我对此并不熟悉,因为将参数传递给命令非常少见。您似乎必须在commandParameterType命令定义中使用org.eclipse.ui.commands来定义基于AbstractParameterValueConverter的代码,以在对象和参数值的字符串之间进行转换。

答案 3 :(得分:0)

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

来电者:

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);

在您的处理程序中:

@Execute
public void execute(@Optional MyObject myObject) {
  if(myObject != null) {
    // work with your object
  }
}

Voila,不需要任何转换器或回调(即SelectionService)...

相关问题