Monday, October 5, 2009

TutoGEF First Extension

All future howtos presuppose Eclipse and GEF in the Version 3.5 or higher and Java 1.6 or higher.


For everyone working through the TutoGEF document and have advanced to Part 10 Property Sheet - first thing to do is adding org.eclipse.ui.views to your Required Plug-ins in your dependencies tab of your project. Only then you are able to use IPropertySource in your imports!




When using a ComboBoxPropertyDescription (in tutogef.NodePropertySource) it is important to know that the getting and setting of the values from and to that ComboBox is done with indexes of the passed array of possible values.

Extending our example TutoGEF we edit our Employe to contain another value - each person now can be part of a department.




public class Employe extends Node {
    // ...
    public static final String PROPERTY_DEPARTMENT = "EmployeDepartment";
    public static final String[] DEPARTMENTS = {"Human Resources", "Finances", "Marketing", "Engineering"};
    // ...
    private String department;
    // ...


    public void setPrenom(String prenom) {
        String oldPrenom = this.prenom;
        this.prenom = prenom;
        getListeners().firePropertyChange(PROPERTY_FIRSTNAME, oldPrenom, prenom);
    }


    public void setDepartment(int index) {
        String oldDepartment = department;
        if (index > -1 && index < DEPARTMENTS.length) {
            department = DEPARTMENTS[index];
            getListeners().firePropertyChange(PROPERTY_DEPARTMENT, oldDepartment, department);
        }
    }
   
    public String getDepartment() {
        return department;
    }
    // ...
}

In order to display the new data we change our figure and add a new Label in EmployeFigure:

public class EmployeFigure extends Figure {
    // ...
    private Label labelDepartment = new Label();
    // ...
    public static final int EMPLOYE_FIGURE_DEFHEIGHT = 60;


    public EmployeFigure() {
        // ...


        add(labelName, ToolbarLayout.ALIGN_CENTER);
        labelDepartment.setForegroundColor(ColorConstants.black);


        // ...
    }


    public void setDepartment(String department) {
        labelDepartment.setText(department);
    }
    // ...
}

We just added new Listeners to the Employe's setPrenom and setDepartment methodes. In the EmployePart we react on them and update the figure.


public class EmployePart extends AppAbstractEditPart {


    protected void refreshVisuals() {
        // ...
        figure.setDepartment(model.getDepartment());
        // ...
    }


    public void propertyChange(PropertyChangeEvent evt) {
        if (evt.getPropertyName().equals(Employe.PROPERTY_DEPARTMENT)) refreshVisuals();
        if (evt.getPropertyName().equals(Employe.PROPERTY_FIRSTNAME)) refreshVisuals();
    }
}

The final step is to add the new department property to the PropertySheetPage. In order to do so we add a few lines in NodePropertySource. In the IPropertyDescriptor[] method we add the ComboBoxPropertyDescriptor. It is very important that it uses an array (Employe.DEPARTMENTS in our case) to handle the data. We need to use indexes of that array to set and get the departments(see methods getPropertyValue and setPropertyValue).

public class NodePropertySource implements IPropertySource {


    public IPropertyDescriptor[] getPropertyDescriptors() {
        // ...
        else if (node instanceof Employe) {
            properties.add(new TextPropertyDescriptor(Employe.PROPERTY_FIRSTNAME, "Prenom"));
            properties.add(new ComboBoxPropertyDescriptor(Employe.PROPERTY_DEPARTMENT, "Department", Employe.DEPARTMENTS));
        }
       // ...
    }


    public Object getPropertyValue(Object id) {
        // ...
        if (id.equals(Employe.PROPERTY_DEPARTMENT)) {
            String department = (((Employe)node).getDepartment());
            for (int i=0; i
                if (Employe.DEPARTMENTS[i].equals(department)) {
                    return i;
                }
            }
            return -1;
        }
        //...
    }


    public void setPropertyValue(Object id, Object value) {
        // ...
        else if (id.equals(Employe.PROPERTY_FIRSTNAME)) {
            try {
                ((Employe)node).setPrenom((String)value);
            }
            catch (NumberFormatException e) { }
        }
        else if (id.equals(Employe.PROPERTY_DEPARTMENT)) {
            try {
                Integer index = Integer.parseInt(value.toString());
                ((Employe)node).setDepartment(index);
            }
            catch (NumberFormatException e) { }
        }
        // ...
    }
}

Feel free to change each employe's department value in MyGraphicalEditor#createEnterprise so you have a default value on startup. 

Here the updated TutoGEF project.

No comments: