We had EMF generated model classes and a Util class with lot of helper methods. Both were exposed to clients as an API. Most of the methods in the Util classes were like:
//API - Util class
Book getBook(Writer writer, String title);
//Customer code
Util.getBook(daveSteinberg, "Eclipse Modeling Framework");
These methods would have been more appropriate in the Writer class itself rather than in a Util class, and it will be more natural to code like:
daveSteinberg.getBook("Eclipse Modeling Framework");
This tip is about how to add such methods in the generated code.
The first way is simple. Just edit the generated java code and add these methods. EMF is smart enough to identify this method and keeps it safe during regeneration of code. But if you were like me, who consider the generated Java files are as good as class files and don't want them checked into the repository, you can follow the second way.
In the eCore Editor for your model, right click the EClass and add a new child EOperation.
Go to the Properties view and specify the name, this will be the name of your method. The EType represents the return type of the method.
If your method has any parameters, then add EParameter children to the EOperation & specify their types and names.

To add the code, add an EAnnotation to the EOperation.
In the properties view, set the Source to "http://www.eclipse.org/emf/2002/GenModel".
Add a details entry to the EAnnotation.
In the properties view set the key to 'body' and value to the code that you want to be generated.
Reload your .genmodel from .ecore and generate the code:
May 5, 2008
Adding util methods to the generated EMF classes
Posted by
Prakash G.R.
at
10:26 PM
0
comments
Labels: eclipse, EMF, guidelines
May 3, 2008
Single column TableViewer and TableColumnLayout
If you have a single column TableViewer (which is commonly used because ListViewer won't show you the images), the single coloumn won't take the entire space. For example if you run the TableViewer snippet, the output is like this:
To get rid of the other spurious coloum that appears on the right, you have to use the TableColumnLayout. Modifying the code to use that:
public Snippet001TableViewer(Shell shell) {
Composite tableComposite = new Composite(shell, SWT.NONE);
final TableViewer v = new TableViewer(tableComposite);
v.setLabelProvider(new LabelProvider());
v.setContentProvider(new MyContentProvider());
MyModel[] model = createModel();
v.setInput(model);
v.getTable().setLinesVisible(true);
TableColumn singleColumn = new TableColumn(v.getTable(), SWT.NONE);
TableColumnLayout tableColumnLayout = new TableColumnLayout();
tableColumnLayout.setColumnData(singleColumn, new ColumnWeightData(100));
tableComposite.setLayout(tableColumnLayout);
}
Remember, the TableColumnLayout should be applied on the composite that holds the Table. And the composite should contain only the table and nothing else. Here is the result:
Posted by
Prakash G.R.
at
12:58 PM
0
comments
Labels: guidelines, jface, swt
Apr 23, 2008
Window Title in an RCP app
In Eclipse IDE, you can see the window title in the format: perspective - editPart name - Eclipse SDK - workspace. But in an RCP app, the title is usually the Product Name defined in the *.product file. This tip explains how to change it dynamically like IM clients - where the window title should be product name - user name.
Window title is *not* set on the IWorkbenchWindow. You need to do it on the IWorkbenchWindowConfigurer.
Whenever the user performs a login/logout, you need to set the window title. The details are sketchy, as its left to you whether to pass the instance of the windowConfigurer to the Login/LogoutAction or implement some sort of event listener for login/logout and do the title change there. But in general:
IWorkbenchWindowConfigurer windowConfigurer = ...;
String title = Platform.getProduct().getName();
if(loggedIn)
title = title + " - " + userName;
windowConfigurer.setTitle(title);
In case you were wondering where to get the instance of the windowConfigurer, it will be passed to your application thru the WorkbenchAdvisor.createWorkbenchWindowAdvisor() method.
Posted by
Prakash G.R.
at
10:40 AM
0
comments
Labels: guidelines, RCP
Mar 15, 2008
Wizard as a Dialog
In an RCP application, I had these requirements for a Dialog box:
- OK button should not be enabled until all the mandatory fields are filled
- Hints for probably incorrect data (The email id grprakash+eclipse@gmail.com "looks" like a wrong one) These should not stop the user from pressing OK
- Progress bar should be shown for long running operations (clicking OK, "check for user id availability", etc)
I was thinking on how to handle all these in a Dialog and something flashed in my mind - JFace Wizards. All the above requirements can be easily done if I use a Wizard. The Finish button is disabled when we call setPageComplete(false), we can show warnings and still allow the user to finish and by calling setNeedsProgressMonitor() & getContainer().run() we can show the progress bar in the UI as well. But there are two small issues to be handled when we use the wizard.
- The first one is to get rid of the Back and Next buttons. We are lucky here because JFace will not show those buttons if there is only one page in the wizard
- The "Finish" looks odd and should be renamed to "OK" or "Submit. This can be done by subclassing the WizardDialog:
@Override
protected void createButtonsForButtonBar(Composite parent) {
super.createButtonsForButtonBar(parent);
Button finishButton = getButton(IDialogConstants.FINISH_ID);
finishButton.setText(IDialogConstants.OK_LABEL);
}
};
Now with the util method, I can enable/disable the "OK" button, reflecting the status of the UI items.
Related:
Util method for Wizard Pages
JFace Wizard Guidelines
Posted by
Prakash G.R.
at
11:57 AM
0
comments
Labels: eclipse, guidelines, jface, RCP, wizards
Feb 18, 2008
Handy util method for WizardPages
Consider this familiar New Java class wizard.
It has to keep track of the status of the source folder, package, enclosing type, name, ... When ever there is a change in these fields, the WizardPage's status has to be updated. The algorithm goes like this: find the most severe status and update the wizard page with that status. This is a very common operation can be applied to any WizardPage. So I've written a helper method which I usually use it in almost all of the WizardPage I create. Let me know if it can be improved
public static void applyStatus(WizardPage page, IStatus[] statuses) {
IStatus severeStatus = statuses[0];
for (IStatus status : statuses) {
severeStatus = severeStatus.getSeverity() >= status.getSeverity() ? severeStatus : status;
}
String message = severeStatus.getMessage();
switch (severeStatus.getSeverity()) {
case IStatus.OK:
page.setMessage(null, IMessageProvider.NONE);
page.setErrorMessage(null);
break;
case IStatus.WARNING:
page.setMessage(message, IMessageProvider.WARNING);
page.setErrorMessage(null);
break;
case IStatus.INFO:
page.setMessage(message, IMessageProvider.INFORMATION);
page.setErrorMessage(null);
break;
default:
if (message.length() == 0) {
message = null;
}
page.setMessage(null);
page.setErrorMessage(message);
break;
}
}
Posted by
Prakash G.R.
at
11:37 PM
0
comments
Labels: guidelines, jface, wizards
Nov 5, 2007
JFace Wizard Guidelines
During Eclipse Plugin Developement training, I always end JFace Wizards session with these guidelines:
- Wizards should be aimed for minimal user interaction
- Wizard pages can be filled with meaningful defaults
- When a Wizard is shown it should not contain any errors. They should appear only after a user interaction
- Present Errors/Warnings in the tab order of the fields
- When a task is split into steps, a wizard page can model a step and shouldn't be doing more things
- Don't create pages that needs scrolling. In general if a wizard's height is greater than its width, probably it needs a review
- Total number of Wizard pages should be ~ 5
The options in the first page falls into three categories:
- Resource: Project name, location & working sets
- Compiler: Source folders
- Runtime: JRE & Execution env.
Ideally the first page should just give the resource related options and the others can be pushed to second page/elsewhere. Since the second page allows the user to configure the JRE, source & binary folder, I guess we are not loosing any functionality if we get rid of those options. If the first page is cleaned up to have only resource related options, this is how it would look like:

in contrast to the current:
Posted by
Prakash G.R.
at
6:44 PM
4
comments
