【问题标题】:Eclipse RCP application custom toolbarEclipse RCP 应用程序自定义工具栏
【发布时间】:2014-11-23 17:27:52
【问题描述】:

我正在为我的 RCP 应用程序创建一个自定义工具栏。

  1. 如图所示,我想要一个带有其他三个文本框的下拉框。这些基本上都是输入框,相互依存。现在,这些盒子中的每一个都在不同的类中。我想把他们放在一个班级里,这样更容易为彼此创建听众。

    protected void fillCoolBar(ICoolBarManager coolBar) {
    
    IToolBarManager toolbar = new ToolBarManager(coolBar.getStyle());
    coolBar.add(toolbar);      
    
    Toolbar extraToolBar = new Toolbar("Toolbar");
    toolbar.add(extraToolBar);
    toolbar.add(new Separator());
    
    toolbar.add(new MyCombo("Demo Combo box"));
    toolbar.add(new Separator());
    
    toolbar.add(new IPaddress("Ip"));
    toolbar.add(new Separator());
    
    toolbar.add(new Mask("Mask"));
    toolbar.add(new Separator());
    
    toolbar.add(new Count("Count"));
    
    }
    
    public class IPaddress extends ControlContribution {
    
     Text textBox;
    
    
     public IPaddress(String id) {
         super(id);
        // TODO Auto-generated constructor stub
     }
    
     @Override
     protected Control createControl(Composite parent) {
    textBox = new Text(parent, SWT.MULTI | SWT.BORDER | SWT.WRAP);
    textBox.setLayoutData(new GridData(GridData.FILL_BOTH));
    textBox.addModifyListener(new ModifyListener(){
        public void modifyText(ModifyEvent event) {
            Text text = (Text) event.widget;
            System.out.println(text.getText());
        } 
    });
    return textBox;
    }
    
    }
    
  2. 因此,我想创建一个新的自定义工具栏,其中包含我想要的所有功能,然后将其保留在原始工具栏上。但不知何故,它只在左侧显示一个空栏。

    protected Control createControl(Composite parent) {
    toolBar = new ToolBar(parent, SWT.FLAT |SWT.BORDER);
    
    Device dev = toolBar.getDisplay();
    
    try {
        newi = new Image(dev, "C:\\Users\\RahmanAs\\ChipcoachWorkspace\\ChipCoach\\icons\\FileClose.png");
        opei = new Image(dev, "C:\\Users\\RahmanAs\\ChipcoachWorkspace\\ChipCoach\\icons\\FileOpen.png");
    
    
    } catch (Exception e) {
        System.out.println("Cannot load images");
        System.out.println(e.getMessage());
        System.exit(1);
    }
    
    
    ToolItem item0 = new ToolItem (toolBar, SWT.PUSH);
    item0.setImage(newi);
    item0.setText("Hello");
    
    ToolItem item1 = new ToolItem(toolBar, SWT.PUSH);
    item1.setText("Push");
    
    ToolItem item2 = new ToolItem(toolBar, SWT.PUSH);
    item2.setText("Pull");
    
    
    return toolBar;
    
    
    }
    
  3. 我也有运行按钮,这是我使用 Vogella 的教程在插件中创建的。但我不能以这种方式对他们的展示位置进行编程。 (例如,如果我一开始就想要它们。)有没有办法以编程方式创建它们?

【问题讨论】:

    标签: java user-interface eclipse-rcp rcp


    【解决方案1】:

    我认为您最左边的ToolBar 为空的原因是布局问题。在下面的代码中,当我在 custom ToolBar 之外没有任何按钮但仍在 main @ 中时,我遇到了类似的“空”ToolBar 问题987654326@。添加“foo”和“bar”按钮修复了布局问题,但我无法找出对layout()pack() 的正确调用来修复它。我认为这可能与the bug here有关。

    我尝试创建一个类似的 ToolBar,并围绕“RCP 邮件模板”插件项目构建,您可以从“新插件项目”向导创建该项目。

    为了解决您的前两个问题,我在示例 RCP 包中创建了 3 个包(我将我的项目称为“com.bar.foo”):

    1. com.bar.foo.actions - 包含扩展 ContributionControl 并包装 ComboText 小部件的类。这些与数据模型无关,只是担心创建小部件。
    2. com.bar.foo.model - 包含数据模型。我只是在这里建立了一个简单的模型,其中包含一个 IP、掩码、网关和一两个有用的方法。
    3. 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找到。

    【讨论】:

    • 欢迎来到 SO!如果您在回答之前需要一些澄清,请留下评论(下次,当您有足够的“声誉”时)现在,您为什么不只是展示您将如何做到这一点并添加一些示例代码?
    猜你喜欢
    • 2017-12-26
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多