ShowTable of Contents
This tutorial is going to describe the method for adding a new customized tab for editing properties of a component. With these customizations, when a user adds the container to their palette and chooses to “Edit Component Properties”, the dialog displayed will include the extra tab. The tab will retrieve, display, then save properties.
Prerequisite
A prerequisite to this tutorial is the article
Creating a Composite Application Container.
The sample code created there will be further expanded on in this tutorial, using the same Eclipse development environment.
Scenario
In this tutorial two new preferences will be defined that store color information. Each of the two pages will have a background color associated with it. The new editing tab will show the user a drop down for each page and allow the user to select from a few color choices. The default color will be gray. When a user changes the colors and saves their preferences, the pages in the component will have their background colors changed. Optional sections at the end of the tutorial will add validation code that ensures the user selects different colors for each of the pages.
Create the new tab
A new tab class will be added to the sample package. This will be the tab that is added to the Edit Component Properties dialog. This section covers creating the new class and adding the code for all the required methods within it.
Import the required package
Add an import package for
com.ibm.rcp.ca.utils.componentconfig
Detailed instructions:
- Open plugin.xml
- On the “Dependencies” tab, click the “Add…” button next to “Imported Packages”
- Search for the package named com.ibm.rcp.ca.utils.componentconfig
- Select the package and choose “OK” to close the dialog and add the package to the list.
- Save the plugin.xml changes
Create the new class
Create a new class called SamplePropertyTab that extends com.ibm.rcp.ca.utils.componentconfig.AbstractPropertyTab
This class controls retrieving preferences, displaying them in customized UI controls, and storing the preferences as modified by the user.
When the component properties dialog is created the createControl method is called.
When the property dialog is dismissed the dispose method is called.
When you switch to the tab activating is called.
When you switch away from the tab deActivating is called.
Define basic tab definition methods
The following picture displays which methods control various areas of the tab’s visual content in the Edit Component Properties dialog:
getDescription() returns a String that will be displayed under the component title
public String getDescription() {
return "These are properties that are added by customization.";
}
getImage() returns an Image located in the “icons” directory of the project, displayed on the tab
The sample icon used here is a 16x16 PNG file:
public Image getImage() {
return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, "/icons/tabicon.png").createImage();
}
getTitle() returns a String that is displayed on the tab, next to the icon
public String getTitle() {
return "Sample";
}
createControl() is responsible for the main portion of the tab content. It will be described in the following section.
Create the main content area
The main content area displayed to the user is created in the createControl method. In this sample it will display a label and a drop down combo box with color options for each of the two pages.
A few final variables are added to the class to keep track of the color options:
// labels displayed to the user
public static final String[] COLOR_LABELS = { "Gray", "Red", "Blue" };
// SWT color reference integers, will be stored as the preference value
public static final String[] COLOR_KEYS = {
Integer.toString(SWT.COLOR_GRAY),
Integer.toString(SWT.COLOR_RED),
Integer.toString(SWT.COLOR_BLUE) };
// the default color
public static final int COLOR_DEFAULT_INDEX = 0;
UI helper classes are defined for the label and combo box:
private Combo createColorCombo(Composite parent) {
Combo combo = new Combo(parent, SWT.DEFAULT);
for (int i = 0; i < COLOR_LABELS.length; i++){
combo.add(COLOR_LABELS[i]);
}
combo.select(COLOR_DEFAULT_INDEX);
return combo;
}
private Label createLabel(Composite parent, String text) {
Label label = new Label(parent, SWT.HORIZONTAL);
label.setText(text);
return label;
}
The combo boxes will be used by other methods, so they will be defined as class instance variables:
private Combo p1ColorCombo;
private Combo p2ColorCombo;
And finally, the createControl method is filled in.
It creates the layout, label, and combo components:
public Control createControl(Composite parent) {
parent = new Composite(parent, SWT.NONE);
GridLayout gl = new GridLayout();
gl.numColumns = 2;
parent.setLayout(gl);
createLabel(parent, "Page 1 Color:");
p1ColorCombo = createColorCombo(parent);
createLabel(parent, "Page 2 Color:");
p2ColorCombo = createColorCombo(parent);
return parent;
}
Create the retrieving and storing preference code
When you switch to the tab the activating() method is called, and when you switch away from it the deActivating() method is called. This is where preferences can be retrieved and stored to the preference manager.
Two final variables are added to the class to hold the property names.
(The view class will also use these properties later. They could be in a common project constants class, but in this sample, for simplicity, we are putting them in the tab class.)
public static final String P1_COLOR_PROP = "sample.property.page1.color";
public static final String P2_COLOR_PROP = "sample.property.page2.color";
In the activating method the colors will be retrieved from the preference manager, and the combo boxes will be set to the retrieved values. If a known color is not retrieved from the property manager, the combo is set to the default color. The code to read the preference and set the combo content is separated into its own method called by activating.
public void activating() {
setColorCombo(p1ColorCombo, P1_COLOR_PROP);
setColorCombo(p2ColorCombo, P2_COLOR_PROP);
}
private void setColorCombo(Combo combo, String property) {
String color = propMgr.getProperty(property);
if (color != null) {
for (int i = 0; i < COLOR_KEYS.length; ++i) {
if (COLOR_KEYS[i].equals(color)) {
combo.select(i);
return;
}
}
}
combo.select(COLOR_DEFAULT_INDEX);
}
In the deActivating method the combo box selections will be stored to the preference manager.
public boolean deActivating() {
String color1 = COLOR_KEYS[p1ColorCombo.getSelectionIndex()];
propMgr.setProperty(P1_COLOR_PROP, color1);
String color2 = COLOR_KEYS[p2ColorCombo.getSelectionIndex()];
propMgr.setProperty(P2_COLOR_PROP, color2);
return true;
}
Add the tab to your view
SampleAppView, the main view of the container, will be modified to be a tabs provider so the new tab is displayed. It will also be modified to use the new preference from new tab.
Add the tabs provider interface implementation
For the system to know about the tab, your view must implement the tabs provider interface. Add an implements statement for com.ibm.rcp.ca.utils.IPropertyTabsProvider to the SampleAppView class.
public class SampleAppView extends ViewPart implements IPropertyTabsProvider {
This interface requires one method getTabs() which returns an array of IPropertyTab objects. The new tab is created and returned.
public IPropertyTab[] getTabs() {
return new IPropertyTab[] { new SamplePropertyTab() };
}
Use the new preference in the view
The view also creates the pages which will have the background color set, based on the new preferences. A method will be added that takes a page and a property name, and sets the page background to the appropriate color.
- The preference is retrieved from the container component data.
- The first element returned is used. This will be the integer value (stored as a String) of the SWT color saved by the tab.
- The integer will be passed to SWT classes to retrieve the color.
- The background of the page is set to that color.
The whole method:
private void setColorToProperty(SampleAppPageWidget page, String property){
String[] value = sap.getComponentData().getPreference(property);
if (value.length > 0 && value[0] != null) {
String colorStr = value[0];
Color color = page.getDisplay().getSystemColor(Integer.valueOf(colorStr));
page.setBackground(color);
}
}
The createPartControl() method calls createPages() to create and add the new pages, and this is where the new method will be called. For each page the new setColorToProperty method is called.
private void createPages(){
String page;
page = "PAGE1";
fieldMap.put("FIELD_A", "");
fieldMap.put("FIELD_B", "send something dynamically here");
page1 = new SampleAppPageWidget(parent, SWT.NONE, SampleAppPageWidget.SHOW_NEXT, this, fieldMap, page);
setColorToProperty(page1, SamplePropertyTab.P1_COLOR_PROP);
pageMap.put(page, page1);
page = "PAGE2";
fieldMap.clear();
fieldMap.put("FIELD_Y", "");
fieldMap.put("FIELD_Z", "www.espn.com");
page2 = new SampleAppPageWidget(parent, SWT.NONE, SampleAppPageWidget.SHOW_PREV, this, fieldMap, page);
setColorToProperty(page2, SamplePropertyTab.P2_COLOR_PROP);
pageMap.put(page, page2);
}
Test container
Now the container is ready to be tested.
1. Add your sample container to a new composite application.
2. Choose to “Edit Component Properties” and navigate to the new “Sample” tab.
3. Set the pages to be different colors.
4. Choose “OK” close the properties dialog.
5. The component pages will have the new colors as their background color.
Validate tab content
Optionally, validation can be added to the deActivating() method. If deActivating returns false the tab is considered to be in error and the user will not be allowed to switch to another tab or close the dialog with “OK” until the error is fixed (when the deActivating method returns true).
In this sample, validation is going to ensure that the colors of the two pages are different.
Add a method to SamplePropertyTab that determines whether the colors are different:
public boolean differentColors(){
return (p1ColorCombo.getSelectionIndex() !=
p2ColorCombo.getSelectionIndex());
}
In deActivating, instead of returning true, now return the value from this differentColors() method.
public boolean deActivating() {
String color1 = COLOR_KEYS[p1ColorCombo.getSelectionIndex()];
propMgr.setProperty(P1_COLOR_PROP, color1);
String color2 = COLOR_KEYS[p2ColorCombo.getSelectionIndex()];
propMgr.setProperty(P2_COLOR_PROP, color2);
return differentColors();
}
After this addition, if the two combo boxes are displaying the same color, the user will not be able to switch to a new tab, or close the dialog with the “OK” button.
This will not display any type of message to the user, to indicate what the problem is. Displaying an error message will be covered in the next section.
Using the message provider
The messageProvider set in the AbstractPropertyTab is accessible from SamplePropertyTab class. It can be used to provide informational messages as well as error messages. These messages are displayed under the component title in the dialog box.
In this sample an error message will be added if the validation during the deActivating method call fails.
If the colors are not different, an error message will be set indicating the problem, and deActivating will return false to prevent the user from switching tabs or choosing “OK”. If the colors are different, the error message will be cleared and deActivating will return true to allow the user to continue.
The return statement from the last section is replaced with the following.
if (!differentColors()){
this.messageProvider.setErrorMessage("Colors must be different");
return false;
}
this.messageProvider.setErrorMessage(null);
return true;
When the user selects two of the same colors and attempts to switch to a new tab or click “OK”, the error will appear:
If they later select two different colors and attempt to switch to a new tab the default message will be restored, or if they click “OK” the dialog will close and the preferences will be updated.
Summary
This tutorial showed how you can add a property editing tab to your container which will be displayed to the user in the Edit Component Properties dialog. This is a way to provide any customized editing screens for application assemblers using your container.