我认为您最左边的ToolBar 为空的原因是布局问题。在下面的代码中,当我在 custom ToolBar 之外没有任何按钮但仍在 main @ 中时,我遇到了类似的“空”ToolBar 问题987654326@。添加“foo”和“bar”按钮修复了布局问题,但我无法找出对layout() 或pack() 的正确调用来修复它。我认为这可能与the bug here有关。
我尝试创建一个类似的 ToolBar,并围绕“RCP 邮件模板”插件项目构建,您可以从“新插件项目”向导创建该项目。
为了解决您的前两个问题,我在示例 RCP 包中创建了 3 个包(我将我的项目称为“com.bar.foo”):
-
com.bar.foo.actions - 包含扩展
ContributionControl 并包装 Combo 和 Text 小部件的类。这些与数据模型无关,只是担心创建小部件。
-
com.bar.foo.model - 包含数据模型。我只是在这里建立了一个简单的模型,其中包含一个 IP、掩码、网关和一两个有用的方法。
-
com.bar.foo.toolBar - 这些类通过
org.eclipse.ui.menus 扩展点插入到主 UI ToolBar。他们将数据模型链接到第一个包中的ContributionControls。这里最重要的类是ToolBarContribution,它有效地集中了所有听众。这使您可以更轻松地将小部件的侦听器链接到同一模型。
这是ToolBarContribution 的来源(请注意,它解决了您的前两个问题,因为它将侦听器连接到模型并且为 UI 提供了自己的ToolBar):
package com.bar.foo.toolBar;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
import com.bar.foo.actions.ComboContributionItem;
import com.bar.foo.actions.TextContributionItem;
import com.bar.foo.model.NetworkConfig;
public class ToolBarContribution extends WorkbenchWindowControlContribution {
// Our data model.
private NetworkConfig configuration = new NetworkConfig();
// Each of these corresponds to a widget in the ToolBar.
private Action scanAction;
private ComboContributionItem sourceCombo;
private TextContributionItem ipText;
private TextContributionItem maskText;
private TextContributionItem gatewayText;
@Override
protected Control createControl(Composite parent) {
setupContributionItems();
// Let's not get our hands messy with SWT... add IActions or
// IContributionItems to a ToolBarManager and let the ToolBarManager
// create the SWT ToolBar.
ToolBarManager manager = new ToolBarManager();
manager.add(scanAction);
manager.add(sourceCombo);
manager.add(ipText);
manager.add(maskText);
manager.add(gatewayText);
ToolBar toolBar = manager.createControl(parent);
// Highlight the ToolBar in red.
toolBar.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_RED));
return toolBar;
}
private void setupContributionItems() {
scanAction = new Action("Scan Host") {
@Override
public void run() {
System.out.println("Scanning...");
String host = sourceCombo.getComboControl().getText();
configuration.scanHost(host);
System.out.println("Scanned!");
refreshTexts();
}
};
scanAction.setToolTipText("Scans the host for a configuration.");
final SelectionListener comboListener = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
ipText.getTextControl().setText("");
maskText.getTextControl().setText("");
gatewayText.getTextControl().setText("");
}
};
sourceCombo = new ComboContributionItem("sourceCombo") {
@Override
public Control createControl(Composite parent) {
// Let ComboContributionItem create the initial control.
Control control = super.createControl(parent);
// Now customize the Combo widget.
Combo combo = getComboControl();
combo.setItems(configuration.getAvailableHosts());
combo.addSelectionListener(comboListener);
// Return the default control.
return control;
}
};
ipText = new TextContributionItem("ipText", SWT.BORDER | SWT.SINGLE
| SWT.READ_ONLY);
maskText = new TextContributionItem("maskText");
gatewayText = new TextContributionItem("gatewayText");
}
private void refreshTexts() {
ipText.getTextControl().setText(configuration.getIP());
maskText.getTextControl().setText(configuration.getMask());
gatewayText.getTextControl().setText(configuration.getGateway());
}
}
除了这个ToolBar,我在主 UIToolBar 中有两个单独的按钮,一个在 customToolBar 之前,一个在 custom 之后。它们的来源在 com.bar.foo.toolBar 包中。这是第一个命令:
package com.bar.foo.toolBar;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
public class FooHandler extends AbstractHandler {
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
System.out.println("foo");
return null;
}
}
这是第二个:
package com.bar.foo.toolBar;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
public class BarHandler extends AbstractHandler {
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
System.out.println("bar");
return null;
}
}
由于我对您的数据了解不多,所以我不得不创建自己的模型。 com.bar.foo.model 包中的模型只是一个类:
package com.bar.foo.model;
public class NetworkConfig {
private String ip = "";
private String mask = "";
private String gateway = "";
public String[] getAvailableHosts() {
return new String[] { "fooHost" };
}
public void scanHost(String host) {
if ("fooHost".equals(host)) {
ip = "192.168.1.2";
mask = "255.255.255.0";
gateway = "192.168.1.1";
} else {
ip = "";
mask = "";
gateway = "";
}
}
public String getIP() {
return ip;
}
public String getMask() {
return mask;
}
public String getGateway() {
return gateway;
}
}
现在是 com.bar.foo.actions 包,其中包含自定义 ToolBar 中的 ControlContributions。请注意,这两个类都与模型无关,它们可以在产品的其他地方重复使用。
第一个类只是包装了一个Combo 小部件。最初可以通过覆盖controlCreated(Combo) 方法来自定义小部件。我在ToolBarContribution 类中使用它来添加SelectionListener 并设置Combo 的项目。这是课程:
package com.bar.foo.actions;
import org.eclipse.jface.action.ControlContribution;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
public class ComboContributionItem extends ControlContribution {
private Combo combo;
public ComboContributionItem(String id) {
super(id);
}
@Override
protected Control createControl(Composite parent) {
combo = new Combo(parent, SWT.READ_ONLY | SWT.V_SCROLL | SWT.H_SCROLL);
return combo;
}
@Override
public int computeWidth(Control control) {
// The widget is now 100 pixels. You can new GC gc = new GC(control) and
// use the gc.stringExtent(String) method to help compute a more dynamic
// width.
return 100;
}
public Combo getComboControl() {
return combo;
}
}
这个包中的另一个类包装了一个Text 小部件:
package com.bar.foo.actions;
import org.eclipse.jface.action.ControlContribution;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;
public class TextContributionItem extends ControlContribution {
private final int style;
private Text text;
public TextContributionItem(String id) {
this(id, SWT.BORDER | SWT.SINGLE);
}
public TextContributionItem(String id, int style) {
super(id);
this.style = style;
}
@Override
protected Control createControl(Composite parent) {
text = new Text(parent, style);
return text;
}
@Override
public int computeWidth(Control control) {
return 100;
}
public Text getTextControl() {
return text;
}
}
我没有这样做,但是如果您需要为您的 ToolBar 进一步自定义 Text 小部件,您可以像初始化 ComboContributionItem 时那样覆盖 createControl(Composite) 方法。
最后一件事:我使用扩展来自定义ToolBar。但是,ToolBarContribution 使用的相同逻辑适用于您的fillCoolBar(ICoolBarManager) 方法或createControl(Composite) 方法,具体取决于您最终希望修改哪个ToolBar。
就我而言,这是我添加到插件plugin.xml 末尾的内容:
<extension
point="org.eclipse.ui.menus">
<menuContribution
locationURI="toolbar:org.eclipse.ui.main.toolbar">
<toolbar
id="com.bar.foo.toolbar">
<command
commandId="com.bar.foo.commands.foo"
label="Foo"
style="push">
</command>
<control
class="com.bar.foo.toolBar.ToolBarContribution">
</control>
<command
commandId="com.bar.foo.commands.bar"
label="Bar"
style="push">
</command>
</toolbar>
</menuContribution>
</extension>
<extension
point="org.eclipse.ui.commands">
<command
id="com.bar.foo.commands.foo"
name="Foo">
</command>
<command
id="com.bar.foo.commands.bar"
name="Bar">
</command>
</extension>
<extension
point="org.eclipse.ui.handlers">
<handler
class="com.bar.foo.toolBar.FooHandler"
commandId="com.bar.foo.commands.foo">
</handler>
<handler
class="com.bar.foo.toolBar.BarHandler"
commandId="com.bar.foo.commands.bar">
</handler>
</extension>
这些命令被连接起来,以便在 custom ToolBar 之前有一个用于FooHandler 的按钮,在 custom ToolBar 之后有一个用于BarHandler 的按钮.这些命令在 xml 中指定的顺序将反映在应用程序中。同样,将项目添加到 custom ToolBar 的顺序将反映在您的产品中。
关于位置的另一个注意事项:您可以通过在 locationURI 的查询中设置位置来使 menuContributions 出现在不同的位置,例如,toolbar:org.eclipse.ui.main.toolbar?after=additions。 “之前”是另一个与“之后”类似的展示位置关键字。更多例子可以在in this Eclipse help doc找到。