Eclipse RCP应用程序自定义工具栏

时间:2014-09-29 10:37:15

标签: java user-interface eclipse-rcp rcp

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

enter image description here

  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的教程在插件中创建。但是我不能用这种方式编排他们的位置。 (例如,如果我在开头想要它们。)有没有办法以编程方式创建它们?

1 个答案:

答案 0 :(得分:2)

我认为最左边ToolBar为空的原因是布局问题。在我下面的代码中,我有一个类似的"空"如果我没有任何按钮位于自定义 ToolBar之外但仍位于 ToolBar中,则会出现ToolBar问题。添加" foo"和" bar"按钮修复了布局问题,但我找不到正确调用layout()pack()来修复它。我认为这可能与the bug here有关。

我开始创建一个类似ToolBar并围绕" RCP邮件模板"您可以从" New Plug-in Project"创建的插件项目。向导。

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

  1. com.bar.foo.actions - 包含扩展ContributionControl并包装ComboText小部件的类。这些与数据模型无关,只是担心创建小部件。
  2. com.bar.foo.model - 包含数据模型。我刚刚在这里用IP,掩码,网关和一两种有用的方法组成了一个简单的模型。
  3. com.bar.foo.toolBar - 这些类通过ToolBar扩展点插入主用户界面org.eclipse.ui.menus。他们将数据模型链接到第一个包中的ContributionControls。这里最重要的类是ToolBarContribution,它有效地集中了所有的听众。这使您可以更轻松地将窗口小部件的侦听器链接到同一模型。
  4. 这里是ToolBarContribution的来源(请注意,它解决了前两个问题,因为它将侦听器与模型挂钩,而提供了自己的ToolBar到UI):

    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之外,我在主界面 ToolBar中有两个单独的按钮,一个在自定义之前,一个在自定义之后ToolBar。它们的来源在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包中包含自定义ControlContributions中的ToolBar。请注意,这两个类都不与模型有关,它们可以在产品的其他地方重复使用。

    第一个类只包含一个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;
        }
    }
    

    我没有这样做,但如果您需要为Text进一步自定义ToolBar窗口小部件,则可以像初始化时一样覆盖createControl(Composite)方法ComboContributionItem

    现在最后一件事:我使用扩展来自定义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>
    

    连接命令,以便在自定义 FooHandler之前有ToolBar的按钮,在之后有BarHandler的按钮>自定义 ToolBar。在xml中指定这些命令的顺序将反映在应用程序中。同样,商品添加到自定义 ToolBar的顺序也会反映在您的商品中。

    关于展示位置的另一个注意事项:您可以通过在locationURI查询中设置展示位置(例如toolbar:org.eclipse.ui.main.toolbar?after=additions),使menuContributions显示在不同的位置。 &#34;前&#34;是&#34;之后的另一个展示位置关键字&#34;。可以找到更多这方面的例子in this Eclipse help doc