Eclipse RCP application custom toolbar

不羁岁月 提交于 2019-12-09 19:46:52

问题


I am creating a custom toolbar for my RCP application.

  1. As shown in figure I want to have a drop down box with three other text boxes. These are basically the input box and are interdependent. Right now each of these boxes are in separate classes. I want to bring them together in one class so it is easier to create listeners for each other.

    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. Thus I want to create a new custom Toolbar will all the functionalities that I want and then stick it to the original. But somehow it only shows an empty bar on the left.

    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. I also have run buttons, which I created in the plugin using Vogella's tutorial. But I cannot program their placements in this way. (For example if I want them in the beginning.) Is there a way to create them programmatically?


回答1:


I think the reason your leftmost ToolBar is empty is a layout issue. In my code below, I had a similar "empty" ToolBar problem when I did not have any buttons located outside the custom ToolBar but still in the main ToolBar. Adding in the "foo" and "bar" buttons fixed the layout issue, but I could not figure out the right calls to layout() or pack() to fix it. I think this may be related to the bug here.

I took a swing at creating a similar ToolBar and built around the "RCP Mail Template" plugin-project that you can create from the "New Plug-in Project" wizard.

To address your first two concerns, I created 3 packages in the example RCP bundle (I called my project "com.bar.foo"):

  1. com.bar.foo.actions - Contains classes that extend ContributionControl and wrap Combo and Text widgets. These have nothing to do with the data model and just worry about creating widgets.
  2. com.bar.foo.model - Contains the data model. I just made up a simple model here with an IP, mask, gateway, and one or two helpful methods.
  3. com.bar.foo.toolBar - These classes are plugged up to the main UI ToolBar via the org.eclipse.ui.menus extension point. They link the data model to the ContributionControls in the first package. The most important class here is ToolBarContribution, which effectively centralizes all of your listeners. This makes it easier for you to link the listeners for the widgets to the same model.

Here's the source for the ToolBarContribution (note that it addresses your first two concerns because it hooks up the listeners to the model and provides its own ToolBar to the 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());
    }
}

In addition to this ToolBar, I have two separate buttons in the main UI ToolBar, one before, and one after the custom ToolBar. Their sources are in the package com.bar.foo.toolBar. Here is the first command:

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

And here is the second one:

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

Since I didn't know too much about your data, I had to create my own model. The model in the package com.bar.foo.model is just one class:

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

Now for the com.bar.foo.actions package that contains the ControlContributions that go in the custom ToolBar. Note that neither of these two classes have anything to do with the model, and they can be re-used elsewhere in your product.

The first class just wraps a Combo widget. The widget can be initially customized by overriding the controlCreated(Combo) method. I use that in the ToolBarContribution class to add a SelectionListener and set the Combo's items. Here's the class:

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

The other class in this package wraps a Text widget:

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

I didn't do this, but if you need to further customize the Text widget for your ToolBar, you can override the createControl(Composite) method just like I did when initializing the ComboContributionItem.

Now one last thing: I used extensions to customize the ToolBar. However, the same logic used by ToolBarContribution applies to your fillCoolBar(ICoolBarManager) method or your createControl(Composite) method, depending on which ToolBar you ultimately wish to modify.

In my case, here's what I added to the end of the plugin's 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>

The commands are hooked up so that there's a button for FooHandler before the custom ToolBar and a button for BarHandler after the custom ToolBar. The order in which these commands are specified in the xml will be reflected in the application. Likewise, the order in which the items are added to the custom ToolBar will reflect in your product.

Another note on placement: You can make the menuContributions appear in different places by setting a placement in the locationURI's query, e.g., toolbar:org.eclipse.ui.main.toolbar?after=additions. "before" is another placement keyword like "after". More examples of this can be found in this Eclipse help doc.



来源:https://stackoverflow.com/questions/26097895/eclipse-rcp-application-custom-toolbar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!