Eclipse RCP菜单和动作:配置还是代码?
-
12-10-2019 - |
题
这是一个普遍的问题,但我目前的问题围绕菜单处理。
在带有贡献菜单操作的普通插件中,您将在插件配置中配置操作集等。这显然是明智的。
我正在研究RCP应用程序(实际上是RAP),我想知道是否值得通过plugin.xml配置所有内容。我的插件不必与其他未知插件进行交互,因此从理论上讲,我具有控制权。我可以以编程方式添加菜单和动作。
我一直在尝试配置包含子菜单的菜单。我尝试定义动作集并将一个链接在另一个内部,但没有成功。有些项目需要根据用户角色禁用。
我认为我本可以在几分钟内对整个编码进行编码,但是我不确定这是否适合Eclipse的“精神”。
那里有什么意见?该应用程序将变得相当大,因此我想从一开始就可以立即获得该方法。也许有人可以指向我配置嵌套菜单的示例:-)
解决方案
我认为插件.xml实现是必经之路。
我使用此方法的两个主要原因:
- 在不编写Java代码的情况下重新配置和重组菜单和按钮确实很容易。
- 菜单树的非常清晰的分层可视化。
这是实现菜单和子菜单的代码段。在此示例中,它们将添加到主菜单中。
您可以将其粘贴到您的plugin.xml中:
<extension
name="Main Menu Contributions"
point="org.eclipse.ui.menus">
<menuContribution
allPopups="false"
locationURI="menu:org.eclipse.ui.main.menu">
<menu
id="fileMenu"
label="File">
<command
commandId="org.eclipse.ui.file.exit"
label="Exit"
style="push">
</command>
</menu>
<menu
label="Edit">
<command
commandId="org.eclipse.ui.edit.selectAll"
label="Select All"
style="push">
</command>
<menu
label="Submenu">
<command
commandId="org.eclipse.ui.edit.selectAll"
label="Select All Submenu"
style="push">
</command>
<command
commandId="org.eclipse.ui.edit.delete"
label="Delete submenu"
style="push">
</command>
</menu>
</menu>
</menuContribution>
</extension>
要激活/停用菜单,您必须使用核心表达式来启用/禁用命令处理程序。如果命令没有任何活动处理程序,则将被禁用。因此,调用该命令的菜单项也将被禁用。
以下代码片段显示了如何在视图工具栏上创建按钮,并根据变量的值启用/禁用它。请记住,您必须在此代码中更改一些内容才能使其正常工作。大多数更改都是用于参考名称和类实现。
在工具栏(plugin.xml)中创建按钮:
<extension
name="View Toolbar Contributions"
point="org.eclipse.ui.menus">
<menuContribution
allPopups="false"
locationURI="toolbar:myapp.views.MyView">
<command
commandId="myapp.commands.PauseSound"
icon=""
label="Pause Playback Sound"
style="push"
tooltip="Pause">
</command>
</menuContribution>
</extension>
创建命令(plugin.xml):
<extension
id="myapp.commands.PauseSound"
name="Pause sound command"
point="org.eclipse.ui.commands">
<command
id="myapp.commands.PauseSound"
name="Pause Sound">
</command>
</extension>
创建命令处理程序(plugin.xml):
<extension
point="org.eclipse.ui.handlers">
<handler
commandId="myapp.commands.PauseSound">
<activeWhen>
<with
variable="myapp.commands.sourceprovider.active">
<or>
<equals
value="PLAYING">
</equals>
<equals
value="PAUSED">
</equals>
</or>
</with>
</activeWhen>
<class
class="myapp.rcp.commands.toolbar.PausePlayback">
</class>
</handler>
</extension>
为命令(plugin.xml)创建状态变量:
<extension
point="org.eclipse.ui.services">
<sourceProvider
provider="myapp.commands.sourceprovider.CommandState">
<variable
name="myapp.commands.sourceprovider.active"
priorityLevel="workbench">
</variable>
</sourceProvider>
</extension>
实施更改变量状态的类:
public class CommandState extends AbstractSourceProvider {
public final static String STATE = "myapp.commands.sourceprovider.active";
public final static String STOPPED = "STOPPED";
public final static String PLAYING = "PLAYING";
public final static String PAUSED = "PAUSED";
public final static String NOT_LOADED = "NOT_LOADED";
enum State {
NOT_LOADED, PLAYING, PAUSED, STOPPED
};
private State curState = State.NOT_LOADED;
@Override
public void dispose() {
}
@Override
public String[] getProvidedSourceNames() {
return new String[] { STATE };
}
// You cannot return NULL
@SuppressWarnings("unchecked")
@Override
public Map getCurrentState() {
Map map = new HashMap(1);
if (curState == State.PLAYING)
map.put(STATE, PLAYING);
else if (curState == State.STOPPED)
map.put(STATE, STOPPED);
else if (curState == State.PAUSED)
map.put(STATE, PAUSED);
return map;
}
public void setPlaying() {
fireSourceChanged(ISources.WORKBENCH, STATE, PLAYING);
}
public void setPaused() {
fireSourceChanged(ISources.WORKBENCH, STATE, PAUSED);
}
public void setStopped() {
fireSourceChanged(ISources.WORKBENCH, STATE, STOPPED);
}
public void setNotLoaded() {
fireSourceChanged(ISources.WORKBENCH, STATE, NOT_LOADED);
}
}
有关如何实现这些功能的更多详细信息,请参见这些位置:
其他提示
对于Eclipse,有两种不同的方法可以为Workbench做出贡献:动作和命令。
我绝对建议这些命令是更新的,比动作更先进。此处指定的操作的缺点(1):
- UI和处理总是绑定的。您无法互相分开
- 虽然动作可以为工作台的不同部分(弹出菜单/工具栏)做出贡献,但它们都是不同的扩展点,因此您最终会在多个位置重复XML。最糟糕的是,并非所有扩展点都期望相同的配置。
- 在多个地方指定动作是一场维护噩梦。如果您必须更改操作的图标,则需要在所有位置进行更改。
在plugin.xml中重复操作的另一个问题是,将在内存中创建相同动作的多个实例
(1) 动作与命令
如果您正在编写RCP应用程序,那么好的做法是在您的ActionBaradvisor中创建持有人。虽然这将定义菜单和工具栏的基本结构,但您可以扩展菜单限制并使用命令来贡献实际的菜单/工具项。
要在RCP中添加操作,您还可以使用applicationActinBaracVisor。它比在此方面的上述解决方案更容易,您只需要首先将动作声明为iWorkBenchaction的对象,然后在方法“受保护的void makeactions(iworkbenchwindow window)中”注册。最后一步是将其添加到菜单中。以下代码将帮助您。
1.首先声明行动: -
private IWorkbenchAction newAction
2.注册行动: -
protected void makeActions(IWorkbenchWindow window) {
newAction = ActionFactory.NEW_WIZARD_DROP_DOWN.create(window);
register(newAction);
newAction.setText("New");
3.last步骤是在菜单中添加操作: -
MenuManager filemenu = new MenuManager("&File", "file");
filemenu.add(newAction);
您还可以在工具栏中添加操作,如下所示: -
protected void fillCoolBar(ICoolBarManager coolBar) {
IToolBarManager toolbar = new ToolBarManager(coolBar.getStyle());
coolBar.add(toolbar);
toolbar.add(newAction);